用了几个月Vue一直很纠结自定义组件的v-model实现,最近开始学习React时,React中受控组件与状态提升的理念与v-model不谋而合。

转载请注明地址: https://www.cnblogs.com/sonoda-umi/p/9750188.html

在Vue与React中其实都存在单向数据流的概念,只不过Vue中通过各种语法糖被弱化了,比如React与Vue中的props都是单向传输数据的。在React中如果想实现类似于v-model的功能,需要这样实现:

父组件:

class Calculator extends React.Component {
constructor(props) {
super(props);
this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
this.state = {temperature: '', scale: 'c'};
} handleCelsiusChange(temperature) {
this.setState({scale: 'c', temperature});
} handleFahrenheitChange(temperature) {
this.setState({scale: 'f', temperature});
} render() {
const scale = this.state.scale;
const temperature = this.state.temperature;
const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature; return (
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={this.handleCelsiusChange} /> <TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={this.handleFahrenheitChange} /> <BoilingVerdict
celsius={parseFloat(celsius)} /> </div>
);
}
}

子组件:

class TemperatureInput extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
} handleChange(e) {
this.props.onTemperatureChange(e.target.value);
} render() {
const temperature = this.props.temperature;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
}

这是一个输入水温从而监控水是否沸腾的一个小组件。子组件是一个温度输入的input控件,父组件是由两个温度输入(华氏与摄氏)与一个现实水是否沸腾的指示器组成。父组件存在一个state作为唯一数据源用于存放温度等值于状态,温度通过子组件的prop传入子组件内部通过input的value属性显示在基础输入框中,当在基础输入框中触发输入时间时,onChange事件触发由prop传入的onTempreture事件并附带变化后的值,再由父组件的handleCelsiusChange/handleFahrenheitChange事件处理方法将基础输入框传来的值写入state中,再由state通过prop将温度传入子组件完成一次数据的更新。这其中其实已经完成了对Vue中基础组件v-model的理解与自定义组件v-model的理解。

转载请注明地址: https://www.cnblogs.com/sonoda-umi/p/9750188.html

在Vue官方文档中,对原生组件v-model的解释是这样的:

<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>

v-model其实是上面写法的语法糖。其实就是将this.searchText的值通过名为value的prop传入input组件内,而后当input事件触发时将事件带来的input的新值写入this.searchText中,然后根据this.searchText中值的变化通过value的prop传入input控件完成input控件上值的变化,如果去掉v-on...后,这个控件将变为一个只读控件。

对于自定义组件,文档中有这样的解释:

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不同的目的。model 选项可以用来避免这样的冲突:

Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
现在在这个组件上使用 v-model 的时候:
<base-checkbox v-model="lovingVue"></base-checkbox>
这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当 <base-checkbox> 触发一个 change 事件并附带一个新的值的时候,这个 lovingVue 的属性将会被更新。

其实就是将原来v-model默认使用的名为value的prop与名为input的event自定义一个名字使用,在上面自定义组件中存在

props: {
checked: Boolean
}

说明checked本质上还是一个prop,然后在子组件的model属性中将自定义的prop与event注册,而触发model中event时也就是通过触发子组件的事件在父组件中修改绑定自定义prop的变量的值的过程,这样这个过程就很明显了:

1.父组件创建一个名为tmp变量绑定名为checked的prop的值(已被修饰为v-model)并根据父组件中tmp值的变化将变化后的值传入子组件中,引起子组件checkbox状态变化;

2.子组件中checkbox被勾选,触发checkbox的change事件,通过this.$emit方法触发子组件的change事件并将change事件产生的新值传入;

3.因为在model属性中已将v-model语法糖中event注册为change(换成其他名字也都可以),v-model会自动将子组件传来的值传入tmp变量中;

4.Vue监听到tmp值的变化,执行第一步,更新子组件中checkbox的状态;

