PS
-
由于公司最近新项目使用了vue3+ts+antdv+vite的技术栈,这几天看了一下vue3系统的了解了一下vue3的新特性和写法,其中有自己的理解也有直接摘抄的文档中的定义,理解不到位的各位看官可以提出来。
-
下面其实是用markdown写的思维导图,使用markmap渲染出来的,另外这个文档更适合有一定vue2基础的人看,懂得都懂
-
一些概念感觉是vue2中的并未做过多解释,只是列出来让vue的概念完全,当然后续有补充的会持续更新
-
最后贴出实际markmap渲染出来的思维导图
新的响应式系统
- Proxy
- 对比 defineProperty 和 value setter
- 兼容性(彻底放弃IE)
- ref
- 利用对象的get和set实现
- 只拦截某一个属性的修改(value)
- 简单数据结构
- 复杂的对象则通过reactive函数对对象进行深度响应式
- unref
- 如果参数是一个 ref,则返回内部值,否则返回参数本身。
- 等价于
val = isRef(val)? val.value: val
- reactive
- 利用Proxy实现
- 复杂的数据结构,深度转换
- 本质是proxy包装的data属性
- 前身:Vue.observable()
- 可以理解为一组单个ref
- ref赋值给reactive会被解包
- isProxy
- isReactive
- toRaw
- 返回 reactive 或 readonly 代理的原始对象
- 可用在对响应式数据处理但不需要代理访问/跟踪的开销,同时可避免触发更改
- markRaw
- 标记对象不再转换为proxy,返回对象本身
- shallowReactive
- 创建响应式代理,但不执行嵌套对象深层响应式转换
- shallowReadonly
- 创建proxy只自身property为只读,不执行嵌套对象的只读转换
- toRefs
- 用来解构响应式数据,将复杂数据拆解成多个ref数据
- 被解构的数据则不是响应式的对象了
-
import { reactive, toRefs } from 'vue' const book = reactive({ author: 'Vue Team', title: '2020', }) let { author, title } = toRefs(book) title.value = 'Vue 3 Detailed Guide' // 我们需要使用 .value 作为标题,现在是 ref console.log(book.title) // 'Vue 3 Detailed Guide'
- toRef
- 对响应式数据对象的某个property新创建一个ref
- 并保持与原对象的响应式连接(可以互相修改)
- 如果源property不存在也会返回一个可用的ref
- isRef
- readonly
- 将响应式数据copy一份儿,并不影响原响应式数据修改,但copy之后的数据不可修改
- computed: 计算属性
-
import { ref, computed } from 'vue'; // 简单用法 const count = ref(0); const pluseOne = computed(() => count.value + 1); // get set const plusOn = computed({ get: () => count.value + 1, set: (val) => { count.value = val - 1; } }) // 第二个参数可以传入出发计算时的钩子函数 onTrack onTrigger // onTrack 是被计算响应式数据作为依赖被追踪时触发 // onTrigger 是被计算响应式数据值被修改时触发
-
- watchEffect
- 立即执行副作用函数(回调)并自动追踪其以来的响应式数据
- watchPostEffect(别名)
flush: post
DOM渲染后执行可以拿到DOM信息 - watchSyncEffect(别名)
flush: sync
- watch
- 可以侦听单个或者多个数据源(第一个参数)
- 懒执行副作用函数,并必须有依赖的响应式数据 (第二个参数)
- 深度:deep: true(第三个参数)
- style使用
- scoped
- :deep()可以影响子组件
.a :deep(.b) {}
- :slotted:插槽选择器,用于直接选择插槽内的元素
:slotted(div) {}
- :global标记全局样式
:global(.red) {}
- SFC中可以有多个style标签
- v-bind绑定到样式属性
生命周期
- Options API
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeUnmount
- unmounted
- errorCaptured
- renderTracked
- renderTriggered
- activated
- deactivated
- Composition API
- 不需要beforeCreate和created
- onBeforeMount
- onMounted
- onBeforeUpdate
- onUpdated
- onBeforeUnmount
- onUnmounted
- onErrorCaptured
- onRenderTracked
- onRenderTriggered
- onActivated
- onDeactivated
组合式API 和 setup
- 计算属性和生命周期都可以脱离Vue组件单独使用,可以在单独的文件中导出方法来使用
- setup
- 作为一个载体可以更好的将组合API导出与视图关联起来
- 在组件创建之前调用
- beforeCreate 和 created
- data property、computed property 或 methods解析之前
- 无法使用this
- 生命周期可以在vue中导出使用
-
onMounted(() => { something });
-
- 需要显式的返回setup函数中定义的响应式数据和方法
- 如果返回函数可以使用vue中导出的h函数来单独渲染
- 参数
- props:响应式数据,解构使用toRefs
- context:可以直接解构
{ attrs, slots, emit, expose }
<script setup>
- 作为setup属性的语法糖,让开发更丝滑
- 可以在顶层使用await调用异步函数
- 可以和其他的
<script>
标签并存 - 顶层的绑定会暴露给模板
- 可直接使用defineProps和defineEmits
- Provide/Inject(依赖注入)
- 用于穿透多个组件传值
- 需要注意响应式数据需要使用ref或者reactive包装后使用
- 尽量在provide组件处修改依赖数据
- 如果有在inject组件修改数据的需求可以在provide处传入修改函数
- 一个例子:组合式API实现获取鼠标位置的功能
-
import {ref, onMounted,onUnmounted} from 'vue' export function useMouse(){ const x = ref(0) const y = ref(0) function update(e) { x.value = e.pageX y.value = e.pageY } onMounted(() => { window.addEventListener('mousemove', update) }) onUnmounted(() => { window.removeEventListener('mousemove', update) }) return { x, y } }
-
- Vueuse
虚拟DOM
- 轻量级的JavaScript对象
Mixin(混入)
自定义指令
- 对DOM层有操作需求的可以自定义一个指令
- focus
- permission
- ...
新的内置组件
- Fragment:
- Vue 3 组件不再要求有一个唯一的根节点,清除了很多无用的占位 div。
- Teleport:
- 允许组件渲染在别的元素内,主要开发弹窗组件的时候特别有用。
- Suspense:
- 异步组件,更方便开发有异步请求的组件。
封装自己的组件
- 组件
- defineProps
- defineEmits
- 插槽(slot)
- Form组件(理解v-model)
- v-model
- props: modelValue
let emits = defineEmits(['update:modelValue])
- 一个例子:
<OrgSelect>
- hooks(useXxx)
TypeScript
- 入门可以参考我的一篇总结TypeScript入门写法总结
- 编辑器VSCode
- Volar插件
- defineComponent
- Props:
-
interface Book { title: string, year?: number } fn: { type: Function as PropType<() => void> }, book: { type: Object as ProType<Book> }
-
- computed:
computedProp(): string {}
- ref:
const year = ref<string | number>('2021)
- reactive:
const book = reactive<Book>()
- 组件
const model = ref<InstanceType<typeof MyComponent>>()
- 类型声明文件
src/types/*.d.ts
Vite
vite.config.js
参考
- vue3官方文档
- 最后感兴趣的可以看看markmap这个工具是markdown转思维导图的,同时提供VSCode插件