ref
Create a responsive data, which is generally used to create simple types of responsive objects, such as String and Number types
const name = ref('tom') Copy code

As you can see, the ref method wraps the string in a layer and returns an object of type RefImpl, which is translated into a reference implementation. An enumerable attribute value is set on the object, so name.value is used to read the value.
As mentioned above, ref is usually used to define a simple type. Can you define an object or array?
const obj = ref({ age: 12, sex: 'man', }) Copy code

The console can see that for complex objects, the value is an object intercepted and processed by the proxy, but the attributes age and sex inside are not RefImpl objects. The proxy objects are also mounted on the value, so you can read the attributes through obj.value.age. These attributes are also responsive. When changing, you can trigger the update of the view
reactive
Through the use case of ref above, ref can be used to define complex reference types, such as array and object, or simple value types, such as string and number. However, when defining objects, it is usually implemented with reactive
const person = reactive({ height: 180, }) Copy code

You can see that the returned person is a proxy object. You can use person.height
Can reactive be used to define common types?
const id = reactive('id Yes 1') Copy code

You can see that * * reactive can only be used to define objects**
Differences and relations between ref and reactive
Generally speaking, ref is used to define simple strings or values, while reactive is used to define object arrays, etc
When ref defines an object, value returns a proxy, and when reactive defines an object, it also returns a proxy. There are some connections
When ref is used to define data, a layer of judgment will be made on the data types inside. When complex reference types are encountered, reactive will still be used for processing
class RefImpl { constructor(value, _shallow) { this._shallow = _shallow; this.dep = undefined; this.__v_isRef = true; this._rawValue = _shallow ? value : toRaw(value); this._value = _shallow ? value : toReactive(value); } ////...... } Copy code
const toReactive = (value) => isObject(value) ? reactive(value) : value;// Judge whether the parameter is an object. The object calls reactive to create it. Otherwise, the original value is returned Copy code
shallowRef and shallowReactive
Both ref and reactive are in-depth monitoring of data. No matter simple types or complex objects, view updates are triggered whenever changes occur. For deep-seated objects, if only a few attributes are easy to change, it is undoubtedly a waste of performance to still monitor the overall attributes of this huge object, In this case, shallowRef or shallowReactive can be used to realize shallow listening
shallowRef
Only monitor the change of the value of the. Value attribute. The update will not be triggered when a property inside the object is changed. The update will be triggered only when the value is changed to re assign the value to the object
const foo = shallowRef({ c: 1, }) const change = () => { foo.value.c = 2 // The view is not updated foo.value={a:1} // View update } Copy code
shallowReactive
Only listen to the first layer properties of objects, and do not respond to nested objects
const state = shallowReactive({ foo: 1, nested: { bar: 2 } }) const change = () => { state.foo = 2 // View update state.nested={count:2}// View update state.nested.bar =3 // The view is not updated } Copy code
triggerRef
It is used to manually force the update of the side effects related to the shallowRef and update the view. It can be seen from the above summary that the shallowRef only listens to the value attribute and does not trigger the update when the internally nested objects change. The function of triggerRef is to forcibly trigger the refresh of shallowRef in some cases. For example, in some cases, an object is nested with hundreds of layers of data, but the data of one layer needs to be changed, and the others do not move. All become responsive, wasting performance, and non responsive can not update the view. In this case, you need to change this layer of data and then use triggerRef to update it
const shallow = shallowRef({ greet: 'Hello, world' }) shallow.value.greet = 'Hello, universe' // The view does not update triggerRef(shallow) // Manually update the relevant side effects and update the view Copy code
readonly and shallowReadonly
Make object read-only
readonly
Receive a normal object or a responsive object processed by reactive and ref to make it a read-only object, and no data in it can be changed
const original = reactive({ count: 0 }) const copy = readonly(original) original.count++ // You can still change the responsive object copy.count++ // If you change it after being wrapped by readonly, you will be warned Copy code
shallowReadonly
The first level property of the object is set to read-only, and the nested genera can still be changed
const state = shallowReadonly({ foo: 1, nested: { bar: 2 } }) state.foo++ //Warning, cannot be changed state.nested.bar++ // Nested properties can still be changed Copy code
toRaw and markRaw
Turn responsive objects back into normal objects
toRaw
Return the proxy object that has been proxied by reactive or readonly, or ref the value when defining the object
const count = ref({ a: 1, }) const c = toRaw(count.value) // The value of ref is the proxy object Copy code
const count = reactive({ a: 1, }) const c = toRaw(count) // reactive objects do not require value Copy code
const roCount = readonly(count) const c = toRaw(roCount) //readonly object Copy code
markRaw
Mark an object so that it will never become a responsive proxy. For example, if you mount a third-party class library, the class library does not need to create a responsive. For example, if you add an additional attribute to a responsive object to display a list, the list is only for display, and there is no need to create a responsive to avoid performance waste
In vue2. If you append an attribute bar to a response number object foo, the update of foo.bar in the view will not be triggered. In this case, you need to use $set to append an attribute to foo
this.foo.bar =1 // Not updated this.$set(this.foo,'bar',1) // Trigger update Copy code
However, in vue3, the proxy is used to intercept data. Its strength lies in that if a responsive object is defined and the attributes of the object are added or deleted, the appended attributes are still responsive and can still trigger the update of the view
const foo =reactive({}) foo.bar =1 // Trigger view update Copy code
However, vue3 such an approach will have another problem -- > in some cases, you do not want the additional data to become responsive. In this case, you need to use markRaw to wrap the object
const foo =reactive({a:1}) foo.bar ={b:1} // The bar attribute is still responsive foo.bar =markRaw({c:1}) // Not responsive Copy code
customRef
Used to customize ref
- Create a function package customRef, which is used to pass initial values and other formal parameter configurations
- customRef is a function that receives two parameters: track tracker and trigger trigger
- customRef returns an object with a get function and a set function in which the read and write operation logic is written
<input v-model="text" /> Copy code
// Create parameter package customRef to pass initial value function useDebouncedRef(value, delay = 200) { let timeout // Return to customRef return customRef((track, trigger) => { // Returns an object with get and set functions return { // Read value operation get() { // Set up a tracker to track this value change track() return value // Value }, // Write value operation set(newValue) { clearTimeout(timeout) timeout = setTimeout(() => { value = newValue // Blasphemy assignment trigger() // Trigger that tells the view to get data }, delay) } } }) } export default { setup() { return { text: useDebouncedRef('hello') // use } } }