preface

The official version of Vue3.0 has been released. Learn it sooner or later.

All the text of this article comes from my vue3 practice warehouse GitHub

Reactivity API

A set of apis that separate UI from data processing logic. The entry function setup();

ref() && reactive()

Both of these functions can make the data responsive. That is, data changes drive view (UI) changes. One of them. Ref typically wraps simple data types, and Reactive wraps reference data types.

So let’s look at the ref example

<template> <button @click="addCnt">count is: {{ cnt }}</button> </template> <script> import { ref } from 'vue'; Export default {name: 'Ref', // setup is the entry to composition API setup() {// define variable /state. Note that ref() starts with a lowercase letter, not ref. let cnt = ref(0); // ref can only listen to simple types of data, but cannot listen to complex types (objects/arrays). For complex types, use Reactive (). // define function (method) const addCnt = () => {// note that we must add value cnt.value++; }; Return {CNT, addCnt}; return {CNT, addCnt}; }}; </script> This is a simple adder demo. We declare a responsible state, CNT, with ref, and a data-processing logic function, addCnt. Setup () requires that the state and method be returned before it can be used in the template.Copy the code

Look at the reactive example, implementing a TODO List demo

<template> <form> name: <input type="text" V-model ="state.name"> age: <input type="text" v-model="state.age"> <input type="submit" @click="submit"></input> </form> <ol class="ol"> <li v-for="(item, index) in state.students" :key="index" @click="delStu(index)"> {{ item.name }} -- {{ item.age }} </li> </ol> </template>  <script> import { reactive } from 'vue'; Export default {name: 'Reactive', // entry function setup() {// declare several variables and use Reactive to listen for changes. Let state = reactive ({students: [{name: 'zhang' age: 11,}, {name: "bill", the age: 21,},], name: ", the age: "',}); // Add a student let submit = (e) => {e.preventdefault (); state.students.push({ name: state.name, age: state.age, }); state.name = ''; state.age = ''; }; Let delStu = (index) => {state.students.splice(index, 1); }; return { state, submit, delStu }; }}; </script>Copy the code

Mix the Options API and Composition API

The Composition API can of course be mixed with the previous Options API for vue2. X. In fact, the Composition API, also known as the injection API, injects variables and methods exposed in setup into data() and methods.

<template> <div> {{count}} < button@click ="logCount"> Click count </button> </div> <div> {{CNT}} <button @click="logCnt"> </button> </div> </template> <script> import {ref} from 'vue'; export default { name: 'Mix', data() { return { count: 1, }; }, methods: { logCount() { alert(this.count); }}, // vue2. x is called the Options API // this 🌰 can be seen in combination with the Options API. Setup () {let CNT = ref(5); // Let CNT = ref(5); // Let CNT = ref(5); let logCnt = () => { alert(cnt.value); // note that ref is listening to the object, in js use to add.value. }; return { cnt, logCnt }; }}; </script>Copy the code

isRef() && isReactive()

How do you distinguish between a data or state wrapped by ref or Reactive? This can be determined by isRef and isReactive.

<template> < button@click ="log"> </button> </template> <script> import {ref, reactive, isRef, isReactive } from 'vue'; export default { name: 'Which', setup() { let age = ref(18); let state = reactive({ age: 11 }); const log = () => { console.log('age is ref ? ', isRef(age)); // true console.log('age is reactive ? ', isReactive(age)); // false console.log('state is ref ? ', isRef(state)); // false console.log('state is reactive ? ', isReactive(state)); // true }; return { age, log }; }}; </script>Copy the code

In this example, age is wrapped by REF and state is wrapped by Reactive, which can be distinguished by isRef and isReactive.

shallowRef() && shallowReactive()

By default, both REF and Reactive wrapped data are listened on recursively and thus respond recursively. But recursive listening has an impact on performance. ShallowReactive () can be used if you want to listen only to the first layer of data, given that the data you want to listen to is very large and deeply nested.

<template> <div> <div>{{state.age}}</div> <div>{{state.a.v}}</div> <div>{{state.a.b.v}}</div> </div> <button @click="log"> </button> </template> <script> import {reactive, shallowReactive, shallowRef} from 'vue'; export default { name: 'Recurse', setup() {Recurse (shallowReactive) {Recurse (shallowReactive) {Recurse (shallowReactive); Let state = shallowReactive({a: {v: 1, b: {v: 2,}}, age: 15}); Const log = () => {// Note the difference between commenting out the following sentence and not commenting out the following sentence. // state.age = 16; // Only age changes can cause UI changes. If age is not changed, inner data changes and UI remains unchanged. State. A.v = 'a'; state. state.a.b.v = 'b'; console.log('111: ', state); console.log('111: ', state.a); console.log('111: ', state.a.b); }; return { state, log }; }}; </script>Copy the code

toRaw() && markRaw()

After ref and Reactive are packaged, data changes are reflected on the UI in real time. If a large amount of monitored data is monitored, performance may be affected.

What if you don’t want to respond to changes in some data or state in real time on the UI? ToRaw and markRaw may be able to help you.

The difference between toRaw and markRaw is that toRaw can take a responsive data/state back to the original value and modify the original value without changing the UI in real time. MarkRaw declares the data or state to be unresponsive, and the UI will not respond to changes to the data, even if refs and reactive are added.

Let’s start with toRaw

<template> <div> {{state.name}} -- {{state.age}} < button@click ="log"> button </button> </div> </template> <script> import { reactive, toRaw } from 'vue'; Export default {name: 'ToRaw', // ToRaw functions: Because ref/ Reactive updates the UI every time it is modified, it consumes a lot of performance. If the UI does not need to be updated in time, ToRaw can get the original data and modify the original data, so that the UI does not update and the performance is better. Setup () {let user = {name: 'zs', age: 12,}; let state = reactive(user); console.log('user === reactive(user): ', user === state); / / false. Let userOld = toRaw(state); console.log('user === toRaw(state): ', user === userOld); // true. Let log = () => {// Change the raw data, the UI will not respond naturally. (But because it's a reference, state.name is actually lisi.) user.name = 'lisi'; console.log('111: ', state); }; return { state, log }; }}; </script>Copy the code

Take a look at markRaw

<template> <div> {{state.name}} -- {{state.age}} < button@click ="log"> button </button> </div> </template> <script> import { reactive, markRaw } from 'vue'; Export default {name: 'MarkRaw', setup() {let user = {name: 'zs', age: 12,}; // Note the difference between adding and not adding markRaw. With it, the UI never responds to changes in data. (although the data itself has changed) markRaw(user); // The UI does not respond to data changes even if reactive is used later. let state = reactive(user); let log = () => { state.name = 'lisi'; console.log('111: ', state); }; return { state, log }; }}; </script>Copy the code

Afterword.

There are many features, to hand lift, the warehouse continues to update, welcome star~~~

GitHub