uniapp+vue3+vite+typescript架构下开发小程序
前言
这篇文章记录的是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,这个文件可以自行去创建
- ref()与reactive()
 
这个应该是比较常用的api,写了一个增加数的按钮,很简单
- computed()
 
计算属性也是比较常用的api,写了一个count增加时+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>
- 动态渲染与条件渲染
 
这里也很常规,直接使用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>
- 动态class与style
 
和平常写vue的语法一样
<h3>动态class与style</h3>
<div :class="count === 2 ? 'active' : ''">count为2时变红</div>
<div :style="{ color: count === 2 ? 'red' : '' }">count为2时变红</div>
- 设置全局变量
 
定义全局变量是在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 部分配置。

泛型的使用
泛型是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