Vue知识点及差常用函数整理 | 豆包MarsCode AI刷题

36 阅读6分钟

Vue2与Vue3的对比

  • 对TypeScript支持不友好(所有属性都放在了this对象上,难以推倒组件的数据类型)
  • 大量的API挂载在Vue对象的原型上,难以实现TreeShaking。
  • 架构层面对跨平台dom渲染开发支持不友好
  • CompositionAPI。受ReactHook启发
  • 更方便的支持了 jsx
  • Vue 3 的 Template 支持多个根标签,Vue 2 不支持
  • 对虚拟DOM进行了重写、对模板的编译进行了优化操作...

Vue3的响应式原理

Vue3的响应式原理是它的重要特性之一,它使得当数据发生变化时,视图会自动更新。Vue3的响应式原理主要依赖于Object.defineProperty和Proxy。当一个普通的对象被转化为响应式对象时,Vue会使用Proxy对其进行包装,从而实现属性的劫持和代理。当属性的值发生变化时,Vue会触发相应的更新操作。

Vue3的模板语法

Vue3的模板语法相对于Vue2并没有太大的变化,但也有一些小的改进和优化。例如,可以使用v-for指令来遍历数组和对象,使用v-if和v-else指令来进行条件渲染等。此外,Vue3还新增了一些指令,如v-slot指令用于插槽内容的位置指定等。

Vue3的生命周期钩子函数

在Vue3中,生命周期钩子函数是非常重要的一个概念。它是指在组件的生命周期中不同阶段可以调用的函数。通过使用生命周期钩子函数,可以控制组件的行为和状态。例如,在created钩子函数中可以初始化数据和执行一些初始化操作;在mounted钩子函数中可以挂载DOM元素并执行一些DOM操作等。

Vue3的路由和状态管理

在构建大型应用时,路由和状态管理是非常重要的一个环节。Vue Router是Vue官方的路由管理器,它与Vue3完美集成,提供了丰富的路由功能和配置选项。同时,Vuex也是Vue的状态管理库,它可以帮助开发者更好地管理应用的状态和数据流。

一、setup 函数

setup() 函数是 vue3 中,专门为组件提供的新属性。它为我们使用 vue3 的 Composition API 新特性提供了统一的入口, setup 函数会在 beforeCreate 、created 之前执行, vue3也是取消了这两个钩子,统一用setup代替, 该函数相当于一个生命周期函数,vue中过去的data,methods,watch等全部都用对应的新增api写在setup()函数中

setup(props, context) {
    context.attrs
    context.slots
    context.emit
    
    return {
        
    }
    }
  • props: 用来接收 props 数据
  • context 用来定义上下文, 上下文对象中包含了一些有用的属性,这些属性在 vue 2.x 中需要通过 this 才能访问到, 在 setup() 函数中无法访问到 this,是个 undefined
  • 返回值: return {}, 返回响应式数据, 模版中需要使用的函数

二、reactive 函数

reactive() 函数接收一个普通对象,返回一个响应式的数据对象, 想要使用创建的响应式数据也很简单,创建出来之后,在setup中return出去,直接在template中调用即可

<template>
    {{name}} // test
<template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
export default defineComponent({
    setup(props, context) {
    
    let state = reactive({
        name'test'
    });
    
    return state
    }
});
</script>

三、ref() 函数

ref() 函数用来根据给定的值创建一个响应式的数据对象,ref() 函数调用的返回值是一个对象,这个对象上只包含一个 value 属性, 只在setup函数内部访问ref函数需要加.value

<template>
    <div class="mine">
        {{count}} // 10
    </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
    setup() {
    const count = ref<number>(10)
    // 在js 中获取ref 中定义的值, 需要通过value属性
    console.log(count.value);
    return {
        count
    }
    }
});
</script>

在 reactive 对象中访问 ref 创建的响应式数据

<template>
    <div class="mine">
        {{count}} -{{t}} // 10 -100
    </div>
</template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
export default defineComponent({
    setup() {
    const count = ref<number>(10)
    const obj = reactive({
        t100,
        count
    })
    // 通过reactive 来获取ref 的值时,不需要使用.value属性
    console.log(obj.count);
    return {
        ...toRefs(obj)
    }
    }
});
</script>

四、isRef() 函数

isRef() 用来判断某个值是否为 ref() 创建出来的对象

<script lang="ts">
import { defineComponent, isRef, ref } from 'vue';
export default defineComponent({
    setup(props, context) {
    const name: string = 'vue'
    const age = ref<number>(18)
    console.log(isRef(age)); // true
    console.log(isRef(name)); // false

    return {
        age,
        name
    }
    }
});
</script>

五、toRefs() 函数

