vite|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
  • 递归监听和非递归监听
【vite|vite + vue3 + ts 使用总结】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 = https://www.it610.com/article/res; }, } // ... ]
这是我在上个项目中实战使用的一点心得,对于开发效率提升还是很明显的,维护起来也是很方便,更多用法也欢迎大家一起交流学习,就目前体验来说vue3很棒~
event bus vue3中移除了实例中挂载 $emit的行为,如果想继续使用可以单独下载对应的 npm包,如:mitt,该包很轻量,仅 200byte
api与用法类似,只是改变为了函数式创建,需要确保单个操作的 emitter创建唯一
import mitt from 'mitt'const emitter = mitt()export emitter

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

    推荐阅读