其实上面的子组件可以换个写法更容易理解:

Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'test'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('test', $event.target.checked)"
>
`
})

父组件中调用时可以这样写:

<base-checkbox :checked="something" @test="something='子组件中的$event.target.value'"></base-checkbox>

这样对v-model的理解也就一目了然了。

转载请注明地址: https://www.cnblogs.com/sonoda-umi/p/9750188.html

自定义组件v-model的实质性理解的更多相关文章

  1. vue 自定义封装组件 使用 model 选项

    自定义组件的 v-model 一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框.复选框等类型的输入控件可能会将 value 特性用于不同 ...

  2. 【Spring注解驱动开发】自定义组件如何注入Spring底层的组件?看了这篇我才真正理解了原理!!

    写在前面 最近,很多小伙伴出去面试都被问到了Spring问题,关于Spring,细节点很多,面试官也非常喜欢问一些很细节的技术点.所以,在 Spring 专题中,我们尽量把Spring的每个技术细节说 ...

  3. Android开发之自定义组件和接口回调

    说到自定义控件不得不提的就是接口回调,在Android开发中接口回调用的还是蛮多的.在这篇博客开始的时候呢,我想聊一下iOS的自定义控件.在iOS中自定义控件的思路是继承自UIView, 在UIVie ...

  4. vue框架之自定义组件中使用v-model

    通常 vue在html常见表单空间支持v-model双向绑定例如 <input v-model="message" placeholder="edit me&quo ...

  5. vue自定义组件中的v-model简单解释

    在使用iview框架的时候,经常会看到组件用v-model双向绑定数据,与传统步骤父组件通过props传值子组件,子组件发送$emit来修改值相比,这种方式避免操作子组件的同时再操作父组件,显得子组件 ...

  6. 前端 | 自定义组件 v-model:Vue 如何实现双向绑定

    v-model 是 Vue 中一个常用的指令,常用于表单中的数据绑定.如下基本用法想必大家都很熟悉,data 中的 checked 属性的值就会随着多选框的状态实时变化. <el-checkbo ...

  7. Vue3 SFC 和 TSX 方式自定义组件实现 v-model

    1 v-model 1.1 理解 v-model v-model 是 vue3 中的一个内置指令,很多表单元素都可以使用这个属性,如 input.checkbox 等,咱可以在自定义组件中实现 v-m ...

  8. Android自定义组件

    [参考的原文地址] http://blog.csdn.net/l1028386804/article/details/47101387效果图: 实现方式: 一:自定义一个含有EditText和Butt ...

  9. PhoneGap: Android 自定义组件

    Hello Core Demo Plugin Development(组件部署): http://docs.phonegap.com/en/2.0.0/guide_plugin-development ...

随机推荐

  1. mysql五补充:SQL逻辑查询语句执行顺序(待完善)

    一.SELECT语句关键字的定义顺序(语法顺序) SELECT DISTINCT <select_list> FROM <left_table> <join_type&g ...

  2. 从零开始的全栈工程师——JS面向对象(复习)

    作用域 栈内存:js执行的环境堆内存:存放代码块的空间 存放方式 键值对形式存放 字符串的形式存放js在执行之前 浏览器会给他一个全局作用域叫window 每个作用域下都分为两个模块 一个是内存模块一 ...

  3. caffe-windows之彩色图像分类例程cifar10

    一.caffe-windows之彩色图像分类例程cifar10 训练测试网络模型[参考1][参考2] 1. 准备数据 下载二进制数据集数据集,下载链接为http://www.cs.toronto.ed ...

  4. vuejs源码摘抄(二)

    创建一个用来观察对象的observe类,这个类会附加在被观察的对象上,并且把被观察对象的属性值转换成getter/setter,同时,收集依赖和分发更新,实现代码如下: /* * not type c ...

  5. java 实现二叉树结构基本运算详细代码

    static final int MAXLEN = 20; //最大长度 class CBTType //定义二叉树节点类型 { String data; //元素数据 CBTType left; / ...

  6. wxpython wx.windows的API

    wx.Window is the base class for all windows and represents any visible object on screen. All control ...

  7. wxpython 界面布局

    1.frame.Centre() 窗口出来后显示居中 2.textCtrl文本框style=wx.TE_PASSWORD密码, wx.TE_MULTILINE多行输入 3.单选按钮组 4.列表 5.图 ...

  8. OLAP和数据挖掘的区别

    总结来说: 数据仓库提供了一个分析的数据源 数据挖掘能分析出未知的信息,提出假设 OLAP能通过分析,验证假设 从技术角度看,商务智能的过程是企业的决策人员以企业中的数据仓库为基础,经由数据挖掘工具. ...

  9. March 10 2017 Week 10 Friday

    If you love life, life will love you back. 爱生活,生活也会爱你. Love life, and it will love you back. All thi ...

  10. 在Kubernetes上运行SAP UI5应用(上)

    2018年只剩最后30天了.Jerry在2017年的最后一天,曾经立下一个目标:这个微信公众号在2018年保证至少每周发布一篇SAP原创技术文章. 从Jerry在后台统计的2018全年文章数量来看,这 ...