Vue3使用总结
setup
vue2使用选项型API在代码里分割了不同的属性(properties):data,computed属性,methods,等等。setup 是 Vue3.x 新增的一个选项, 他是组件内使用 Composition API的入口,执行时机在 beforeCreate 之前执行。使用setup时,它接受两个参数:
- props: 组件传入的属性
- context
setup 中接受的props是响应式的, 当传入新的 props 时,会及时被更新。由于是响应式的, 所以
不可以使用 ES6 解构,解构会消除它的响应式(响应式需要依赖a.b这种访问方式来触发proxy拦截,但是解构就相当于直接访问b了,所以就失去了响应性)
setup中不能访问 Vue2 中最常用的this对象,所以context中就提供了this中最常用的三个属性:attrs、slot 和emit,分别对应 Vue2.x 中的 $attr属性、slot插槽 和$emit发射事件。并且这几个属性都是自动同步最新的值,所以我们每次使用拿到的都是最新值。
reactive,ref 和 toRefs
在 vue2.x 中, 定义数据都是在data中, 但是 Vue3.x 可以使用reactive和ref来进行数据定义。
想使用解构后的数据怎么办,解决办法就是
使用toRefs。 toRefs 用于将一个 reactive 对象转化为属性全部为 ref 对象的普通对象。
生命周期钩子
Vue3.0 新增了setup,这个在前面我们也详细说了, 然后是将 Vue2.x 中的beforeDestroy名称变更成beforeUnmount; destroyed 表更为 unmounted,
其次,钩子命名都增加了on; Vue3.x 还新增用于调试的钩子函数onRenderTriggered和onRenderTricked。
watch和watchEffect
watch
watch 函数用来侦听特定的数据源,并在回调函数中执行副作用。默认情况是惰性的,也就是说仅在侦听的源数据变更时才执行回调。
watch(source, callback, [options])
参数说明:
- source: 可以支持 string,Object,Function,Array; 用于指定要侦听的响应式变量
- callback: 执行的回调函数
- options:支持 deep、immediate 和 flush 选项。
- //侦听reactive定义的数据
- import { defineComponent, ref, reactive, toRefs, watch } from "vue";
- export default defineComponent({
- setup() {
- const state = reactive({ nickname: "xiaofan", age: 20 });
- setTimeout(() => {
- state.age++;
- }, 1000);
- // 修改age值时会触发 watch的回调
- watch(
- () => state.age,
- (curAge, preAge) => {
- console.log("新值:", curAge, "老值:", preAge);
- }
- );
- return {
- …toRefs(state),
- };
- },
- });
- //侦听ref定义的数据
- const year = ref(0);
- setTimeout(() => {
- year.value++;
- }, 1000);
- watch(year, (newVal, oldVal) => {
- console.log("新值:", newVal, "老值:", oldVal);
- });
- //多个数据
- watch([() => state.age, year], ([curAge, newVal], [preAge, oldVal]) => {
- console.log("新值:", curAge, "老值:", preAge); console.log("新值:", newVal,
- "老值:", oldVal); });
- //复杂
- const state = reactive({
- room: {
- id: 100,
- attrs: {
- size: "140平方米",
- type: "三室两厅",
- },
- },
- });
- watch(
- () => state.room,
- (newType, oldType) => {
- console.log("新值:", newType, "老值:", oldType);
- },
- { deep: true }
- );
复制代码 如果不使用第三个参数deep:true, 是无法监听到数据变化的。
stop停止监听
在组件中创建的watch监听,会在组件被销毁时自动停止。如果在组件销毁之前我们想要停止掉某个监听, 可以调用watch()函数的返回值
- const stopWatchRoom = watch(() => state.room, (newType, oldType) => {
- console.log("新值:", newType, "老值:", oldType);
- }, {deep:true});
- setTimeout(()=>{
- // 停止监听
- stopWatchRoom()
- }, 3000)
复制代码
watchEffect
watchEffect会自动收集依赖, 只要指定一个回调函数。在组件初始化时, 会先执行一次来收集依赖, 然后当收集到的依赖中数据发生变化时, 就会再次执行回调函数。
- watchEffect 不需要手动传入依赖
- watchEffect 会先执行一次用来自动收集依赖
- watchEffect 无法获取到变化前的值, 只能获取变化后的值
自定义Hooks
我们约定这些「自定义 Hook」以 use 作为前缀,和普通的函数加以区分。
对比vue2和vue3的响应式
Teleport传送
使用 teleport 组件,通过 to 属性,指定该组件渲染的位置与 <div id=&#34;APP&#34;></div> 同级,也就是在 body 下,但是 Dialog 的状态 dialogVisible 又是完全由内部 Vue 组件控制.
- <template>
- <teleport to=&#34;body&#34;>
- <div class=&#34;dialog&#34;>
- <div class=&#34;dialog_wrapper&#34;>
- <div class=&#34;dialog_header&#34; v-if=&#34;title&#34;>
- <slot name=&#34;header&#34;>
- <span>{{ title }}</span>
- </slot>
- </div>
- </div>
- <div class=&#34;dialog_content&#34;>
- <slot></slot>
- </div>
- <div class=&#34;dialog_footer&#34;>
- <slot name=&#34;footer&#34;></slot>
- </div>
- </div>
- </teleport>
- </template>
复制代码
Suspense
新出的内置组件Suspense,可在嵌套层级中等待嵌套的异步依赖项,它提供两个template slot, 刚开始会渲染一个 fallback 状态下的内容, 直到到达某个条件后才会渲染 default 状态的正式内容
- <Suspense>
- <template #default>
- <async-component></async-component>
- </template>
- <template #fallback>
- <div>
- Loading…
- </div>
- </template>
- </Suspense>
复制代码
片段(Fragment)
在 Vue2.x 中, template中只允许有一个根节点;在 Vue3.x 中,可以直接写多个根节点。
Tree-Shaking
以前的全局 API 现在只能通过具名导入,不再打包没用到的模块
相对于Vue2的变更
slot具名插槽语法
vue2:
- <!– 子组件中:–>
- <slot name=&#34;title&#34;></slot>
- //父组件
- <template slot=&#34;title&#34;>
- <h1>歌曲:成都</h1>
- <template>
- // 子组件
- <slot name=&#34;content&#34; :data=&#34;data&#34;></slot>
- export default {
- data(){
- return{
- data:[&#34;走过来人来人往&#34;,&#34;不喜欢也得欣赏&#34;,&#34;陪伴是最长情的告白&#34;]
- }
- }
- }
- <!– 父组件中使用 –>
- <template slot=&#34;content&#34; slot-scope=&#34;scoped&#34;>
- <div v-for=&#34;item in scoped.data&#34;>{{item}}</div>
- <template>
复制代码 在 Vue2.x 中具名插槽和作用域插槽分别使用slot和slot-scope来实现, 在 Vue3.0 中将slot和slot-scope进行了合并同意使用。 Vue3.0 中v-slot:
- <!– 父组件中使用 –>
- <template v-slot:content=&#34;scoped&#34;>
- <div v-for=&#34;item in scoped.data&#34;>{{item}}</div>
- </template>
- <!– 也可以简写成: –>
- <template #content=&#34;{data}&#34;>
- <div v-for=&#34;item in data&#34;>{{item}}</div>
- </template>
复制代码
v-model升级
变更:在自定义组件上使用v-model时, 属性以及事件的默认名称变了
变更:v-bind的.sync修饰符在 Vue 3 中又被去掉了, 合并到了v-model里
新增:同一组件可以同时设置多个 v-model
新增:开发者可以自定义 v-model修饰符
原创文章,作者:starterknow,如若转载,请注明出处:https://www.starterknow.com/126923.html