Preface
Vue3.x The official version has been released for nearly half a year , I believe we can use it more or less Vue3.x Developed projects . that , Let's sort it out today Vue3.x Responsiveness in API.
Responsiveness API
reactive
effect : Create a responsive data .
The essence : Incoming data ( Complex type : Array and json object ) Pack it as a Proxy
object . If you pass in another object , Modify objects by default , The interface doesn't update automatically , If you want to update , By reassigning ( Create a new object ) The way .
<template> <div class="reactive"> <button @click="fn"> Click on </button> <p>{{ state }}</p> <button @click="fn1"> Click on 1</button> <p>{{ timeState }}</p> </div> </template> <script> import { reactive } from "vue"; export default { name: "Reactive", setup() { let state = reactive({ name: "123", }); function fn() { console.log(state); state.name = "456"; } let timeState = reactive({ time: new Date(), }); function fn1() { const newTime = new Date(timeState.time.getTime()); newTime.setDate(timeState.time.getDate() + 1); timeState.time = newTime; console.log(timeState.time); } return { state, fn, timeState, fn1, }; }, }; </script>
ref
effect : Create a responsive data .
The essence : ( The essence is not rigorous enough ) For complex types or reactive
. When we give ref
Function passes a value ( It's usually a simple type ) after ,ref
The underlying function will automatically ref
convert to reactive
, namely ref(123) => reactive({value:123})
, So to modify the corresponding value, you must add .value
.
Be careful : stay template
There's no need to add .value
.
<template> <div> <button @click="fn"> Click on </button> <p>{{state}}</p> <button @click="fn1"> Click on 1</button> <p>{{arrState}}</p> </div> </template> <script> import {ref} from "vue"; export default { name:"Ref", setup(){ let state = ref(123); function fn () { state.value = 345; } let arrState = ref([]); function fn1 (){ arrState.value.push("1"); } return { state, fn, arrState, fn1 } } } </script>
shallowReactive
effect : Create a responsive proxy
, Tracking itself property
Responsiveness , But do not perform deep responsive transformation of nested objects ( Exposure raw value ).
The essence : Do not respond to nested objects , The value tracks the first layer of itself property
.
<template> <div> <button @click="fn"> Click on </button> <button @click="fn1"> Click on 1</button> <p>{{state}}</p> </div> </template> <script> import { shallowReactive } from "vue" export default { name:"ShallowReactive", setup(){ let state = shallowReactive({ name:"maomin", age:{ number:20 } }) function fn(){ state.name = "123"; // Responsiveness } function fn1(){ state.age.number = 23; // No response } return { state, fn, fn1 } } } </script>
shallowRef
effect : Create a ref
, It tracks its own .value
change , But it doesn't make its value responsive . Does not convert its value to Proxy
object .
<template> <div> <button @click="fn"> Click on </button> <p>{{ state }}</p> <button @click="fn1"> Click on 1</button> <p>{{ state1 }}</p> </div> </template> <script> import { shallowRef, ref, // triggerRef } from "vue"; export default { name: "ShallowRef", setup() { let state = shallowRef({ name: "maomin", }); let state1 = ref({}); function fn() { state.value.name = "345"; console.log(state.value); // {name: "345"}, however UI The interface doesn't change . // triggerRef(state); // If you want to trigger UI Interface , You can use it . } function fn1() { state1.value = { name: "123", }; // eslint-disable-next-line no-irregular-whitespace console.log(state1.value); // Proxy {name: "123"} } return { state, fn, state1, fn1, }; }, }; </script>
readonly
effect : Get an object ( Responsive or pure object ) or ref
And return to the original proxy
Read only proxy
. read-only proxy
It's deep : Any nesting accessed property
It's also read-only .
<template> <div> <button @click="fn"> Click on </button> <p>{{os}}</p> <p>{{state}}</p> </div> </template> <script> import {reactive, readonly} from "vue"; export default { name:"Readonly", setup(){ let state = reactive({ name:"maomin", age:{ number:18 } }) let os = readonly(state); function fn(){ os.name = "123"; } return{ os, state, fn } } } </script>
shallowReadonly
effect : Create a proxy
, Make its own property
As read-only , But do not perform deep read-only conversion of nested objects ( Exposure raw value ).
<template> <div> <button @click="fn"> Click on </button> <p>{{os}}</p> <p>{{state}}</p> </div> </template> <script> import { reactive, shallowReadonly, isReadonly } from "vue"; export default { name:"ShallowReadonly", setup(){ let state = reactive({ name:"maomin", age:{ number:18 } }) let os = shallowReadonly(state); function fn(){ console.log(isReadonly(os.name)) //false os.age.number = 20; } return{ state, os, fn, } } } </script>
toRaw
effect : Responsive object to normal object .
The essence : Return from reactive
or readonly
Method into a normal object of a responsive proxy . This is a reduction method , Can be used for temporary reading , Access will not be proxied / track , Changes are not triggered when writing . It is not recommended to hold references to the original object all the time .
<template> <div> <button @click="fn"> Click on </button> <p>{{state}}</p> </div> </template> <script> import { reactive, toRaw } from "vue"; export default { name:"ToRaw", setup(){ const obj = { name:"maomin" }; let state = reactive(obj); function fn(){ console.log(toRaw(state) === obj); //true let obj1 = toRaw(state); obj1.name = "123"; // eslint-disable-next-line no-irregular-whitespace console.log(state); // Proxy {name: "123"}. Although the value changes , But the page didn't change . } return { state, fn } } } </script>
markRaw
effect : Mark an object , Make it never convert to proxy. Returns the object itself .
<template> <div> <button @click="fn"> Click on </button> <p>{{state}}</p> </div> </template> <script> import {markRaw,reactive} from "vue" export default { name:"MarkRaw", setup(){ let obj = {name:'maomin', age: 20}; obj = markRaw(obj); let state = reactive(obj); function fn(){ state.name = '123'; console.log(state); // It's printed out here name:123, however UI The interface doesn't change . } return{ state, fn } } } </script>
toRef
If you use ref
, Our modification of responsive data will not affect the original data ( Copy ). If you use toRef
, If we modify the responsive data, it will affect the original data ( quote ).
effect : It can be used to create a property
Create a new ref
. Then you can put ref
Pass out , So as to maintain a good understanding of its source property
Responsive connection for .
<template> <div> <button @click="fn"> Click on </button> <p>{{state}}</p> <button @click="fn1"> Click on 1</button> <p>{{state1}}</p> </div> </template> <script> import {reactive, ref, toRef} from "vue" export default { name:"ToRef", setup(){ let obj = {name:"maomin"}; let os = reactive(obj); let state = ref(os.name); let state1 = toRef(os,'name'); // ref function fn(){ state.value = "123"; console.log(os); // The raw data doesn't change console.log(state); } // toRef function fn1(){ state1.value = "345"; console.log(os); // The raw data will change console.log(state1); } return { state, fn, state1, fn1 } } } </script>
toRefs
effect : Convert a responsive object to a normal object , Where each property
They all point to the original object property
Of ref
.
purpose : When a responsive object is returned from a composite function ,toRefs
Very useful , In this way, the consumer component can decompose the returned object without losing its responsiveness / Spread .
<template> <div> <button @click="fn"> Click on </button> <p>{{state}}</p> <button @click="fn1"> Click on 1</button> <p>{{foo}}</p> </div> </template> <script> import {reactive, toRefs} from "vue" export default { name:"ToRefs", setup(){ let obj = { name:"maomin", age:20 } let os = reactive(obj); let state = toRefs(os); function fn(){ state.name.value = "123"; os.name = "234"; console.log(os); console.log(state); console.log(state.name.value === os.name); //true } const { foo, bar } = useFeatureX(); function fn1(){ foo.value = "2"; } return { fn, state, foo, bar, fn1 } } } function useFeatureX() { const state = reactive({ foo: 1 }) // Convert to on return ref return toRefs(state) } </script>
customRef
effect : Create a custom ref
, And explicitly control its dependency tracking and update trigger . It needs a factory function , This function receives track
and trigger
Function as parameter , And should return a get
and set
The object of .
<template> <div> <button @click="fn"> Click on </button> <p>{{state}}</p> </div> </template> <script> import {customRef} from "vue"; function myRef(value){ return customRef((track, trigger)=>{ return { get(){ track(); console.log('get',value); return value; }, set(newValue){ console.log('set',newValue); value = newValue; trigger(); } } }) } export default { name:"CustomRef", setup(){ let state = myRef(18); function fn(){ state.value = 19; } return { state, fn } } } </script>
computed
effect : When dependencies change , The value assigned to it changes accordingly .
Be careful : Directly modifying computed
no .
<template> <div> <p>{{state}}</p> <p>{{os}}</p> <button @click="fn"> Click on </button> </div> </template> <script> import {computed,ref} from "vue" export default { name: "Computed", setup(){ let state = ref(12); let os = computed(() => state.value + 1); function fn(){ state.value = 23; // os The value of will change accordingly // os.value = 26; // Write operation failed: computed value is readonly } return{ state, os, fn } } } </script>
watchEffect
effect : Run a function immediately when you responsively track its dependencies , And rerun it when you change the dependency .
<template> <div> <button @click="fn"> Click on </button> <p>{{state}}</p> <p>{{state1}}</p> <p>{{num}}</p> </div> </template> <script> import { reactive, ref, watchEffect } from "vue" export default { name:"WatchEffect", setup(){ let state = ref(0); let state1 = reactive({ name:"maomin" }) let num = 1; // It is executed the first time it runs , If the response dependency changes , It will be re executed . watchEffect(()=>{ // console.log(num); console.log(state.value); console.log(state1); }) function fn() { state.value = 3; state1.name = "123"; num = 2; } return{ fn, state, state1, num } } } </script>
watch
effect : By default , It's also inert —— That is, callbacks are only called when the listening source changes .
<template> <div> <button @click="fn"> Click on </button> <p>{{state}}</p> <button @click="fn1"> Click on 1</button> <p>{{state1}}</p> </div> </template> <script> import {reactive, ref, watch} from "vue" export default { name:"Watch", setup(){ // reactive let state = reactive({ name:"maomin" }) watch( () => state.name, (count) =>{ console.log(count); //123 } ) function fn() { state.name = "123"; } //ref let state1 = ref(1); watch( state1, (count) =>{ console.log(count); //2 } ) function fn1() { state1.value = 2; } return { state, fn, fn1, state1 } } } </script>
Conclusion
Thank you for reading , I hope you didn't waste your time . You can use code examples to type your own code , Responsiveness API There are many uses , This is just a drop in the bucket , Hurry up !