likes
comments
collection
share

uniapp+vue3+vite+typescript架构下开发小程序

作者站长头像
站长
· 阅读数 75

前言

这篇文章记录的是uniapp+vue3+vite+typeScipt架构下如何使用vue与ts开发。主要是1. vue的基本语法,2. uniapp在ts下的类型声明与使用,3.uniapp组件与API的使用,4.vue生态的使用,会使用pinia作为状态管理工具。

系列文章

前言

这篇文章记录的是uniapp+vue3+vite+typeScipt架构下如何使用vue与ts开发。主要是1. vue的基本语法,2. uniapp在ts下的类型声明与使用,3.uniapp组件与API的使用,4.vue生态的使用,会使用pinia作为状态管理工具。

uniapp与vue3结合开发

在uniapp中使用vue3开发,首先看到main.ts文件,这里有需要注意的地方是这里不是使用createApp来创建实例,而是使用createSSRApp来创建应用实例。然后导出了一个叫createApp的函数。我们可以在这里面写一些常用的操作。如注册全局变量,创建全局组件,注册插件等等。下面是我main.ts的代码片段

import { createSSRApp } from "vue"
import App from "./App.vue"
import Test from "@/component/Test/Test.vue"
import { createPinia } from "pinia"
export function createApp() {
  const app = createSSRApp(App)
  const pinia = createPinia() // 导入插件
  app.config.globalProperties.$token = "xxxx" // 创建全局变量
  app.component("Test", Test) // 注册全局组件
  app.use(pinia)
  return {
    app
  }
}

接下来新建一个demo文件,去实验vue的语法。我创建的名字叫vue.vue,这个文件可以自行去创建

  1. ref()与reactive()

这个应该是比较常用的api,写了一个增加数的按钮,很简单

  1. computed()

计算属性也是比较常用的api,写了一个count增加时+1的计算属性

  1. watch()与watchEffect()

这两个的区别我这里就不展开描述了,一大推文章,这里只贴用法

<template>
  <div class="page_main">
    <div>vue页面</div>
    <Test />
    <div class="add_button" @click="updateCount">点击</div>
    <div>count值:{{ count }}</div>
    <div>countPlus值: {{ countPlus }}</div>
    <div>reactive: {{ obj.count }}</div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, reactive, watch, watchEffect } from "vue"

const count = ref(0)
const obj = reactive({ count: 1 })

const countPlus = computed(() => count.value + 1)

watch(count, (newVal, oldVal) => {
  console.log(newVal, oldVal)
})

const stop = watchEffect(() => {
  console.log(`watchEffect`, count.value)
})
// stop() // 停止监听

const updateCount = () => {
  count.value += 1
  obj.count += 1
}
</script>
  1. 动态渲染与条件渲染

这里也很常规,直接使用v-for与v-if指令来

<tempalte>
	 <div v-for="(item, index) in list" :key="index" class="list_item">{{ item }}</div>
    <div @click="changeTips">点击{{ tips.title }}</div>
    <div v-if="tips.show === true">{{ tips.title }}</div>
</teamplate>
<script setup lang="ts">
const list = ref([1, 2, 3, 4, 5, 6])
const tips = reactive({
  title: "展示",
  show: false
})

const changeTips = () => {
  tips.show = !tips.show
  tips.title = tips.show === true ? "隐藏" : "展示"
}
</script>
  1. 动态class与style

和平常写vue的语法一样

<h3>动态classstyle</h3>
<div :class="count === 2 ? 'active' : ''">count2时变红</div>
<div :style="{ color: count === 2 ? 'red' : '' }">count2时变红</div>
  1. 设置全局变量

定义全局变量是在main.ts中定义,我们来聚一个例子,在全局变量中记录token,并在页面上拿到这个token

//main.ts
export function createApp() {
  const app = createSSRApp(App)
  const pinia = createPinia() // 导入插件
  app.config.globalProperties.$token = "xxxx" // 创建全局变量
  app.component("Test", Test) // 注册全局组件
  app.use(pinia)
  return {
    app
  }
}

在页面中就这样使用

import { getCurrentInstance } from "vue"

const token = getCurrentInstance()?.appContext.config.globalProperties.$token
console.log(`token值`, token)

基本常用的语法我都尝试了一下,都是支持,所以可以放心的用。uniapp在vue3的支持这一块还是很nice的。

uniapp下ts的使用

简单记录一下在uniapp中使用ts的场景,因为自己写ts也不是很好,所以就按最常见的使用场景来记录一下

uniappAPI的TS声明

uniapp的类型定义是由@dcloudio/types 模块提供的,所以在使用uniapp+ts时请检查是否有这个包,如果没有需要下载。下载好后还需要在 tsconfig.json 文件中的 compilerOptions > types 部分配置。

