vite|vite + vue3 + ts 使用总结
现阶段开发 vue3
项目使用 vite
+ ts
应该已成为标准范式了吧,新的语法体验 vue composition api
再配合 script setup
谁用谁知道啊,开发和构建方面,vite
作为下一代构建工具,想必大家也有所了解,使用 ES6 module
+ ESbuild
支持本地开发,速度和效率起飞啊,就一个字——爽,对于 TypeScript
,感觉都没必要说了,现在还没上车的赶紧的了~
前言
vite
作为一个构建工具,我们目前了解如何使用即可,该工具足够优秀,默认对很多功能都做到了支持(css module
、less
、scss
),且其作为 vue
之父尤大大的作品,对于 vue
也有着较好的支持,目前使用率也已经很高了,nuxt
等多个大项目都已支持,结合文档和社区,目前使用足够了,也无需担心疑难杂症~,快上车~
vue3
,感觉变化最大的就是全面拥抱了函数式编程,结合 composition api
现在真的可以做到对于复杂业务代码的轻松管理,抛弃以前的 this this 一大堆,不友好的mixin
,使用现在的 hooks
处理,逻辑复用、功能模块拆分简直太方便了,语法、api使用上也优雅方便了很多,很值得一试
另一大亮点就是 vue3
对 TS
的良好支持,现在项目可以全面拥抱 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,包括:
String
、Number
、boolean
、null
、undefined
控制台打印数据结构为
RefImpl
// ref
const count = ref(0)count.value++
console.log(count.value)
在定义基本类型时,响应式原理是与 vue2.x类似的
Object.defineProperty()
,通过 get
、 set
读取、修改数据不过,ref也可以定义引用类型的数据,注意,当定义引用类型时,其内部实现则是借助 reactive
可以通过打印数据在控制台查看结构,分别为:
RefImpl
、Proxy
reactive
只能定义引用类型,即Object,包括:
Object
、Array
、Date
、function
,定义基本类型时会警告使用时,直接通过属性读写
// reactive
const state = reactive({count:0})state.count++
console.log(state.value)
reactive默认对对象内的所有属性都进行响应式处理,并可以实现深层监听
该响应式能力是通过
ES6 Proxy
实现的,其可以做到对属性的新增、删除监听,解决了 defineProperty
的缺陷,并且对嵌套属性有着良好的支持,可以轻松实现 a.b.c.d=xx
的响应式更新小结Proxy
与Reflect
均为ES6语法,一般他俩是一起配合使用,可以很好的做到安全优雅的对属性做出劫持更新
模板 tempalte 会自动解包,在模板中使用时,不需要
.value
对于引用类型来说,简单理解即:ref本质也是reactive,ref(obj)等价于reactive({value: obj}),
ref
的底层实现就是 reactive
可以发现,所谓响应式其实就是对属性的劫持
ref
和reactive
定义的数据,每一层都是响应式的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
- 递归监听和非递归监听
ref
和reactive
都属于递归监听,也就是数据的每一层都是响应式的,如果数据量比较大,非常消耗性能,非递归监听只会监听数据的第一层。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,该包很轻量,仅 200byteapi与用法类似,只是改变为了函数式创建,需要确保单个操作的 emitter创建唯一
import mitt from 'mitt'const emitter = mitt()export emitter
结语 这篇文章其实相当于自己的学习笔记,也是为了加深印象,在使用的过程中记录了遇到的一些问题,希望可以给自己和大家带来一些帮助。就内容而言属于入门使用水平,目前暂未涉及到深水区,本文会根据使用情况持续更新
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用
- 使用协程爬取网页,计算网页数据大小