学习 Vue 3.0 (1)

2022-05-29  本文已影响0人  Beppo

setup 函数

定义

  1. 理解:Vue3 中新增的一个配置项,值为一个函数

  2. setup 是所有 <font color="red">Composition API(组合式 API)</font> 表演的舞台

  3. 组件中所用到的数据、方法等均要匹配值在 setup 中,通过 setup 函数返回的对象中的属性来获取的

  4. setup 函数的有两种返回值

  1. 执行时机:beforeCreate 之前执行一次,this 是 undefined

setup 接收到的参数

// xxx.vue
<template>
  {{msg}}
</template>

<script>
export default {
  // setup(props,context) {
  setup(props,{emit, attr, slots}) {
    ......
    let msg = 'hello world'
    const setValue = () => {
      msg.value = 'hello'
    };
    return {
      msg,
      setValue
    }
  }
}
</script>
  • 尽量不要与 Vue2 配置混用

ref 函数

  1. 定义一个响应式数据
  2. 语法

<template>
  <div> {{ a }} </div>
  <div> {{ obj.msg }} </div>
</template>

<script>
export default {
  setup() {
    ....
    // 创建一个包含响应式数据的 引用对象`(reference 对象,称 ref 对象)
    let a = ref(1);
    let obj = {
      msg: 'hello',
      num: 2
    };
    const setValue = () => {
      // 取值 xxx.value
      console.log(a.value); // 1
      console.log(obj.value.msg); // hello
      // 设置值  xxx.value = newValue
      a.value = 2;
      obj.value.msg = 'world';
    };
    ....
    return {
      a,
      obj,
      setValue
    }
  }
}
</script>
  • 接收的数据: 基本数据类型、 对象类型
  • 基本类型数据:响应式靠 Object.defineProperty()getset 实现
  • 对象类型数据:内部使用 vue3.0 的新函数 reactive() 实现

reactive 函数

  1. 定义一个<font color='red'>对象类型</font>的响应式数据 (基本类型数据要是用 ref 实现)

  2. 语法: const 代理对象 = reactive(原始对象)接收一个对象(或数组)作为参数,返回一个<font color='red'>代理对象(Proxy 对象)</font>

const obj = reactive({
  a: 1,
  b: 2
});
  1. reactive 定义的响应式数据是‘深层次的’

  2. 内部基于 ES6 Proxy 实现,通过代理对象操作原始对象内部数据

reactive 与 ref

  1. 从定义数据

ref 也可以用来定义对象类型数据,它内部会自动通过 reactive 转为代理对象

  1. 从原理
  1. 从使用

toRef 与 toRefs

  1. toRef作用: 创建一个 ref 对象,其 value 值指向另一个对象中某个属性
  2. 语法:
const obj = reactive({
  a: 1,
  b: 2
});
const a = toRef(obj, a);
  1. 应用场景: 要将响应式中的某个属性单独提供给外部使用时
  2. toRefstoRef 功能一致,但是可以批量创建多个 ref 对象
const obj = reactive({
  a: 1,
  b: 2
});
const { a, b } = toRefs(obj);

Vue3.0 中的响应式原理

Vue 2.x 中的响应式原理

let person = {
  name: '张三',
  age: 18
};

let p = {};

defineProperty(p, 'name', {
  get() {
    return person.name;
  },
  set(newValue) {
    person.name = newValue;
  }
});

Vue 3.x 中的响应式原理

let person = {
  name: '张三',
  age: 18
};

const p = new Proxy(person, {
  // 读取某个属性时调用
  get(target, key) {
    return Reflect.get(target, key);
    // return target[key];
  },
  //  新增或修改属性时调用
  set(target, key, value) {
    return Reflect.set(target, key, value);
    // target[key] = value;
  },
  // 删除属性时调用
  deleteProperty(target, key) {
    return Reflect.deleteProperty(target, key);
    //  return delete target[key];
  }
});

shallowRef 与 shallowReactive

readonly 与 shallowReadonly

toRaw 与 markRaw

customRef

// 实现一个延迟的 ref
const delayRef = (value.delay)=> {
  let timer = null;
  return customRef((track,trigger) => {
    return {
      get(){
        track();
        return value;
      },
      set(newValue){
        clearTimeout(timer);
        timer = setTimeout(() =>{
          value = newValue;
          trigger();
        }, delay);
      }
    }
  })
}

provide 与 inject

// 父组件

import { provide } from 'vue';

setup(){
  ....
  let person = {
    name: '张三',
    age: 18
  };
  provide('person', person);
  ....
}

// 后代组件

import { inject } from 'vue';

setup(){
  ....
  const student = inject('person');
  ....
  return{
    student
  }

}

响应式数据判断

Composition API 的优势

上一篇 下一篇

猜你喜欢

热点阅读