uniapp+vue3+vite+typescript架构下开发小程序

泛型的使用

泛型是ts很常见的功能啦,这里简单写了一个print函数,使用了一下泛型

<script setup lang="ts">
type Print = <T>(data: T) => T
const print: Print = (data) => {
  console.log(data)
  return data
}

print("string") // 打印出string
print(10) // 打印出10
</script>

其他TS常用功能的使用

像基础的类型声明啥的都不说了,肯定是能正常使用的,还有一些类型断言,类型约束啥的也是可以使用,这里就不一一列举啦。ts这块应该没啥大坑,我就不再占用过多篇幅了。(主要是我经常用anyscript)

uniapp的组件与api使用

这里我来介绍开发中常用的功能进行记录。

跳转路由

跳转功能就正常的调uniapp提供的api就好,这里以navigateTo做代码示例

<template>
  <div>uniapp+vue3+ts首页</div>
  <div class="button" @click="navigateTo('/pages/vue/vue')">vue页面</div>
</template>

<script setup lang="ts">
const navigateTo = (url: string) => {
  uni.navigateTo({
    url: url
  })
}
</script>

网络请求

网络请求也是最常用的api,使用uni.request(),这里也封装了一个uni.request()的工具方法。

我们先新建一个api文件夹,里面存放我们的api路径,这边适配这几种规则的接口信息

// api/index.ts
const Api: Record<keyof APIModule, string> = {
  getUserInfo: "GET:user/info",
  updateUserInfo: "POST:user/update",
  getDetail: "GET: user/detail"
}

export { Api }
//声明文件
declare type APIModule = {
  getUserInfo: {
    url: string
    params: {
      test: string
    }
    response: {
      code: number
      data: {
        id: string
        name: string
        age: number
      } | null
      msg: string | null
    }
  }
	//这里就不全粘贴了,格式都是一样的
}

然后封装一个useApi的hook,这里有个坑就是success的回调参数有声明类型了,好像不太匹配,我就给注释掉检查啦,哈哈,如果有啥好的方法希望大家可以告诉我咋改,ts真心玩的不熟

import { Api } from "@/api/index"
import { BASE_URL } from "@/config/index"
function useApi<T extends keyof APIModule>(api: T) {
  const [method, ...url] = Api[api].split(":")
  const _method = method as "GET" | "POST"
  const runAsync = (
    params: APIModule[T]["params"],
    header: object | null
  ): Promise<APIModule[T]["response"]> => {
    return new Promise((resolve, reject) => {
      uni.request({
        url: BASE_URL + url,
        method: _method,
        data: params,
        header: Object.assign({}, header),
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        //@ts-ignore
        success(res: APIModule[T]["response"]) {
          if (res && res.code === 200) {
            resolve(res)
          } else {
            reject(res)
          }
        },
        fail(err) {
          reject(err)
        }
      })
    })
  }

  return {
    runAsync
  }
}

export { useApi }

数据缓存

使用的就是uni.setStorageSync,uni.getStorageSync,uni.removeStorageSync,uni.clearStorageSync()

uni.setStorageSync("test", "test")
const test = uni.getStorageSync("test")

其他api能力就不占篇幅举例啦,大家对着文档用,踩坑应该也是uni的已知的坑啦。

uniapp下vue生态的使用

这里我们使用vue新推出(其实已经不新啦)的pinia来举例。pinia是新推出的vue的状态管理库。这里不过多介绍pinia啦。有兴趣的可以看其他大佬的分享。这里直接上使用代码。

新建一个store文件夹,里面新建一个user.ts。里面创建了一个user

//store/index.ts
import { defineStore } from "pinia"

interface State {
  count: number
}

export const useUserStore = defineStore("user", {
  state: (): State => {
    return {
      count: 0
    }
  },
  actions: {
    updateName() {
      this.count++
    }
  }
})

在pinia.vue中使用定义的store

<template>
  <div></div>
</template>

<script setup lang="ts">
import { useUserStore } from "@/store/index"
import { storeToRefs } from "pinia"
const userStore = useUserStore()
const { count } = storeToRefs(userStore)
userStore.updateName()
console.log(`store`, count.value)
</script>

<style></style>

很简单的一个小demo,简单记录了如何使用pinia。

github地址

这个是这个demo的git地址uniapp_vue3_demo,分支是features/dev,有兴趣可以看一下完整的demo。

后记

以上就是我试用这个架构开发demo的一些记录。如果有新的更新我也会更新在这个系列。如果有什么问题或者讨论的点欢迎大佬们下方评论或者留言。

转载自:https://juejin.cn/post/7232164444985442364
评论
请登录