Changes in data are reflected to the view
We learned earlier that after data hijacking, we can do whatever we want after the data is modified, and the operation view is of course OK.
Imperative operation view
Goal: We can use the original operation of the dom to enable the latest value of each name to be displayed inside the p element.
<div > <p></p> </div> <script> let data = { name: 'Xiaolan', age: 18, height:180 } // traverse each property (data).forEach((key)=>{ // key attribute name // data[key] attribute value defineReactive(data,key,data[key]) }) function defineReactive(data,key,value){ (data,key,{ get(){ return value }, set(newVal){ value = newVal // The data changes, the operation dom is updated ('#app p').innerHTML = } }) } // First rendering ('#app p').innerHTML = </script>
Declarative operation view
Goal: We render the value of the name attribute in data as text to the p tag marked with v-text. In vue, we call this tokenized declarative rendering instruction
<div > <p v-text="name"></p> </div> <script> let data = { name: 'Xiaolan', age: 18, height: 180 } // traverse each property (data).forEach((key) => { // key attribute name // data[key] attribute value // data original object defineReactive(data, key, data[key]) }) function defineReactive(data, key, value) { (data, key, { get() { return value }, set(newVal) { value = newVal // The data changes, the operation dom is updated compile() } }) } // function compile() { let app = ('app') // 1. Get all the sub-elements in the app const nodes = // [text, input, text] //2. Iterate through all child elements (node => { // nodeType is 1 for element node if ( === 1) { const attrs = // traverse all attrubites to find v-model (attrs).forEach(attr => { const dirName = const dataProp = if (dirName === 'v-text') { = data[dataProp] } }) } }) } // First rendering compile() </script>
summary
Whether it is a instruction or an interpolation expression, these are just marks that reflect data to the view. Through marking, we can react the data's change response to the corresponding dom position.
The process of finding tags and binding data to the dom is called binding
Changes in the view reflect to the data
Objective: Render the corresponding value of the message attribute in data onto input. At the same time, after the input value is modified, the message value can be modified in reverse. In the vue system, the v-model instruction does this. Let's implement the function of v-model
<div > <input v-model="name" /> </div> <script> let data = { name: 'Xiaolan', age: 18, height: 170 } // traverse each property (data).forEach((key) => { // key attribute name // data[key] attribute value // data original object defineReactive(data, key, data[key]) }) function defineReactive(data, key, value) { (data, key, { get() { return value }, set(newVal) { // The data changes, the operation dom is updated if (newVal === value) { return } value = newVal compile() } }) } // Compile the function function compile() { let app = ('app') // 1. Get all the sub-elements in the app const nodes = // [text, input, text] //2. Iterate through all child elements (node => { // nodeType is 1 for element node if ( === 1) { const attrs = // traverse all attrubites to find v-model (attrs).forEach(attr => { const dirName = const dataProp = if (dirName === 'v-model') { = data[dataProp] // View changes are reflected to data, nothing more than event listening reverse modification ('input', (e) => { data[dataProp] = }) } }) } }) } // First rendering compile() </script>
Existing problems
Unable to achieve accurate updates
<div > <p v-text="name"></p> <p v-text="age"></p> <p v-text="name"></p> </div> <script> let data = { name: 'Xiaolan', age: 18, height: 180 } // traverse each property (data).forEach((key) => { // key attribute name // data[key] attribute value // data original object defineReactive(data, key, data[key]) }) function defineReactive(data, key, value) { (data, key, { get() { return value }, set(newVal) { // The data changes, the operation dom is updated if (newVal === value) { return } value = newVal compile() } }) } // Compile the function function compile() { let app = ('app') // 1. Get all the sub-elements in the app const nodes = // [text, input, text] //2. Iterate through all child elements (node => { // nodeType is 1 for element node if ( === 1) { const attrs = (attrs).forEach(attr => { const dirName = const dataProp = ( dirName,dataProp) if (dirName === 'v-text') { (`Updated${dirName}instruction,The attributes that need to be updated are${dataProp}`) = data[dataProp] } }) } }) } // First rendering compile() </script>
The above is a detailed content for a deep understanding of the principle of two-way data binding in Vue. For more information about Vue’s two-way data binding, please pay attention to my other related articles!