Writing is like open source. — Yard farmer fat sea
preface
It’s a habit to like it before you look at it. Hello, I am the ocean of programming.
The purpose of this article is to provide an easy-to-understand description of the concepts, functions, and syntax of the “responsive API”, as a continuation of my own learning and phased achievements.
What is a responsive API
-
Before describing the concept, let’s review what responsiveness is.
Responsiveness is a programming paradigm that allows us to adapt to change in a declarative way.
Adapt to change? Still confused… Let’s take a non-reactive example.
let val1 = 2 let val2 = 3 let sum = val1 + val2 console.log(sum) / / 5 val1 = 3 console.log(sum) // Still 5 Copy the code
We changed the first value, sum didn’t change.
Conversely, if a value is changed, sum is recalculated and assigned, then this is responsive.
export default{ data(){ return { val1:2.val2:3}},computed: {sum(){ return this.val1 + this.val2 } }, created(){ console.log(this.sum) / / 5 this.val1 = 3 console.log(this.sum) // the sum of 6 will change}}Copy the code
-
Responsiveness in Vue
The computed attributes used in the above example are an implementation of responsiveness by Vue.
In addition, responsiveness in Vue is often expressed as changing the data bound to the template, and the view is updated automatically. This is the “responsive system” that Vue prides itself on, and it’s the cornerstone of a huge shift in the Web front end from “manipulating the DOM” to “data-driven.”
How does it work? This is a familiar and well-worn interview question, “Introduce the responsive principle of Vue”.
-
After answering the question of what responsiveness is, it is clear that responsiveness apis are a generic name for a set of functions/methods added to Vue3.0 that create responsive state/effects for JavaScript objects. Core syntax includes reactive, ref, Coumpetd, Watch, etc
2. Introduction to core grammar
reactive()
-
The API returns a reactive object state. Allows us to explicitly define a reactive state.
import { reactive } from 'vue' // Reactive state const state = reactive({ count: 0 }) console.log(state) // Proxy {count: 0} Copy the code
Bind reactive objects to the template, and the view updates automatically as the data changes.
<template> <div>{{ state }}</div> </template> Copy the code
-
This reactive transformation is a “deep transformation” — it affects all the nested properties of the passed object.
const state = reactive({ obj: { count1: 0.// Note that there is one more layer of nesting}})// state.obj.count1 is also reactive Copy the code
-
The responsiveness of the data we define in the data option is also implemented by Reactive ().
When an object is returned from data() in a component, it is internally passed on to Reactive () to make it a reactive object.
-
Tracking data changes based on Proxy avoids the responsiveness failures that existed in earlier versions of Vue. Due to JavaScript limitations (Object.defineProperty), Vue cannot detect changes to arrays and objects. Responsiveness fails in the following scenarios:
- When adding or removing object properties
- When an array item is set directly using an index
- When modifying the length of an array
var vm = new Vue({ data: { a: 1}})// 'vm.a' is now responsive vm.b = 2 // 'vm.b' is not responsive Copy the code
Vue3.0 uses ES6 Proxy to track data changes, avoiding the above problems. If you print the return from reactive, you can clearly see that it is a Proxy object.
const state = reactive({ count: 0 }) console.log(state) // Proxy {count: 0} Copy the code
Why the Object.defineProperty scheme is flawed and why Proxy avoids this problem and has better performance is described in detail in The Article Reading Vue3 Improvements and Optimizations, which will not be covered here.
ref()
-
Takes an internal value and returns a reactive and mutable REF object.
import { ref } from 'vue' let count = ref(1) console.log(count); // RefImpl {_shallow: false, dep: undefined, __v_isRef: true, _rawValue: 1, _value: 1} Copy the code
Yes, it creates reactive objects just like Reactive (). The difference is that ref can accept values of the base type, whereas Reactive cannot.
-
If the value received is an object, it will be processed by Reactive as a deeply reactive object.
const refObj = ref({ count:'1',})console.log(refObj.value) // Proxy {count: '1'} Copy the code
Reactive (obj). Value reactive(obj)
const obj = { count:'1' } console.log(ref(obj).value === reactive(obj)) // true Copy the code
-
In the setup function, you need to access and change its value through the.value property
export default { setup() { let count = ref(1); console.log(count.value); / / 1 count.value = 2 console.log(count.value); / / 2}};Copy the code
-
Access from a template is not required, and Vue unpacks the Ref automatically
When ref is returned as a property on the render context (the object returned from Setup ()) and can be accessed in the template, it will automatically shallow unpack the internal values. Add.value to the template only when accessing nested refs
Value <span>{{count}}</span> <button @click="count ++">Increment count</button <button @click="nested.count.value ++">Nested Increment count</button> </div> </template> <script> import { ref } from 'vue' export default { setup() { const count = ref(0) return { count, nested: { count } } } } </script>Copy the code
toRefs()
In plain English, the reactive object version of deconstructed assignment. It allows us to retrieve the properties of a responsive object we want, just as we would with ES6 deconstruction, without losing responsiveness.
setup() {
const state = reactive({
foo: 1.bar: 2
})
// Can be destructed without losing responsiveness
const { foo, bar } = toRefs(state)
return {
foo,
bar
}
}
Copy the code
There are many more reactive apis for helper classes like this, such as using Readonly to prevent changes to reactive objects, using isRef to check if a value is a REF object, and so on.
There are two reasons: (1) Only using Reactive and REF can meet most application scenarios, and delaying learning does not prevent us from “getting started” and doing projects; ② This kind of API adds up to more than ten, need to consume a lot of energy and attention, put in the entry stage to gnawing, increase the difficulty of entry.
Everything has a priority, we can take a quick look at the API, get a general impression, and come back to make up the lesson when we use it in the future.
computed()
Computed in the same optional API
const count = ref(1)
const plusOne = computed(() = > count.value + 1)
console.log(plusOne.value) / / 2
Copy the code
watch()
The same as watch in the optional API
import { onMounted, ref, watch } from "vue"; // Watch export default {setup(props, context) {let defaultName = ref(" props "); onMounted(() => { console.log("mounted!" ); // Update data to trigger watch defaultName.value = "Mounted "; }); watch(defaultName, (newValue, oldValue) => { console.log("The defaultName is: " + defaultName.value); // The defaultName is: Mounted Console. log("The defaultName newValue is: "+ newValue); // The defaultName is: Mounted console.log("The defaultName newValue is:" + newValue); // The defaultName newValue is: Mounted Console. log("The defaultName oldValue is: "+ oldValue); // The defaultName oldValue is:}); return { defaultName, }; }};Copy the code
Third, summary
Reactive apis can be thought of as a continuation of compound apis; they are all one. However, Vue divides them into two categories in terms of function.
This is the third chapter of “The Beginning is the Peak, Vue3.0 Learning Summary”.
-
The entry is the peak, read the improvement and optimization of Vue3.0
-
The beginning is the peak, Vue3.0 learning summary of the compound API