vue3

84 阅读5分钟

defineComponent

  • defineComponent可以给组件的setup方法准确的参数类型定义.
  • defineComponent 可以接受显式的自定义 props 接口或从属性验证对象中自动推断
  • defineComponent 可以正确适配无 props、数组 props 等形式
  • 引入 defineComponent() 以正确推断 setup() 组件的参数类型

setup是一个函数。

  • 新的option,所有的组合API函数都在此使用,只在初始化时执行一次。
  • 函数如果返回对象,对象中的属性或方法,模板中可以直接使用。
  • 代替beforeCreate和Created这两个生命周期 setup执行在beforeCreate之前且执行一次 此时this是undefined
  • 两个参数props和context={$attrs,$slots,$emit}

ref

ref 创建响应式数据

const count = ref(0);

  • ref是一个函数,返回的是一个Ref对象。
  • 作用:用来定义一个响应式的数据。
  • 一般用来定义一个基本类型的响应式数据,如果想要定义一个对象类型的响应式数据可以使用函数reactive

ref 获取页面元素

ref函数可以获取页面中已经加载完毕的元素。

<template>
    <!-- 1. 在标签中使用 ref 属性绑定一个数据 -->
    <input type="text" id="demo" ref="inputRef" />
</template>

<script lang="ts">
import { defineComponent, onMounted, ref } from "vue";

export default defineComponent({
    setup() {
        //2. 调用ref创建初始值为null的响应数据
        const inputRef = ref < HTMLElement | null > (null);

        onMounted(() => {
            //3. 在生命周期函数onMounted页面已经渲染好了,可以在这里拿到页面的元素
            console.log(inputRef.value);
            //<input type="text" id="demo">

            //表示标签存在时,就让该标签自动获取焦点
            inputRef.value && inputRef.value.focus();
        });

        return {
            inputRef,
        };
    },
});
</script>

toRef

const state = reactive({
    age: 5,
    money: 100,
})

const age = toRef(state, "age")

toRefs

  • toRefs 函数可以将一个响应式对象转换为一个普通的对象,该对象的每个属性都是独立的 ref 对象。
  • 返回的对象可以进行解构,每个属性都可以像普通的 ref 对象一样访问和修改,而且会保持响应式的关联。
  • toRefs 的使用场景主要是在将响应式对象作为属性传递给子组件时,确保子组件可以正确地访问和更新这些属性。

reactive

  • reactive是一个函数,返回一个代理对象Proxy
  • 作用:用来定义多个响应式的数据。
  • const proxy = reactive(obj): 接收一个普通对象然后返回该普通对象的响应式代理器对象。obj是被代理的对象,proxy是代理对象。
  • 响应式转换是深层的:会影响对象内部所有嵌套的属性。
  • 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的。
  • reactive函数接收一个普通对象作为参数,然后返回该普通对象的代理对象Proxy 通过代理对象添加属性、或删除属性可以同时更改代理对象与被代理对象,并且还可以实时渲染到界面。但是通过被代理对象操作,也是可以更改被代理对象的,但是不可以渲染到界面。

响应式原理

Proxy 文档:developer.mozilla.org/zh-CN/docs/…
Reflect 文档:developer.mozilla.org/zh-CN/docs/…


  • 先通过 Proxy 代理对象拦截目标对象的任意属性的任意(13种)操作,包括属性值的读写、属性的添加,、属性的删除等。
  • 然后通过 Reflect 反射对象,动态地对被代理对象的相应属性进行特定的操作。
<script type="text/javascript">
    //1. 目标对象(被代理对象)
    const user = {
        name: '张三',
        wife: {
            name: '小樱'
        }
    }

    //2. 代理对象
    const proxyUser = new Proxy(user, {
        //获取目标对象的属性值
        get(target, prop) {
            return Reflect.get(target, prop)
        },
        //修改或新增目标对象的属性
        set(target, prop, val) {
            return Reflect.set(target, prop, val)
        },
        //删除目标对象属性
        deleteProperty(target, prop) {
            return Reflect.deleteProperty(target, prop)
        }
    })

    //3. 通过代理对象获取属性
    console.log(proxyUser.name)
    //张三

    //4. 通过代理对象更改属性
    proxyUser.name = '王五'
    console.log(user)
    //{name: '王五', wife: {…}}

    //5. 通过代理对象添加新属性
    proxyUser.gender = '男'
    console.log(user)
    //{name: '王五', wife: {…}, gender: '男'}

    //6. 通过代理对象删除属性
    delete proxyUser.gender
    console.log(user)
    //{name: '王五', wife: {…}}
</script>

computed计算属性

/* 语法1 */
//当只传入一个回调函数时,该回调函数默认为get函数
//当targetValue发送变化时,computed能够监视到数据的变化,并将变化后的值返回
//computed函数返回一个ComputedRef对象,是一个响应式的对象
const returnVal = computed(() => {
    return targetValue
})

/* 语法2 */
//当需要get与set函数时,应该传入一个对象
//当returnVal发送改变时,val就是returnVal改变后的值
const returnVal = computed({
    get() { return targetValue }
    set(val) { targetValue = val }
})

watch监视

1. 调用语法

/* 语法1:只监视一个数据 */
//data:被监视的数据
//(val) => {}:当data发生变化时该回调函数就会被调用
//val:就是data发生变化后的新数据
//immediate:true则默认自动执行一次,因为当obj发生变化时回调才会被调用,newObj才有值,
//    但是首次初始化obj时obj并没有发生变化,newObj就是一个空对象。
//deep:true则进行深度监视,即obj可能有多层嵌套,每一层都会被监视;false则只监视obj对象的第一层
watch(data, (val) => {}, {immediate: true, deep: true})

//如果data是一个对象{lastName: '', firstName: ''},也可以如下写
watch(data, ({lastName, firstName}) => {}, {immediate: true, deep: true})


/* 语法2:监视多个数据 */
//当 obj.val1 不是响应式数据时,需要以 ()=>obj.val1 声明才能被监视到
//vals是一个数组,顺序就是 [()=>obj.val1, ()=>obj.val2] 的顺序
watch([()=>obj.val1, ()=>obj.val2], (vals) => {})

watchEffect监视

watchEffectwatch的区别是:watchEffect不需要配置{ immediate: true, deep: true },默认初始化时就执行一次并可以深层监视。
1. 调用语法

//直接将targetObj放入回调函数就可以监视targetObj对象的变化了
watchEffect(() => { targetObj })

生命周期

vue2中的生命周期加on重命名

原文在[这里](https://www.kancloud.cn/king_om/uikuangjiazongjie/2734074)