• Vue3.x新特性 Vue3新功能(详细)


    Vue3.x新特性 Vue3新功能(详细)

    1:setup

    setup 取代了 beforeCreate created

    setup作用:之前,我们需要在data、methods、mounted的不同位置编写代码,分散的区域很大。现在我们可以在setup中实现它。

    <template>
      <div>{{name}}</div>
    </template>
    <script>
    import {ref} from "vue"
    
    export default {
      name: "App",
      setup() {
        let name = ref(0);
        return {name};
      },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    这里的ref代替了data的双向绑定,最后我们需要返回一个对象。

    有关setup的更多详细信息

    2:指令生命周期

    vue2.x:

    • bind
    • inserted
    • update
    • componentUpdated
    • unbind

    vue3.x:

    • beforeMount
    • mounted
    • beforeUpdate
    • updated
    • beforeUnmount
    • unmounted

    3:数据(data)

    清单:

    1. ref
    2. toRefs
    3. toRef

    vue2使用data初始化数据并进行双向绑定,现在使用ref来实现。

    3.1:ref

    <template>
      <div>age is:{{age}}</div>
    </template>
    <script>
    import {ref} from "vue"
    
    export default {
      name: "App",
      setup() {
        let age = ref(20);
        return {age};
      },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    修改双向绑定的值,需要使用 value 属性,如:age.value

    <template>
      <div>age is:{{age}}</div>
    </template>
    <script>
    import {ref} from "vue"
    
    export default {
      name: "App",
      setup() {
        let age = ref(20);
    
        setTimeout(() => {
          age.value = 22;
        }, 2000);
        
        return {age};
      },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    3.2:toRefs

    toRefs() 期望一个响应对象,并根据响应对象属性值的自动变化来渲染页面。

    <template>
      <div>name is:{{obj.name}}</div>
    </template>
    <script>
    import { toRefs,reactive } from 'vue';
    
    export default {
      name: "App",
      setup() {
        let obj = reactive({
          name:'anny',
          age:22
        })
    
        let objs = toRefs(obj);
    
        setTimeout(() => {
          objs.name.value = 'tony'
        }, 2000);
    
        return {obj};
      },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3.3:toRef

    toRef() 期望一个响应对象及参数,并根据响应对象属性值的自动变化来渲染页面。

    <template>
      <div>name is:{{obj.name}}</div>
    </template>
    <script>
    import { toRef,reactive } from 'vue';
    
    export default {
      name: "App",
      setup() {
        let obj = reactive({
          name:'anny',
          age:22
        })
    
        let names = toRef(obj,'name');
    
        setTimeout(()=>{
          names.value = 'tony';
        },2000)
    
        return {obj};
      },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3.4:ref,toRef,toRefs 的区别

    • ref:主要用于绑定 非对象类型 的参数。
    • toRef:主要用于绑定 对象类型 ,将 单个reactive对象属性转换ref,保持与父对象的连接
    • toRefs:主要用于绑定 对象类型 ,将 所有 reactive对象属性转换ref,保持与父对象的连接

    4:监听

    • vue2.x:watch
    • vue3.x:watchEffect

    相较于 watchwatchEffect 传入回调函数,不需要指定监听的数据源,自动收集响应式数据。

    <template>
      <div>age is:{{age}}</div>
    </template>
    <script>
    import { ref, watchEffect } from 'vue';
    
    export default {
      name: "App",
      setup() {
        let age = ref(0);
    
        setTimeout(() => {
          age.value+=1;
        }, 2000);
    
        watchEffect(()=>{
          console.log(age.value)
        })
    
        return {age};
      },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    5:slot

    通过在 template 标签上使用 v-slot 并指定插槽名称来实现命名插槽。

    App.vue:

    <template>
      <HelloWorld>
        <template v-slot:test>
          <h1>hello test</h1>
        </template>
      </HelloWorld>
    </template>
    <script>
    import HelloWorld from "./components/HelloWorld.vue";
    
    export default {
      name: "App",
      components: { HelloWorld },
      setup() {},
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    HelloWorld.vue:

    <template>
      <div class="hello">
        <slot name="test"></slot>
      </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5.1:让插槽内容能够访问子组件中的数据

    要使父级提供的插槽可以访问子组建的数据,我们需要在子组建添加一个 slot 元素并将其作为一个 attribute 绑定:

    如:这里我们在子组建使用了 myName

    HelloWorld.vue:

    <template>
      <div class="hello">
        <slot :myName="user.name" name="test"></slot>
      </div>
    </template>
    
    <script>
    export default {
      name: "HelloWorld",
      setup() {
        let user = {
          name: "anny",
          age: 22,
        };
        return {
          user,
        };
      },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在父级使用:

    App.vue:

    <template>
      <HelloWorld>
        <template v-slot:test='item'>
          <h1>hello {{item.myName}}</h1>
        </template>
      </HelloWorld>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5:v-model

    vue3.x 中无需再使用 .async 修饰。

    .async 实现对某一个 prop 进行“双向绑定”。

    6:teleport

    teleport 可以将模板的这一部分移动到 DOM 中 Vue app 之外的其他位置。

    请注意,目标元素必须在组件安装之前存在 - 即目标不能由组件本身渲染,理想情况下应该在整个 Vue 组件树之外。

    <!DOCTYPE html>
    <html lang="">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="icon" href="<%= BASE_URL %>favicon.ico">
        <title><%= htmlWebpackPlugin.options.title %></title>
      </head>
      <body>
      
        <!-- vue dom -->
        <div id="app"></div>
        
        <!-- vue之外其他dom -->
        <div id="some-id"></div>
        
      </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    组建 HelloWorld.vue 使用:

    <template>
      <div class="hello">
        <teleport to='#some-id'>123</teleport>
      </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    可用于全局弹窗,全局提醒等功能。

    7:defineAsyncComponent

    defineAsyncComponent 主要用于异步加载组建。

    defineAsyncComponent 接收一个 Promise 的工厂函数。

    <template>
      <div id="some-id">
          <AsyncCom />
      </div>
    </template>
    <script>
    import {defineAsyncComponent} from 'vue'
    const AsyncCom = defineAsyncComponent(function(){
      return import('./components/HelloWorld.vue')
    })
    export default {
      name: "App",
      components: { AsyncCom },
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    对于高价用法 AsyncCom 参数如下:

    const AsyncCom = defineAsyncComponent({
      // 工厂函数
      loader: () => import('./components/HelloWorld.vue'),
      // 加载异步组件时要使用的组件
      loadingComponent: LoadingComponent,
      // 加载失败时要使用的组件
      errorComponent: ErrorComponent,
      // 在显示 loadingComponent 之前的延迟 | 默认值:200(单位 ms)
      delay: 200,
      // 如果提供了 timeout ,并且加载组件的时间超过了设定值,将显示错误组件
      // 默认值:Infinity(即永不超时,单位 ms)
      timeout: 3000,
      // 定义组件是否可挂起 | 默认值:true
      suspensible: false,
      /**
       *
       * @param {*} error 错误信息对象
       * @param {*} retry 一个函数,用于指示当 promise 加载器 reject 时,加载器是否应该重试
       * @param {*} fail  一个函数,指示加载程序结束退出
       * @param {*} attempts 允许的最大重试次数
       */
      onError(error, retry, fail, attempts) {
        if (error.message.match(/fetch/) && attempts <= 3) {
          // 请求发生错误时重试,最多可尝试 3 次
          retry()
        } else {
          // 注意,retry/fail 就像 promise 的 resolve/reject 一样:
          // 必须调用其中一个才能继续错误处理。
          fail()
        }
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    8:多个根结点

    相较于 vue2.x,vue3.x允许包含多个根结点:

    vue2.x:

    <template>
      <div class="hello">
        <div>hello</div>
        <div>world</div>
      </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    vue3.x:

    <template>
      <div>hello</div>
      <div>world</div>
    </template>
    
    • 1
    • 2
    • 3
    • 4

    9:Proxy

    vue3.x中的数据变化劫持,由 definePoperty 改为了 Proxy

    10:diff 算法

    vue2.x:当数据发生变化时,会生成一个新的 DOM 树,与之前的 DOM 树进行比较,找到不同的节点并更新

    vue3.x: 在创建虚拟 DOM 树时,会根据 DOM 中的内容是否发生变化,添加一个静态标签。那么与上一个虚拟节点比较时,只会比较这些带有静态标签的节点。

    11:Vite

    作用:

    • 提高项目启动速度
    • 提高修改内容之后更新速度

    Vite文档

  • 相关阅读:
    题目0114-简易内存池2
    浅显直白的Python深拷贝与浅拷贝区别说明
    《Java编程思想》读书笔记(三)
    Go并发的非阻塞缓存
    安泰:功率放大器的工作原理以及注意事项有哪些
    Python多线程(一)
    AD教程 (九)导线及NetLabel的添加
    网络安全学习:操作系统安装部署
    代码随想录 Day46 动态规划14 LeetCode T392 判断子序列 T115 不同的子序列
    shell_57.Linux创建自己的重定向
  • 原文地址:https://blog.csdn.net/qq_41974199/article/details/125500509