1. 首页
  2. 技术知识

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 选项。
  1. //侦听reactive定义的数据
  2. import { defineComponent, ref, reactive, toRefs, watch } from "vue";
  3. export default defineComponent({
  4.   setup() {
  5.     const state = reactive({ nickname: "xiaofan", age: 20 });
  6.     setTimeout(() => {
  7.       state.age++;
  8.     }, 1000);
  9.     // 修改age值时会触发 watch的回调
  10.     watch(
  11.       () => state.age,
  12.       (curAge, preAge) => {
  13.         console.log("新值:", curAge, "老值:", preAge);
  14.       }
  15.     );
  16.     return {
  17.       …toRefs(state),
  18.     };
  19.   },
  20. });
  21. //侦听ref定义的数据
  22. const year = ref(0);
  23. setTimeout(() => {
  24.   year.value++;
  25. }, 1000);
  26. watch(year, (newVal, oldVal) => {
  27.   console.log("新值:", newVal, "老值:", oldVal);
  28. });
  29. //多个数据
  30. watch([() => state.age, year], ([curAge, newVal], [preAge, oldVal]) => {
  31. console.log("新值:", curAge, "老值:", preAge); console.log("新值:", newVal,
  32. "老值:", oldVal); });
  33. //复杂
  34. const state = reactive({
  35.   room: {
  36.     id: 100,
  37.     attrs: {
  38.       size: "140平方米",
  39.       type: "三室两厅",
  40.     },
  41.   },
  42. });
  43. watch(
  44.   () => state.room,
  45.   (newType, oldType) => {
  46.     console.log("新值:", newType, "老值:", oldType);
  47.   },
  48.   { deep: true }
  49. );

复制代码 如果不使用第三个参数deep:true, 是无法监听到数据变化的。


stop停止监听

在组件中创建的watch监听,会在组件被销毁时自动停止。如果在组件销毁之前我们想要停止掉某个监听, 可以调用watch()函数的返回值

  1. const stopWatchRoom = watch(() => state.room, (newType, oldType) => {
  2.     console.log("新值:", newType, "老值:", oldType);
  3. }, {deep:true});
  4. setTimeout(()=>{
  5.     // 停止监听
  6.     stopWatchRoom()
  7. }, 3000)

复制代码
watchEffect

watchEffect会自动收集依赖, 只要指定一个回调函数。在组件初始化时, 会先执行一次来收集依赖, 然后当收集到的依赖中数据发生变化时, 就会再次执行回调函数。

  • watchEffect 不需要手动传入依赖
  • watchEffect 会先执行一次用来自动收集依赖
  • watchEffect 无法获取到变化前的值, 只能获取变化后的值

自定义Hooks

我们约定这些「自定义 Hook」以 use 作为前缀,和普通的函数加以区分。


对比vue2和vue3的响应式

Teleport传送

使用 teleport 组件,通过 to 属性,指定该组件渲染的位置与 <div id="APP"></div> 同级,也就是在 body 下,但是 Dialog 的状态 dialogVisible 又是完全由内部 Vue 组件控制.

  1. <template>
  2.   <teleport to="body">
  3.     <div class="dialog">
  4.       <div class="dialog_wrapper">
  5.         <div class="dialog_header" v-if="title">
  6.           <slot name="header">
  7.             <span>{{ title }}</span>
  8.           </slot>
  9.         </div>
  10.       </div>
  11.       <div class="dialog_content">
  12.         <slot></slot>
  13.       </div>
  14.       <div class="dialog_footer">
  15.         <slot name="footer"></slot>
  16.       </div>
  17.     </div>
  18.   </teleport>
  19. </template>

复制代码
Suspense

新出的内置组件Suspense,可在嵌套层级中等待嵌套的异步依赖项,它提供两个template slot, 刚开始会渲染一个 fallback 状态下的内容, 直到到达某个条件后才会渲染 default 状态的正式内容

  1. <Suspense>
  2.         <template #default>
  3.             <async-component></async-component>
  4.         </template>
  5.         <template #fallback>
  6.             <div>
  7.                 Loading…
  8.             </div>
  9.         </template>
  10.   </Suspense>

复制代码
片段(Fragment)

在 Vue2.x 中, template中只允许有一个根节点;在 Vue3.x 中,可以直接写多个根节点。


Tree-Shaking

以前的全局 API 现在只能通过具名导入,不再打包没用到的模块


相对于Vue2的变更

slot具名插槽语法

vue2:

  1. <!–  子组件中:–>
  2. <slot name="title"></slot>
  3. //父组件
  4. <template slot="title">
  5.     <h1>歌曲:成都</h1>
  6. <template>
  7. // 子组件
  8. <slot name="content" :data="data"></slot>
  9. export default {
  10.     data(){
  11.         return{
  12.             data:["走过来人来人往","不喜欢也得欣赏","陪伴是最长情的告白"]
  13.         }
  14.     }
  15. }
  16. <!– 父组件中使用 –>
  17. <template slot="content" slot-scope="scoped">
  18.     <div v-for="item in scoped.data">{{item}}</div>
  19. <template>

复制代码 在 Vue2.x 中具名插槽和作用域插槽分别使用slot和slot-scope来实现, 在 Vue3.0 中将slot和slot-scope进行了合并同意使用。 Vue3.0 中v-slot:

  1. <!– 父组件中使用 –>
  2. <template v-slot:content="scoped">
  3.    <div v-for="item in scoped.data">{{item}}</div>
  4. </template>
  5. <!– 也可以简写成: –>
  6. <template #content="{data}">
  7.     <div v-for="item in data">{{item}}</div>
  8. </template>

复制代码
v-model升级

变更:在自定义组件上使用v-model时, 属性以及事件的默认名称变了

变更:v-bind的.sync修饰符在 Vue 3 中又被去掉了, 合并到了v-model里

新增:同一组件可以同时设置多个 v-model

新增:开发者可以自定义 v-model修饰符

原创文章,作者:starterknow,如若转载,请注明出处:https://www.starterknow.com/126923.html

联系我们