05-vue-响应式数据、双向绑定

(1).响应式数据

1.响应式数据和普通数据

<body>

<!-- dom -->

    <button onclick="fn()">dom </button>

    <div id="box">

    </div>

<!--vue  -->

    <button onclick="fnapp()">vue</button>

    <div id="app">

        {{msg}}

    </div>

    <script>

        var data ={msg:["heeee",99]}

        var box = document.querySelector("#box")

        box.innerHTML=data.msg //改变的是box节点的值

        function fn(){

            data.msg=555; // data.msg的值改变并不会让box节点值改变,除非再次执行box.innerHTML

        }

        var app = document.querySelector("#app")

        var vm = new Vue({

            el: '#app',

            data: {

                msg:"hello"

            }

        })

        function fnapp(){

            vm.msg="66" //会改变页面的值,响应式布局。相当于再次执行了app.innerHTML

        }

    </script>

</body>

2.响应式数据原理代码

<body>

    <div id="myapp">

        <!-- <div v-html="html">{{msg}}</div> -->

        <h1 id="title"></h1>

        <p id="msg"></p>

    </div>

    <script>

        function MyVue(option) {

            let _myvm = {}

            let arr = Object.keys(option.data)

            let arr1 = {}  //设置的值保存的地方

            for (let i = 0; i < arr.length; i++) {

                Object.defineProperty(_myvm, arr[i], {

                    set(v) {

                        // 劫持

                        option.data[arr[i]] = v

                        // arr1[arr[i]] = v

                        // 响应数据实现

                        let title = document.querySelector("#title")

                        title.innerHTML = _myvm["title"]

                        let msg = document.querySelector("#msg")

                        msg.innerHTML = _myvm["msg"]

                   

                    },

                    get() {  //_myvm,对arr[i]的属性值 取操作时候执行

                        return option.data[arr[i]]

                        // return arr1[arr[i]]

                    },

                })

                _myvm[arr[i]] = option.data[arr[i]]

            }

            // Object.defineProperty(obj, "a", {

            //     set() { }, //obja属性设置值时调用

            //     get() { }, //obja属性取值时调用

            // })

            // 劫持了option里面的data的对象值,未来使用_myvmthis),因为设置了set方法,就响应数据,把网页数据更新

            return _myvm

        }

        var myvm = new MyVue({

            el: "#myapp",

            data: {

                title: "mytitle1",

                msg: "mymsg"

            }

        })

        myvm.title=1

        myvm.msg=1

        console.log(myvm.data);

    </script>

</body>

3.面试题

1.什么是响应式数据

如果内存中的数据变化了 页面UI也会动态跟着刷新  这种数据就是响应式数据

2.响应式数据设计原理:

1)vue2.0 采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

       2)ue3.0 --使用es6 proxy 代理了data对象

vue2.0对于一些特殊的引用数据,比如数组取下标的方法就劫持不了,若通过改变data中的arr[0]=1,就劫持不了,就没有响应数据,所以vue3.0就代理整个data对象。

this.arr[2]="hello"//没有劫持数组的下标(不能刷新页面)

解决:

1)

Vue.set(this.arr,2,"hello")//vue帮我们刷新页面,将数组arr的下标2,改为"hello"

this.$set(this.arr,2,"hello")//vue帮我们刷新页面

2)

使用数组自带的方法,如splice()\push()

this.arr.splice(2,1,"hello")//劫持了数组的方法(可以刷新页面)

(2).双向数据绑定

<body>

    <div id="app">

        <p>1.如果数据容器中的数据变了也会让页面刷新(dom操作让页面改变)</p>

        <p>2.如果用户操作dom,改变了页面,反之也会让数据容器中的数据的值改变</p>

        <button @click="change1">改变数据容器中的数据</button>

        <button @click="look">查看text和数据容器</button>

        <p>{{msg}}</p>

        <input type="text" :value="msg">

       

        <!-- react实现双向绑定,输入框值改变就触发myinput事件 -->

        react:<input type="text" :value="msg" @input="myinput">

        <!-- vue实现双向绑定 ,v-model负责监听用户的输入事件来更新数据-->

        <input type="text"  v-model="msg">

    </div>

   

</body>

<script>

    var vm = new Vue({

        el:"#app",

        data:{

            msg:"hello"

        },

        methods: {

            change1(){

                this.msg = "999"

            },

            look(){

                console.log(this.msg); //用户输入框11this.msg不会改变成11

            },

            myinput(e){

                // console.log();

                this.msg = e.target.value

            }

        },

    })

</script>

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值