customRef
-
作用:创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。
-
实现防抖效果:
<template> <input type="text" v-model="keyword" /> <h3>{{ keyword }}</h3> </template> <script> import { ref, customRef } from "vue"; export default { name: "Demo", setup() { // let keyword = ref('hello') //使用Vue准备好的内置ref //自定义一个myRef function myRef(value, delay) { let timer; //通过customRef去实现自定义 return customRef((track, trigger) => { return { get() { track(); //告诉Vue这个value值是需要被“追踪”的.即每次调用set更改value后,都重新调用get读取数据 return value; }, set(newValue) { clearTimeout(timer); timer = setTimeout(() => { value = newValue; trigger(); //告诉Vue去更新界面 }, delay); }, }; }); } let keyword = myRef("hello", 500); //使用程序员自定义的ref return { keyword, }; }, }; </script>
provide 与 inject
![](https://v3.cn.vuejs.org/images/components_provide.png)
-
作用:实现祖与后代组件间通信
-
套路:父组件有一个
provide
选项来提供数据,后代组件有一个inject
选项来开始使用这些数据 -
具体写法:
-
祖组件中:
setup(){ ...... let car = reactive({name:'奔驰',price:'40万'}) provide('car',car) ...... }
-
后代组件中:
setup(props,context){ ...... const car = inject('car') return {car} ...... }
-
响应式数据的判断
- isRef: 检查一个值是否为一个 ref 对象
- isReactive: 检查一个对象是否是由
reactive
创建的响应式代理 - isReadonly: 检查一个对象是否是由
readonly
创建的只读代理 - isProxy: 检查一个对象是否是由
reactive
或者readonly
方法创建的代理
Composition API 的优势
Options API 存在的问题
- 使用传统 OptionsAPI 中,新增或者修改一个需求,就需要分别在 data,methods,computed 里修改 。
Composition API 的优势
- 我们可以更加优雅的组织我们的代码,函数。让相关功能的代码更加有序的组织在一起。
# 新的组件
Fragment
- 在 Vue2 中: 组件必须有一个根标签
- 在 Vue3 中: 组件可以没有根标签, 内部会将多个标签包含在一个 Fragment 虚拟元素中
- 好处: 减少标签层级, 减小内存占用
Teleport
-
什么是 Teleport?——
Teleport
是一种能够将我们的组件 html 结构移动到指定位置的技术。<teleport to="移动位置"> <div v-if="isShow" class="mask"> <div class="dialog"> <h3>我是一个弹窗</h3> <button @click="isShow = false">关闭弹窗</button> </div> </div> </teleport>
Suspense
-
等待异步组件时渲染一些额外内容,让应用有更好的用户体验
-
Suspense 和异步组件的配合时,可以让 setup 返回一个 Promise 实例,即可以给 setup 添加 async
-
使用步骤:
-
异步引入组件
import { defineAsyncComponent } from "vue"; const Child = defineAsyncComponent(() => import("./components/Child.vue"));
-
使用
Suspense
包裹组件,并配置好default
与fallback
<template> <div class="app"> <h3>我是App组件</h3> <Suspense> <template v-slot:default> <Child /> </template> <template v-slot:fallback> <h3>加载中.....</h3> </template> </Suspense> </div> </template>
-
其他
全局 API 的转移
-
Vue 2.x 有许多全局 API 和配置。
-
例如:注册全局组件、注册全局指令等。
//注册全局组件 Vue.component('MyButton', { data: () => ({ count: 0 }), template: '<button @click="count++">Clicked {{ count }} times.</button>' }) //注册全局指令 Vue.directive('focus', { inserted: el => el.focus() }
-
-
Vue3.0 中对这些 API 做出了调整:
-
将全局的 API,即:
Vue.xxx
调整到应用实例(app
)上2.x 全局 API( Vue
)3.x 实例 API ( app
)Vue.config.xxxx app.config.xxxx Vue.config.productionTip 移除 Vue.component app.component Vue.directive app.directive Vue.mixin app.mixin Vue.use app.use Vue.prototype app.config.globalProperties
-
其他改变
-
data 选项应始终被声明为一个函数。
-
过度类名的更改:
-
Vue2.x 写法
.v-enter, .v-leave-to { opacity: 0; } .v-leave, .v-enter-to { opacity: 1; }
-
Vue3.x 写法
.v-enter-from, .v-leave-to { opacity: 0; } .v-leave-from, .v-enter-to { opacity: 1; }
-
-
移除keyCode 作为 v-on 的修饰符,同时也不再支持
config.keyCodes
-
移除
v-on.native
修饰符-
父组件中绑定事件
<my-component v-on:close="handleComponentEvent" v-on:click="handleNativeClickEvent" />
-
子组件中声明自定义事件
<script> export default { emits: ["close"], }; </script>
-
-
移除过滤器(filter)
过滤器虽然这看起来很方便,但它需要一个自定义语法,打破大括号内表达式是 “只是 JavaScript” 的假设,这不仅有学习成本,而且有实现成本!建议用方法调用或计算属性去替换过滤器。
-
…