vue3.0
vue3.0
开发工具
- (新的友好的支持 vue3 的 vscode 开发插件) volar
- (官方脚手架工具 create-vue)[https://github.com/vuejs/create-vue]
- (Vitesse)[https://github.com/antfu/vitesse]
- (vue3-eslint-stylelint-demo) [https://github.com/sethidden/vue3-eslint-stylelint-demo](Volar + ESLint + stylelint + husky)
- (volar-starter)[https://github.com/johnsoncodehk/volar-starter] (For bug report and experiment features testing)
生命周期
destroyed 生命周期选项被重命名为 unmounted
beforeDestroy 生命周期选项被重命名为 beforeUnmount
Composition API 简单使用
teleport 组件
有时组件模板的一部分逻辑上属于该组件,而从技术角度来看,最好将模板的这一部分移动到 DOM 中 Vue app 之外的其他位置。
Teleport 提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下渲染了 HTML,而不必求助于全局状态或将其拆分为两个组件
1 | <teleport to="#modals"> |
stylelint
StyleLint 是『一个强大的、现代化的 CSS 检测工具』, 与 ESLint 类似, 是通过定义一系列的编码风格规则帮助我们避免在样式表中出现错误.
(StyleLint 使用指南)[https://www.cnblogs.com/jiaoshou/p/11284204.html]
setup 的形参
1 | <script setup></script> |
采用 script setup 语法糖的话这种方式就不可行了,原因是它会自动以文件名为主,不需要在写 name 属性
需要设置 name 直接在 script setup 同级中再添加一个 script 即可。
1 | <script> |
如果同时使用了 typescript 的话,可以配合插件直接在 script 标签中设置 name,具体方式如下:
安装插件:vite-plugin-vue-setup-extend
1 | <script lang="ts" setup name="xxx"></script> |
reactive()
和 ref()
的比对
- ref() 单独地为某个数据提供响应式能力
想要保持对象内容的响应式能力,在 return 的时候必须把整个 reactive() 对象返回出去,同时在引用的时候也必须对整个对象进行引用而无法解构,否则这个对象内容的响应式能力将会丢失。
- reactive() 给一整个对象赋予响应式能力
在具体的业务中,如果无法使用解构取出 reactive() 对象的值,每次都需要通过 . 操作符访问它里面的属性会是非常麻烦的,所以官方提供了 toRefs() 函数来为我们填好这个坑。只要使用 toRefs() 把 reactive() 对象包装一下,就能够通过解构单独使用它里面的内容了,而此时的内容也依然维持着响应式的特性。
ref可以包装基本类型和引用类型,reactive只能包装引用类型。第二点,ref取值要用.value,而reactive可以直接访问
ref解构后仍然保持响应性,因为解构的是 ref 对象。而reactive解构后会丢失响应性,因为解构的是普通对象。如果需要解构并保持响应性,可以使用 toRefs。
如何选择 ref 和 reactive?
- 优先 ref
- 管理基本类型数据
- 需要明确的数据引用(如传递到函数中仍保持响应性)
- 优先 reactive
- 管理复杂对象/数组,避免频繁使用.value
- 需要深层嵌套的响应式数据
1 | setup() { |
isRef,unRef,toRef 和 toRefs
1 | let foo: unknown; |
ref、reactive、shallowRef、 shallowReactive、toRaw、unref、toRef、toRefs、customRef
shallowRef & shallowReactive 只对对象的第一层做监听变化
customRef 创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象
1 | function useDebouncedRef(value, delay = 200) { |
定义 prop emit
- defineProps
1 | import { defineProps } from "vue"; |
- defineEmits
1 | import { defineEmits } from "vue"; |
子组件
1 | <template> |
父组件
1 | <template> |
- defineExpose
script setup 默认是不对外界暴露组件实例的,所以在其他组件中通过诸如$refs和$parent 都默认无法获取当前组件实例,但是通过 defineExpose 暴露的可以获取。
显示暴露的数据,才可以在父组件拿到
1 | <script setup lang="ts"> |
使用 slots 和 attrs
- 通过 useSlots 和 useAttrs 来定义,达到类似$slots和$attrs 的效果
1 | // 导入 useAttrs 组件 |
使用 provide 给子孙组件传值和 inject 接收父组件的值
父组件
1 | <script setup lang="ts"> |
孙子组件
1 | <script setup lang="ts"> |
watch 和 watchEffect
- watch ()
第一个参数为观察 ref 物件,第二个参数为一个 callBack ,当状态更新,就会针对其来执行 callback。
- watchEffect()
不用指定要监听的目标,只要在 callback 函式中对应响应式资料更新后就会依照对应资料来执行了,而与 watch 不同的是,watchEffect () 在初始 setup () 的时候,就会先执行一次了。
第一个参数还可以是队列,如果是 reative 中的一个 key-value,用有回传值的 getter 函式,即()=>state.key,深度监听在第三个参数{deep: true}
属性透传
1 | <!-- 父组件 --> |
v-model 的参数分析
v-model 其实是做双向绑定,实际上是语法糖
vue2.x.x 的语法
1 |
|
vue3.x.x 的语法
- 2.x 的 v-model 只能有一个,3.x 灵活为支持多个
1 | <ChildComponent v-model:title="pageTitle" v-model:content="pageContent" /> |
- 除了像 .trim 这样的 2.x 硬编码的 v-model 修饰符外,现在 3.x 还支持自定义修饰符
1 | <ChildComponent v-model.capitalize="pageTitle" /> |
1 | <!-- 1 --> |
Vue3 指令新特性
支持多个 v-model
自定义修饰符:通过 modelModifiers 访问
作用域插槽
动态属性名
1 | <img :src="imageUrl" :alt="altText"> |
进阶
组合式 API 中组件的 setup() 钩子可以是异步的
如果使用