vite + vue3 + ts 使用总结

现阶段开发 vue3 项目使用 vite + ts 应该已成为标准范式了吧,新的语法体验 vue composition api 再配合 script setup 谁用谁知道啊,开发和构建方面,vite 作为下一代构建工具,想必大家也有所了解,使用 ES6 module + ESbuild 支持本地开发,速度和效率起飞啊,就一个字——爽,对于 TypeScript,感觉都没必要说了,现在还没上车的赶紧的了~

前言

vite 作为一个构建工具,我们目前了解如何使用即可,该工具足够优秀,默认对很多功能都做到了支持(css modulelessscss),且其作为 vue之父尤大大的作品,对于 vue也有着较好的支持,目前使用率也已经很高了,nuxt等多个大项目都已支持,结合文档和社区,目前使用足够了,也无需担心疑难杂症~,快上车~

vue3,感觉变化最大的就是全面拥抱了函数式编程,结合 composition api 现在真的可以做到对于复杂业务代码的轻松管理,抛弃以前的 this this 一大堆,不友好的mixin ,使用现在的 hooks处理,逻辑复用、功能模块拆分简直太方便了,语法、api使用上也优雅方便了很多,很值得一试

另一大亮点就是 vue3TS的良好支持,现在项目可以全面拥抱 TS写法了,然后与 setup 再结合我接下来推荐的几款工具,组合起来使用,简直不要太爽

对于 TS,首先要做到对类型的定义,这是和传统写JS有所不同的地方,但是这一步却是很必要也很值得的,这对你接下来的工作或者说对于这个项目的以后都是有很大的好处

如这样一个场景,和后端接口对接:

在前期,我们拿到接口文档,按照格式和类型定义好对应 TS类型,并结合 Mock写好接口和业务逻辑,使用时通过TS可以高效的完成代码开发,同时可以极大的避免犯错,对于后期维护迭代有很大的保障

import.meta

使用 vite做为构建工具,可以通过 import.meta获取对应方法方便快速的处理业务

环境变量获取

import.meta.env

// console.log(import.meta.env)
{
    "BASE_URL": "/",
    "MODE": "development",
    "DEV": false,
    "PROD": true,
    "SSR": false
}

注意:

配合.env/.env.development/.env.production等文件设置环境变量使用时,变量Key应该以VITE_为前缀

{
  "script":{
    "dev": "vite --mode development"
  }
}
为了防止意外泄漏 env 变量给客户端,只有以 VITE_为前缀的变量才会暴露给 Vite 处理的代码。只会向您的客户端源代码VITE_SOME_KEY公开import.meta.env.VITE_SOME_KEY,但DB_PASSWORD不会。

批量处理文件

import.meta.globEager

// 读取当前目录下的所有 .ts文件
const modules = import.meta.globEager('./**/*.ts')

ref和reactive

都可以用来定义响应式数据

ref

主要用于定义基本类型,使用时需要通过 .value 读取或修改

基本类型:除去Object,包括:StringNumberbooleannullundefined

控制台打印数据结构为 RefImpl

// ref
const count = ref(0)

count.value++
console.log(count.value)

在定义基本类型时,响应式原理是与 vue2.x类似的 Object.defineProperty(),通过 getset读取、修改数据

不过,ref也可以定义引用类型的数据,注意,当定义引用类型时,其内部实现则是借助 reactive

可以通过打印数据在控制台查看结构,分别为:RefImplProxy

reactive

只能定义引用类型,即Object,包括:ObjectArrayDatefunction,定义基本类型时会警告

使用时,直接通过属性读写

// reactive
const state = reactive({count:0})

state.count++
console.log(state.value)

reactive默认对对象内的所有属性都进行响应式处理,并可以实现深层监听

该响应式能力是通过 ES6 Proxy实现的,其可以做到对属性的新增删除监听,解决了 defineProperty的缺陷,并且对嵌套属性有着良好的支持,可以轻松实现 a.b.c.d=xx的响应式更新

ProxyReflect均为ES6语法,一般他俩是一起配合使用,可以很好的做到安全优雅的对属性做出劫持更新

小结

