• web前端面试高频考点——Vue3.x深入理解(v-model参数用法、watch和watchEffect区别、Vue3快于Vue2、Vite启动快的原因)


    系列文章目录



    一、v-model 参数的用法

    1、Vue2.x 的 .sync

    在一个包含 title prop 的组件中,我们可以用以下方法表达对其赋新值的意图

    普通写法:

    this.$emit('update:title', newTitle)
    
    • 1
    <text-document
      v-bind:title="doc.title"
      v-on:update:title="doc.title = $event"
    >
    </text-document>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    .sync 修饰符(简写):

    <text-document v-bind:title.sync="doc.title"></text-document>
    
    • 1

    2、Vue3.x的 v-model:title=“xxx”

    若要更改 model 名称,而不是更改组件内的 model 选项,那么可以将一个 arguments 传递给 model

    <ChildComponent v-model:title="pageTitle"></ChildComponent>
    
    <!-- 是以下的简写 -->
    <ChildComponent :title="pageTitle" @update:title="pageTitle = $event"></ChildComponent>
    
    • 1
    • 2
    • 3
    • 4

    示例:

    index.vue 父组件

    <template>
      <p>{{ name }} {{ age }}</p>
      <UserInfo
        v-model:name="name"
        v-model:age="age"
      >
      </UserInfo>
    </template>
    
    <script>
    import { reactive, toRefs } from 'vue'
    import UserInfo from './UserInfo.vue';
    export default {
        name: 'VModel',
        components: {UserInfo},
        setup() {
            const state = reactive({
                name: '杂货铺',
                age: '20'
            })
    
            return toRefs(state)
        }
    };
    </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
    • 25

    UserInfo.vue 子组件

    • v-bind 绑定属性的 value
    • 监听 input 框内值的更新
    <template>
      <input :value="name" @input="$emit('update:name', $event.target.value)">
      <input :value="age" @input="$emit('update:age', $event.target.value)">
    </template>
    
    <script>
    export default {
        name: 'UserInfo',
        props: {
            name: String,
            age: String
        }
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述
    在这里插入图片描述

    二、watch 和 watchEffect 的区别

    • 两者都可监听 data 属性变化
    • watch 需要明确监听哪个属性
    • watchEffect 会根据其中的属性,自动监听其变化

    1、watch 监听(vue2.x)

    (1)示例:watch 监听 的变化

    • 第一个参数是要监听的属性
    • 第二个参数是新旧值
    • 第三个参数是初始化之前就监听(可选参数)
    <template>
      <p>watch vs watchEffect</p>
      <p>{{ numberRef }}</p>
    </template>
    
    <script>
    import { ref, toRefs, watch} from 'vue'
    export default {
        name: 'Watch',
        setup() {
       		// 定义值类型
            const numberRef = ref(100)
    
    		// watch 监听
            watch(numberRef, (newNumber, oldNumber) => {
                console.log('ref watch', newNumber, oldNumber);
            })
    
    		// 定时器,修改 numberRef 的值,用于监听
            setTimeout(() => {
                numberRef.value = 200
            }, 1000)
    
            return {
                numberRef,
            }
        }
    };
    </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
    • 25
    • 26
    • 27
    • 28
    • 29

    watch 监听可选的第三个参数

    immediate: true // 初始化之前就监听,可选
    
    • 1

    在这里插入图片描述

    在这里插入图片描述


    (2)示例:watch 监听 对象 的变化

    <template>
      <p>watch vs watchEffect</p>
      <p>{{ name }} {{ age }}</p>
    </template>
    
    <script>
    import { reactive, toRefs, watch} from 'vue'
    export default {
        name: 'Watch',
        setup() {
            const state = reactive({
                name: '杂货铺',
                age: 21
            })
    
            watch(
                // 第一个参数,确定要监听哪个属性
                () => state.age,
    
                // 第二个参数,回调函数
                (newAge, oldAge) => {
                    console.log('state watch', newAge, oldAge);
                },
    
                // 第三个参数,配置项,可选
                {
                    immediate: true, // 初始换之前就监听,可选
                    deep: true // 深度监听
                }
            )
    
            setTimeout(() => {
                state.age = 25
            }, 3000)
    
            setTimeout(() => {
                state.name = '前端杂货铺'
            }, 5000)
    
            return {
                ...toRefs(state)
            }
        }
    };
    </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
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述

    2、watchEffect 监听(Vue3.x)

    示例:watchEffect 监听对象变化

    <template>
      <p>watch vs watchEffect</p>
      <p>{{ name }} {{ age }}</p>
    </template>
    
    <script>
    import { reactive, toRefs, watchEffect} from 'vue'
    export default {
        name: 'Watch',
        setup() {
            const state = reactive({
                name: '杂货铺',
                age: 21
            })
    
            // 初始化时,一定会执行一次(收集要监听的数据)
            watchEffect(() => {
                console.log('hello watchEffect');
            })
    
            // 监听 state.name
            watchEffect(() => {
                console.log('state.name', state.name);
            })
    
            // 监听 state.age
            watchEffect(() => {
                console.log('state.age', state.age);
            })
    
            setTimeout(() => {
                state.age = 25
            }, 1500)
    
            setTimeout(() => {
                state.name = '前端杂货铺'
            }, 3000)
    
            return {
                ...toRefs(state)
            }
        }
    };
    </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
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述

    3、watch 和 watchEffect 的区别

    • 两者都可监听 data 属性变化
    • watch 需要明确监听哪个属性
    • watchEffect 会根据其中的属性,自动监听其变化

    三、在 setup 中如何获取组件实例

    • 在 setup 和其他 Composition API 中没有 this
    • 可通过 getCurrentInstance 获取当前实例
    • 若使用 Options API 可照常使用 this

    示例:使用 getCurrentInstance 获取当前实例

    <template>
      <p>setup中获取组件实例</p>
    </template>
    
    <script>
    import { getCurrentInstance, onMounted } from 'vue';
    export default {
        name: 'GetInstance',
        data() {
            return {
                x: 1
            }
        },
        setup() {
            // Composition API 没有 this => undefined
            console.log('this1', this);
    
            // 获取当前实例
            const instance = getCurrentInstance()
            console.log('instance', instance);
    
            // 挂载完成 => 通过 instance.data.x 获取 x 的值
            onMounted(() => {
            	// 挂载完也没有 this => undefined
                console.log('this in onMounted', this);
                console.log('x', instance.data.x);
            })
        },
        // vue2.x 中有 this,能直接取到值
        mounted() {
            console.log('this2', this);
            console.log('x', this.x);
        }
    };
    </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
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    在这里插入图片描述

    四、Vue3 为何比 Vue2 快

    • Proxy 响应式
    • PatchFlag
    • hoistStatic
    • cacheHandler
    • SRR 优化
    • tree-shaking

    1、PatchFlag

    • 编译模板时,动态节点做标记
    • 标记,分为不同的类型,如 TEXT PROPS
    • diff 算法时,可以区分静态节点,以及不同类型的动态节点

    测试地址:PatchFlag测试

    在这里插入图片描述

    Vue2.x 与 Vue3.x diff 算法的部分区别:

    在这里插入图片描述
    出处:https://coding.imooc.com/lesson/419.html#mid=41996

    2、hoistStatic

    • 将静态节点的定义,提升到父作用域,缓存起来
    • 多个相邻的静态节点,会被合并起来
    • 典型的拿空间换时间的优化策略

    Options 打开 hoistStatic:

    在这里插入图片描述

    3、cacheHandler

    • 缓存事件

    在这里插入图片描述

    4、SSR 优化

    • 静态节点直接输出,绕过了 vdom
    • 动态节点,还是需要动态渲染
      在这里插入图片描述

    5、tree shaking

    • 编译时,根据不同的情况,引入不同的 API

    需要什么就引入什么:

    在这里插入图片描述
    在这里插入图片描述

    五、Vite 为何启动快?

    • 开发环境使用 ES6 Module,无需打包 —— 非常快
    • 生产环境使用 rollup,并不会快很多

    示例:ES Module 在浏览器中的使用

    print.js 文件

    export default function (a, b) {
        console.log(a, b)
    }
    
    • 1
    • 2
    • 3

    add.js 文件

    import print from './print.js'
    
    export default function add(a, b) {
        print('print', 'add')
        return a + b
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    test.html

    • script 标签中要使用 type="module"
    • 导入所需文件
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>ES Module demo</title>
    </head>
    <body>
        <p>基本演示</p>
    
        <script type="module">
            import add from './src/add.js'
    
            const res = add(1, 2)
            console.log('add res', res)
        </script>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    六、Composition API 和 React Hooks 对比

    • 前者 setup 只会被调用一次,而后者函数会被多次调用
    • 前者无需 useMemo useCallback,因为 setup 只调用一次
    • 前者无需顾虑调用顺序,而后者需要保证 hooks 的顺序一致

    不积跬步无以至千里 不积小流无以成江海

    点个专注不迷路,持续更新中…

  • 相关阅读:
    大数据应用开发流程
    适用于车载设备无钥匙进入系统汽车用晶振FA-238A
    java11中String类,StringBuffer类和StringBuilder类区别
    [Linux] 进程等待
    温湿度阈值联网控制
    去除IDEA中代码的波浪线(黄色警示线)
    目标检测网络系列——YOLO V4
    简单了解一下:Node的util工具模块
    设计模式-14-迭代器模式
    【RuoYi-Cloud-Plus】学习笔记 02 - Nacos(二)寻址机制之文件寻址分析
  • 原文地址:https://blog.csdn.net/qq_45902692/article/details/126700615