欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue之响应式属性和数据双向绑定

程序员文章站 2022-05-15 17:38:55
...

响应式数据的原理

  • 响应式属性:能监听到修改操作,并更新视图

  • 如何设置一个属性为响应式属性(属性特性)

    • 值属性:拥有值的属性
    • configurable => 配置属性(一个控制开关)
    • enumerable => 可枚举型
    • writable => 可写性
    • value => 属性的值

    特别说明:
    1. 传统方式添加的属性,所有属性特性默认为true
    2. 通过Object.defineProperty()添加的属性,所有属性特性默认为false
    * 参数:参数1:目标对象 参数2:目标对象的属性 参数3:对属性的修饰(可写啊,还是设置为不可枚举等!)

    • 存储器属性:本身没有值,一般用于代理其他数据
      • configurable
      • enumerable
      • get
      • set

属性特性之值属性

    //1:值属性
    let xzl = {
      uname: "xzl",
      pwd: 123
    }
    //传统方式修改值属性
    xzl.pwd = 456 // =>  {uname: "xzl", pwd: 456}  这里面的属性都是可写的!

    //通过Object.defineProperty()方法修改值属性
    //需求:设置pwd为不可写!
    Object.defineProperty(xzl, "pwd", {
      writable: false //在浏览器控制台之中 使用xzl.pwd=123回车 表示不能修改! {uname: "xzl", pwd: 456}
    })

    //需求:设置pwd不可枚举性
    Object.defineProperty(xzl, "pwd", {
      enumerable: false
    })
    for (let key in xzl) {
      console.log(key + "=" + xzl[key]); //遍历发现 只有这个 uname=xzl
    }

    //使用普通的方式和 Object.defineProperty() 给当前对象添加属性的区别
    //普通方式
    xzl.age = 111 //{uname: "xzl", age: 111, pwd: 456} => 通过普通方式添加的属性 都是可遍历的,可写的 也就是说值属性是为trye

    //使用 Object.defineProperty() 
    Object.defineProperty(xzl, "gender", {
      value: "男" //{uname: "xzl", age: 111, pwd: 456, gender: "男"}
    })
    for (let key in xzl) {
      console.log(key + "=" + xzl[key]); //遍历发现 只有这个 uname=xzl age=111 因为Object....设置的值属性为false的不可遍历等!
    }

输出特性之存储器属性

  <div id="box">
  </div>

   //2:存储器属性 
    // + 原理:就是在一个对象内部有着get 和 set 方法
    // * get 属性()方法 =>这是获取到当前的属性, set 属性()方法 => 设置新的属性
    //注意点:存储器属性作用代理,也是就说使用当前的xll作为代理,然后修改ll的性别
    const xll = {
      uname: "xll",
      get age() {
        return 11
      },
      set age(newVal) {
        console.log("set=", newVal); //在浏览器之中 xll.age=22 => 给当前对象设置了一个age属性,输出 set= 22
      }
    }

    const ll = {
      gender: "男"
    }

    Object.defineProperty(xll, "gender", {
      get() {
        console.log("get00");
        return ll.gender
      },
      set(newVal) {
        console.log("get00");
        return ll.gender = newVal;
      }
    })
    //输入:xll.gender="女"  get00  "女" 
    //然后在输入: ll => {gender: "女"}

    //3:响应式原理
    // 响应式属性的原理:把值属性变成存储器属性(getter&setter)
    const user = { //作为存储器:目的用于代理,但是不修改自身的数据,不然在循环遍历这个对象的时候,造成内存的溢出现象!
      uname: "xll",
      age: 20
    }

    //通过代理user这个对象 来实现数据的修改!
    const xjj = {}
    box.innerText = user.uname;

    for (let key in user) {
      Object.defineProperty(xjj, key, {
        // Object.defineProperty(user, key, {
        get() {
          return user[key];
        },
        set(newVal) {
          box.innerText = newVal;
          user[key] = newVal;
        }
      })
    }

Vue实例中的响应式数据的原理

  • Vue.set(vm.score, “chinese”, 100);
    const initDate = {
      uname: "xll",
      age: 13,
      score: {
        eng: 61,
        math: 113
      }
    }
    const vm = new Vue({
      el: "#app",
      data: initDate
    })
    //vm.score.che=100 这边的100不是存储器属性 直接在页面显示的 ,并非像存储器属性一样,最先是隐藏的!
    //因此需要使用Vue.set()方式 去设置,才能为后添加的属性设置为存储器属性!
    //参数:参数1:目标对象 参数2:目标对象的属性值 参数3:目标对象的属性值

    Vue.set(vm.score, "chinese", 100);
    // Vue.set(vm, "chinese", 100);
    //注意点:就是这个目标对象 不能设置为vm实例对象 ,也不能设置为initDate对象 
    //也不能设置给当前的initDate对象的chinese设置为100 也不能 `Vue.set(vm, "chinese", 100);` 否则都会报错:
    //只能设置为: Vue.set(vm.score, "chinese", 100);

v-model的原理:

  • 双向数据绑定—需要添加v-model指令
    v-model这个指令是由两个指令组成的,分别为v-bind(绑定表单的值),@input(绑定oninput事件)

  • 原理:
    v-bind:attr — 就是给属性绑定数据(单项),用于显示数据
    v-on:input=“事件处理函数” —就是给表单添加一个事件,并且处理数据
    分析:数据双向绑定就是:表单value通过属性的绑定来拿到data的数据,然后通过对表单绑定oninput事件
    来实现表单值的修改的时候,从而修改了data中的数据,也就是修改了显示页面的data!
    /*数据的双向绑定: v-model的原理

    • 01:事件绑定:对表单绑定一个事件,检测表单的值发生变化的时候,就把数据传递到控制层,进而来影响数据层!
    • 02:属性绑定:就是把data的值绑定到当前的标签之中,用于显示数据
  <div id="app">
    <p>姓名:{{username}}</p>
    <p>年龄:{{age}}</p>
    <input type="text" v-bind:value="age" v-on:input="changeAge">
  </div>

  <script src="../vue.js"></script>
  <script>
    let data = {
      username: "pink",
      age: 20
    }

    const vm = new Vue({
      el: "#app",
      data,
      methods: {
        changeAge: function (e) {
          //e为事件对象,target-当前目标 ---也就是当前目标的值
          data.age = e.target.value;
        }
      }
    })

相关标签: vue系列