响应式原理-vue双向绑定

看了B站上一个老师的课,简单记录下。
一,响应式原理:
前端有命令式与声明式两种开发模式。
命令式框架关注过程,声明式框架关注结果。
命令式框架
命令式框架一般说的jquery, 操作dom获取dom。
思考一个问题:有个按钮,点击文案改成英文文字。
如果是原生js和jQuery,方法是button 绑定 click 修改文案

        const div = document.getElementsByTagName('div')[0]
        const btn = document.getElementsByTagName('button')[0]
        btn.onclick = function(){
            div.innerText = '好'
        }

声明式框架
现在,vue、react出来了以后,由命令式转换为声明式,如果使用vue方法是,绑定一个click事件,定义一个初始数据,修改这个数据就行。

    <div>
        {{text}}
    </div>
    <button @click="()=>{text='好'}">button</button>
    <script>
        export default {
            data() {
                return {
                    text: 'hello'
                }
            }
        }
    </script>

相比来说,声明式没有对dom的操作,只是对数据的修改,不用关注底层怎么实现的。不过声明式的底层还是命令式。
二,双向绑定
输入input数据,引起一个data变化。改变data,input中数据也变化,叫做双向绑定。
在这里插入图片描述
点击按钮,都改变为’hao‘
在这里插入图片描述

底层实现

    <div id="app">
        <input type="text">
        <h1></h1>
        <button>button</button>
    </div>
    <script>
        const input = document.getElementsByTagName('input')[0]
        const h1 = document.getElementsByTagName('h1')[0]
        const btn = document.getElementsByTagName('button')[0]
        let data = {
            text: ''
        }
        input.addEventListener('input', function(e) {
            data.text = e.target.value
        })
        btn.onclick = function() {
            data.text = 'hao'
        }
        Object.defineProperty(data, 'text', {
            get: function() {
                return data['text']
            },
            set: function(newValue) {
                h1.innerText = newValue
                input.value = newValue
            }
        })
    </script>

双向绑定抽象出来就是响应式页面的实现。
三,vue2和vue3响应式数据的区别
vue3使用proxy代理,使用ref或reactive将数据转化为响应式数据。
vue3传递的是对象,没有指定具体监听的属性,所以无论修改或者添加属性,都不会触发getter和setter。
vue2缺点:不能给数组或者对象直接修改数值,不能给对象赋一个新的属性。
是因为defineProperty这个方法有局限性,当定义Object.defineProperty(data, ‘text’,
{get: },{ set: }),已经确定要给属性‘text‘进行双向绑定,后来再添加其他属性时,就没有响应式了。

vue3底层大致是这

    <script>
     const btn = document.getElementsByTagName('button')[0]
        const data = {
            text: ''
        }

        function effect() {
            document.body.innerText = data.text
        }
        const obj = new proxy(data, {
            get(target, key) {
                return target[key]
            },
            set(target, key, newvalue) {
                target[key] = newvalue
                effect()
                return true
            }
        })
        btn.onclick = function() {
            obj.text = 'hao'
        }
    </script>

四,用vue3官网中的例子简单看下:
一个经常被拿来当作典型例子的用例即是 Excel 表格:
在这里插入图片描述

这里单元格 A2 中的值是通过公式 = A0 + A1 来定义的 (你可以在 A2 上点击来查看或编辑该公式),因此最终得到的值为 3,正如所料。但如果你试着更改 A0 或 A1,你会注意到 A2 也随即自动更新了。
我们可以用真正的 Vue API 改写上面的例子:

import { ref, watchEffect } from 'vue'

const A0 = ref(0)
const A1 = ref(1)
const A2 = ref()

watchEffect(() => {
  // 追踪 A0 和 A1
  A2.value = A0.value + A1.value
})

// 将触发副作用
A0.value = 2

使用一个响应式副作用来更改一个 ref 并不是最优解,事实上使用计算属性会更直观简洁:

import { ref, computed } from 'vue'

const A0 = ref(0)
const A1 = ref(1)
const A2 = computed(() => A0.value + A1.value)

A0.value = 2

在内部,computed 会使用响应式副作用来管理失效与重新计算的过程。

那么,常见的响应式副作用的用例是什么呢?自然是更新 DOM!我们可以像下面这样实现一个简单的“响应式渲染”:

import { ref, watchEffect } from 'vue'

const count = ref(0)

watchEffect(() => {
  document.body.innerHTML = `计数:${count.value}`
})

// 更新 DOM
count.value++
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值