模板 tempalte 会自动解包,在模板中使用时,不需要 .value

对于引用类型来说,简单理解即:ref本质也是reactive,ref(obj)等价于reactive({value: obj})ref 的底层实现就是 reactive

可以发现,所谓响应式其实就是对属性的劫持

refreactive定义的数据,每一层都是响应式的

watch、watchEffect

监听响应式数据的变化

watch

基本语法和 vue2类似,不过在这里有一些不同的使用方式

监听 ref定义的响应式数据(基本类型)

  • 函数式写法需要 .value,监听的是一个值的变化
const count = ref(0);
const str = ref('abc');

// 1. 普通写法
// watch可以省略 .value
watch(count, (val, old) => console.log({ val, old }));

// 2. 函数写法
watch(
  () => count.value,
  (val, old) => console.log({ val, old }),
);

// 3. 数组写法
watch(
  () => [count.value, str.value],
  (val, old) => console.log({ val, old }),
);

监听 ref定义的响应式数据(引用类型)

  • 需明白的是,ref定义引用类型,内部是使用 reactive实现的,因此,需要通过 .value拿到响应式对象,再进行属性监听
const refState = ref({
  count: 0,
  str: 'abc',
});
// 1. 普通写法,无效
// => refState.value 有效
watch(refState, (val, old) => console.log({ val, old }));
// 2. 函数写法
watch(
  () => refState.value.count,
  (val, old) => console.log({ val, old }),
);

监听 reactive定义的响应式数据

  • 需要针对属性监听 state.count
const state = reactive({
  count: 0,
  str: 'abc',
  a: {
    b: {
        c: 'a-b-c',
      },
    },
});

// 1. 普通写法
// 结果:val, old 新旧值相同,
// watch(state, (val, old) => console.log({ val, old }));

// 2. 函数写法
// 结果:指定属性变化才会触发
watch(
  () => state.value.a.b.c, // 只监听指定的 属性
  (val, old) => console.log({ val, old }),
);

watchEffect

接收一个函数,不需要设置监听对象,该方法会自动接管函数内部使用到的依赖,当依赖发生更新时,触发该函数执行

该函数会初始化默认执行一次

watchEffect(()=>{

  if(state.count>1){
    // 只要 count变化,这个 watchEffect函数就会执行一次
    // 当 count > 1时,做对应行为
  }

})

watch、watchEffect 小结

使用watch时,需要考虑的情况比较多

watch更强调结果,watchEffect强调过程

就用法方面来说 watchEffect似乎更简单易用~

shallowRef和shallowReactive

  • 递归监听和非递归监听

refreactive都属于递归监听,也就是数据的每一层都是响应式的,如果数据量比较大,非常消耗性能,非递归监听只会监听数据的第一层。

script setup 写法的 props 、context处理方式

在以

使用

// 

export const columns = [
  // ...
  {
    title: '操作',
    key: 'action',
    width: 120,
    slots: { customRender: 'action' },
  },
]

const tableActions = ref([
  {
    label: '编辑',
    auth: AuthEnum.user_update, // 配置按钮权限
    onClick: async (row) => {
      modalState.visible = true;
      const res = await store.fetchDetail(row.id);
      if (res) formModel.value = res;
    },
  }
  // ...
]

这是我在上个项目中实战使用的一点心得,对于开发效率提升还是很明显的,维护起来也是很方便,更多用法也欢迎大家一起交流学习,就目前体验来说vue3很棒~

event bus

vue3中移除了实例中挂载 $emit的行为,如果想继续使用可以单独下载对应的 npm包,如:mitt,该包很轻量,仅 200byte

api与用法类似,只是改变为了函数式创建,需要确保单个操作的 emitter创建唯一

import mitt from 'mitt'

const emitter = mitt()

export emitter

结语

这篇文章其实相当于自己的学习笔记,也是为了加深印象,在使用的过程中记录了遇到的一些问题,希望可以给自己和大家带来一些帮助。就内容而言属于入门使用水平,目前暂未涉及到深水区,本文会根据使用情况持续更新

你可能感兴趣的:(vite + vue3 + ts 使用总结)