Understanding of setup, ref and reactive in Vue3

setup

Composition API is used in Vue3, so that all composition API functions are used here, and only executed once during initialization.
If the function returns an object, the properties or methods in the object can be used directly in the template

Some details of setup

1. The timing and return value of setup execution:

  • Execute (once) before beforeCreate, at this time the component object has not been created, and data/computed/methods/props cannot be accessed through this
  • The return value is generally an object, and the properties/methods in the returned object will be merged with the properties of the object returned by the data/methods function to become the properties/methods of the component object
  • The properties and methods provided by setup can be accessed in methods, but data and methods cannot be accessed in the setup method;
  • setup cannot be an async function: because the return value is no longer the return object, but a promise, the template cannot see the attribute data in the return object
  • If there is a duplicate name, setup takes precedence

2. Setup parameters:

  • setup(props, context) / setup(props, {attrs, slots, emit})
  • props: An object containing all the properties declared by the props configuration and passed in
  • attrs: an object containing attributes not declared in the props configuration, equivalent to this.$attrs
  • slots: an object containing all incoming slot content, equivalent to this.$slots
  • emit: A function used to distribute custom events, equivalent to this.$emit
props: ['msg'],
emits: ['fn'], // 可选的, 声明了更利于程序员阅读, 且可以对分发的事件数据进行校验
setup (props, {
     
     attrs, emit, slots}) {
    
    
	console.log(props.msg, attrs.msg2, slots, emit)
	function toClick(){
    
    
		emit(fn, 'xxxxx') // 相当于 this.$emit
	}
}

ref

Function: Define a response type of data
Syntax: const xxx = ref(initValue)
is generally used to define a basic type of response type data

  • Create a reference object containing reactive data
  • Operation data in js: xxx.value
  • Operate data in the template: no need for .value

Combining setup and ref instructions

Among them, the writing method of vue2 is:

<template>
  <h2>{
   
   {count}}</h2>
  <hr>
  <button @click="update">更新</button>
</template>

<script>
export default {
      
      
  /* 在Vue3中依然可以使用data和methods配置, 但建议使用其新语法实现 */
   data () {
      
      
     return {
      
      
       count: 0
     }
   },
   methods: {
      
      
     update () {
      
      
       this.count++
     }
   }
}
</script>

The writing method of vue3 is:

  1. setup will eventually return an object, and the value in the object can be used in the template, such as count
  2. To ensure responsiveness, ref must be used
<template>
  <h2>{
   
   {count}}</h2>
  <hr>
  <button @click="update">更新</button>
</template>

<script>
import {
      
      
  ref
} from 'vue'
export default {
      
      
  /* 使用vue3的composition API */
  setup () {
      
      
    // 定义响应式数据 ref对象
    const count = ref(1)
    console.log(count)

    // 更新响应式数据的函数
    function update () {
      
      
      count.value = count.value + 1
    }

    return {
      
      
      count,
      update
    }
  }
}
</script>

reactive

Role: Define the responsiveness of multiple data, such as an object;
const isProxy = reactive(obj): A responsive proxy that receives a common object and then returns the common object. The responsive
conversion of the object is "deep": it will affect the internals of the object All nested properties
are internally implemented based on ES6 Proxy, and the internal data of the source object is operated through the proxy object.

<template>
  <h2>name: {
   
   {state.name}}</h2>
  <h2>age: {
   
   {state.age}}</h2>
  <h2>wife: {
   
   {state.wife}}</h2>
  <hr>
  <button @click="update">更新</button>
</template>

<script>
import {
      
       reactive } from 'vue'
export default {
      
      
  setup () {
      
      
    /*  定义响应式数据对象 */
    let obj = {
      
      
      name: 'tom',
      age: 25,
      wife: {
      
      
        name: 'marry',
        age: 22
      },
    };
    // 此时state通过 reactive代理了obj,使其内属性成为响应式的;
    const state = reactive(obj)
    // 此时打印state 会得到一个Proxy的一个对象
    // state---代理对象,obj---目标对象
    console.log(state)

    const update = () => {
      
      
      state.name += '--'
      state.age += 1
      state.wife.name += '++'
      state.wife.age += 2
    }

    return {
      
      
      state,
      update,
    }
  }
}
</script>

Summary: If you operate the proxy object, the value in the target object will also change. If you want the page to be rendered, you must also operate the proxy object;

Some details of ref and reactive

  • It is the two most important responsive APIs in Vue3's composition API;
  • ref is used to process basic types of data, and reactive is used to process objects (recursive depth response);
  • If a ref object/array is used, the object/array will be automatically converted to a reactive proxy object internally;
  • Inside ref: hijack data by adding getter/setter to value attribute;
  • Reactive internal: Hijack all data inside the object by using Proxy, and manipulate the internal data of the object through Reflect;
  • Data manipulation of ref: .value is required in js, not required in the template (.value will be added automatically when the template is parsed internally)
export default {
    
    

  setup () {
    
    
    const m1 = ref('abc')
    const m2 = reactive({
    
    x: 1, y: {
    
    z: 'abc'}})

    // 使用ref处理对象  ==> 对象会被自动reactive为proxy对象
    const m3 = ref({
    
    a1: 2, a2: {
    
    a3: 'abc'}})
    console.log(m1, m2, m3)
    console.log(m3.value.a2) // 也是一个proxy对象

    function update() {
    
    
      m1.value += '--'
      m2.x += 1
      m2.y.z += '++'

      m3.value = {
    
    a1: 3, a2: {
    
    a3: 'abc---'}}
      m3.value.a2.a3 += '==' // reactive对对象进行了深度数据劫持
      console.log(m3.value.a2)
    }

    return {
    
    
      m1,
      m2,
      m3,
      update
    }
  }
}

Although vue3 responsiveness is cumbersome to write, it reduces the performance overhead brought by vue2 responsiveness

Guess you like

Origin blog.csdn.net/weixin_44684357/article/details/132177322