【Vue.js】之V-model双向绑定

1.自己实现一个v-model

Index.vue

<template>
  <div>
      <p>vue高级特性</p>
      <hr>

      <!-- 自定义 v-model -->
      <p>{{name}}</p>
      <CustomVModel v-model="name"></CustomVModel>
  </div>
</template>

<script>
import CustomVModel from './VModel'
export default {
  components: {
    CustomVModel
  },
  data () {
    return {
      name: '夹心'
    }
  }
}
</script>

<style>

</style>

VModel.vue

<template>
  <input type="text"
         :value = "text"
         @input = "$emit('change', $event.target.value)">
</template>
/* 1.上面的input使用了:value而不是v-model
   2.上面的change和model.event要对应起来
   3.text属性要对应起来
 */

<script>
export default {
  model: {
    prop: 'text',
    event: 'change'
  },
  props: {
    text: String,
    default () {
      return ''
    }
  }
}
</script>

<style>

</style>

2.V-model作用

v-model本质上不过是语法糖, 可以用v-model指令在表单上及元素上创建双向数据绑定

  1. 它会根据控件类型自动选取正确的方法来更新元素
  2. 它负责监听用户的输入数据以更新数据,并对一些极端场景进行一些特殊处理
  3. v-model会忽略所有表单元素的value, checked, selected特性的初始值,而总是将Vue实例的数据作为数据来源,因此我们应该通过Javascript在组件的data选项中声明初始值
  4. 4.v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件
    • text和textarea元素使用value属性和input事件
    • checkbox和radio使用checked属性和change事件
    • select字段将value作为prop并将change作为事件

3.V-Model的实现原理

v-model只不过是一个语法糖而已,真正实现靠的还是

  1. v-bind: 绑定响应式数据
  2. 触发oninput事件并传递数据
<input v-model="sth" />
<input :value="sth" @input="sth = $event.target.value" />
  • 自html5开始, input每次输入都会触发oninput事件, 所以输入时input的内容会被绑定到sth中, 于是sth的值就被改变

$event 指代当前触发的事件对象
$event.target指代当前触发的事件对象的dom
$event.target.value就是当前dom的value值
在@input方法中, value => sth
在:value中, sth => value

4.Vue2.0双向绑定的缺陷

Vue2.0的数据响应式采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter、getter,但是它并算是实现数据的响应式的完美方案,主要有以下缺陷:

1.Vue实例创建后, 无法检测到对象属性的新增或者删除, 只能追踪到数据是否修改
2.不能监听数组变化
vue 实例创建后,无法检测到对象属性的新增或删除,只能追踪到数据是否被修改(Object.defineProperty只能劫持对象的属性)。

1.当创建一个Vue实例时,将遍历所有DOM对象,并为每个数据属性添加了get和set。get和set 允许Vue观察数据的更改并触发更新。但是,如果在Vue实例化后添加(或删除)一个属性,这个属性不会被vue处理,改变get和set。

解决方案:

Vue.set(obj, propertName/index, value)
// 响应式对象的子对象新增属性,可以给子响应式对象重新赋值
data.location = {
    x: 100,
    y: 100
}
data.location = {...data, z: 100}

2.不能监听数组的变化
Vue在实现数组的响应式时,使用了一些hack,把无法监听数组的情况通过重写数组的部分方法来实现响应式,这也只限制在数组的push/pop/shift/unshift/splice/sort/reverse七个方法,其他数组方法及数组的使用则无法检测到。

5. Vue3.0 实现数据双向绑定的方法

vue3.0 实现数据双向绑定是通过Proxy

Proxy是 ES6 中新增的一个特性,翻译过来意思是"代理"。 Proxy 让我们能够以简洁易懂的方式控制外部对对象的访问。其功能非常类似于设计模式中的代理模式。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

使用 Proxy 的核心优点是可以交由它来处理一些非核心逻辑(如:读取或设置对象的某些属性前记录日志;设置对象的某些属性值前,需要验证;某些属性的访问控制等)。 从而可以让对象只需关注于核心逻辑,达到关注点分离,降低对象复杂度等目的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值