vue深入响应式原理

153 阅读5分钟

1.面试

1. vue数据驱动原理是什么?
2. vue双向数据绑定原理是什么?
3. vue深入响应式原理是什么? 
深入响应式指的就是数据驱动

2.vue深入响应式原理

  • Vue是通过数据劫持和事件的订阅发布来实现的,数据劫持指的是Vue通过observer观察者对象对data选项中的数据进行getter和setter设置【Object.defineProperty】,事件的订阅发布指的是 Vue通过事件来监听,通知Vue进行视图更新

底层实现 - es5特性 -> Object.definePropty

代码实现:
html:
    <div id="box"></div>
    <button> 修改数据 </button>
    <input type="text" name="" id="">
  js:  
    var box = document.querySelector('#box')
    var btn = document.querySelector('button')
    var input = document.querySelector('input')
    
    var model = { //我这里定义了一个数据,这个数据是一个对象
        info: 'West Court' //西阁
    }
    
    input.onkeyup = function () {
    // Object.defineProperty( 对象,对象的属性,对对象属性的配置 )
    Object.defineProperty( model, 'info', {
      /* 存储器 getter & setter */
      get: function () {//get可以给对象做一次初始化赋值
        return input.value
      },
      set: function ( val ) {
        console.log( val )
        box.innerHTML = val 
      }
    })
    box.innerHTML = model.info
    }
    
    btn.onclick = function () {
    model.inf="vue" // 数据修改了
    }

3.模板语法 mustache

  1. null 和 undefined 是不会显示的,其他数据类型都是支持的,可以显示的
  2. 挂载在window身上的全局属性,我们都不能用的: 比如; console alert
  3. mustache语法中 不写流程控制
    • for
    • if
    • while
    • do...while
  4. mustache语法中支持三元表达式,同样也支持运算符
  5. 短路原则也是支持的

4.指令

1)指令的目的是做什么: 操作DOM

指令这个词来源于angular, angualr是对于html的扩展, 通过html是允许我们自定义属性的特征,我们给我们的自定义属性加一个特殊的标识,比如ng-,比如 v-.

  1. {{ }}: 非转义输出,也就是无法解析 xml 类型数据,加载要时间
  2. v-html: 转义输出,也就是可以解析 xml 数据
  3. v-text: 非转义输出,也就是无法解析 xml 类型数据
  4. v-bind: 将数据和属性进行单向数据绑定: 将vue中数据赋值给属性值
将数据和属性进行单向数据绑定: 将vue中数据赋值给属性值
    <img v-bind:src = "src" />
    <div v-bind:class = "">
    
    </div>
    <div v-bind:style = "">
    
    </div>
    
简写形式:
    <img v-bind:src="src" alt="">
    <img :src="src" alt="">
  • 类名绑定
    • 对象形式用法
    <p :class = "{ bg: true,size: true }"></p>
    <p :class = "{ bg: true,size: false }"></p>
    <p :class = "{ [classA]: true,[classB]: true }"></p>
    
    • 数组形式用法
    <p :class = "['size','bg']"></p>
    <p :class = "[classA,classB]"></p>
    <p :class = "[classA,classB,5>3?'a':'b']">  </p>
    
  • 样式绑定
    • 对象形式用法
    <p :style = "{width: '100px',height: '100px',background: 'yellow'}"></p>
    <p :style = "styleObj"></p>
    
    • 数组形式用法
    <p :style = "[{width:'100px',height: '100px'},{ background: 'green'}]"></p>
    <p :style = "[size,bg]"></p>
    

2). 条件渲染

- v-if 条件渲染
- v-else-if
- v-else
- v-show 条件展示

**v-if控制的是元素的存在与否**

**v-show控制的是元素的display:none属性**
``` <h3> 条件渲染 - 单路分支 </h3>
<p v-if = "flag"> A </p>

<h3> 条件渲染 - 双路分支 </h3>
<p v-if = "flag"> A </p>
<p v-else > B </p>

<h3> 条件渲染 - 多路分支 </h3>
<p v-if = "type === '美食'"> 美食 </p>
<p v-else-if = " type === '游戏' "> 游戏 </p>
<p v-else> 睡觉 </p>

<h3> 条件展示 </h3>

<p v-show = " showFlag "> 条件展示 </p>

思考? 如果出事条件为假时? v-if   v-show 谁的性能损耗较高?
v-show

总结: 项目中如何选择哪一个?
频繁切换用  v-show
如果不是很频繁的切换,那我们用 v-if 
```

3). 列表渲染

  • v-for 指令
    <h3> 数组 </h3>
    <ul>
        <li v-for = "(item,index) in arr" :key = " index ">
             -- index
        </li>
    </ul>
    <h3> 对象 </h3>
    <ul>
        <li v-for = "(item,key,index) of obj" :key = "index">
             --  -- 
        </li>
    </ul>
    <h3> json </h3>
    <ul>
        <li v-for = "item in json" :key = "item.id">
            <span> 商品名称:  </span>
            <span> 商品价格:  </span>
        </li>
    </ul>
    
    <h3> 循环嵌套 </h3>
    
    <ul>
        <li v-for = "item in lists" :key = "item.id">
            <h3>  商品类型:  </h3>
            <ul>
                <li v-for = "item in item.type" :key = "item.id">
                    <p> 制造商:  </p>
                </li>
                <!-- <li v-for = "ele in item.type" :key = "ele.id">
    <p> 制造商:  </p>
    </li> -->
            </ul>
        </li>
    </ul>
    
    <h3> 循环number / string  </h3>
    
    <p v-for = "item in 10">  </p>
    <p v-for = "item in 'abc'">  </p>
    
  • 总结:
    • 列表渲染参数可以写三个,分别为 item key index
    • 列表渲染,要在渲染的元素身上加一个key,作为这个元素唯一的标识
    • 这个key最好是id,因为id唯一的
    • 循环嵌套式,参数名称是可以一致的
    • in / of 都可以使用

4). 表单控件绑定

- **v-model 只能用于表单元素,它默认绑定了value**
- v-model
- 双向数据绑定
- VM 改变 V随之改变
- V改变, VM也随之改变
- v-model只用于表单
- 理由: v-model默认绑定value属性
- 技巧: 看到表单直接 v-model

5). 事件处理函数

  • v-on
    • 单向数据绑定实现双向数据绑定
    • v-bind模拟v-model
    • oninput函数
    <div id="app">
    <h3> v-model </h3>
    <input type="text" v-model = "money">
    <hr>
    <h3> v-bind </h3>
      <input type="text" :value = "money" v-on:input = "changeMoney">
      <p> {{ money }} </p>
    </div>
    
    new Vue({
    el: '#app',
    data: {
      money: 1000
    },
    methods: {
    //methods里面放的都是事件处理程序
      changeMoney ( e ) {
        //修改money
        this.money = e.target.value 
      }
    },
    })