toRefs() 函数可以将 reactive() 创建出来的响应式对象,转换为普通的对象,只不过,这个对象上的每个属性节点,都是 ref() 类型的响应式数据

<template>
    <div class="mine">
    {{name}} // test
    {{age}} // 18
    </div>
</template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
export default defineComponent({
    setup(props, context) {
    let state = reactive({
        name'test'
    });

    const age = ref(18)
    
    return {
        ...toRefs(state),
        age
    }
    }
});
</script>

六、computed()

该函数用来创造计算属性,和过去一样,它返回的值是一个ref对象。里面可以传方法,或者一个对象,对象中包含set()、get()方法

6.1 创建只读的计算属性

import { computed, defineComponent, ref } from 'vue';
export default defineComponent({
    setup(props, context) {
    const age = ref(18)

    // 根据 age 的值,创建一个响应式的计算属性 readOnlyAge,它会根据依赖的 ref 自动计算并返回一个新的 ref
    const readOnlyAge = computed(() => age.value++) // 19

    return {
        age,
        readOnlyAge
    }
    }
});
</script>

6.2 通过set()、get()方法创建一个可读可写的计算属性

<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
export default defineComponent({
    setup(props, context) {
    const age = ref<number>(18)

    const computedAge = computed({
        get() => age.value + 1,
        setvalue => age.value + value
    })
    // 为计算属性赋值的操作,会触发 set 函数, 触发 set 函数后,age 的值会被更新
    age.value = 100
    return {
        age,
        computedAge
    }
    }
});
</script>

七、 watch() 函数

watch 函数用来侦听特定的数据源,并在回调函数中执行副作用。默认情况是懒执行的,也就是说仅在侦听的源数据变更时才执行回调。

7.1 监听用reactive声明的数据源

<script lang="ts">
import { computed, defineComponent, reactive, toRefs, watch } from 'vue';
interface Person {
    namestring,
    agenumber
}
export default defineComponent({
    setup(props, context) {
    const state = reactive<Person>({ name'vue'age10 })

    watch(
        () => state.age,
        (age, preAge) => {
        console.log(age); // 100
        console.log(preAge); // 10
        }
    )
    // 修改age 时会触发watch 的回调, 打印变更前后的值
    state.age = 100
    return {
        ...toRefs(state)
    }
    }
});
</script>

7.2 监听用ref声明的数据源

<script lang="ts">
import { defineComponent, ref, watch } from 'vue';
interface Person {
    namestring,
    agenumber
}
export default defineComponent({
    setup(props, context) {
    const age = ref<number>(10);

    watch(age, () => console.log(age.value)); // 100
    
    // 修改age 时会触发watch 的回调, 打印变更后的值
    age.value = 100
    return {
        age
    }
    }
});
</script>

7.3 同时监听多个值

<script lang="ts">
import { computed, defineComponent, reactive, toRefs, watch } from 'vue';
interface Person {
    namestring,
    agenumber
}
export default defineComponent({
    setup(props, context) {
    const state = reactive<Person>({ name'vue'age10 })

    watch(
        [() => state.age() => state.name],
        ([newName, newAge], [oldName, oldAge]) => {
        console.log(newName);
        console.log(newAge);

        console.log(oldName);
        console.log(oldAge);
        }
    )
    // 修改age 时会触发watch 的回调, 打印变更前后的值, 此时需要注意, 更改其中一个值, 都会执行watch的回调
    state.age = 100
    state.name = 'vue3'
    return {
        ...toRefs(state)
    }
    }
});
</script>

7.4 stop 停止监听

在 setup() 函数内创建的 watch 监视,会在当前组件被销毁的时候自动停止。如果想要明确地停止某个监视,可以调用 watch() 函数的返回值即可,语法如下:

<script lang="ts">
import { set } from 'lodash';
import { computed, defineComponent, reactive, toRefs, watch } from 'vue';
interface Person {
    namestring,
    agenumber
}
export default defineComponent({
    setup(props, context) {
    const state = reactive<Person>({ name'vue'age10 })

    const stop =  watch(
        [() => state.age() => state.name],
        ([newName, newAge], [oldName, oldAge]) => {
        console.log(newName);
        console.log(newAge);

        console.log(oldName);
        console.log(oldAge);
        }
    )
    // 修改age 时会触发watch 的回调, 打印变更前后的值, 此时需要注意, 更改其中一个值, 都会执行watch的回调
    state.age = 100
    state.name = 'vue3'

    setTimeout(()=> { 
        stop()
        // 此时修改时, 不会触发watch 回调
        state.age = 1000
        state.name = 'vue3-'
    }, 1000// 1秒之后讲取消watch的监听
    
    return {
        ...toRefs(state)
    }
    }
});
</script>