您的位置:首页 > 产品设计 > UI/UE

曹可爱之最可爱-Vue.js入门(十)组件3

2017-11-01 22:30 751 查看

自定义事件

我们知道,父组件使用prop传递数据给子组件。但是子组件怎么跟父组件通信呢?这个时候Vue的自定义事件系统就派上用场了。

使用v-on绑定自定义事件

每个Vue实例都实现了事件接口,即:

使用$on(eventName)监听事件

使用$emit(eventName)触发事件

另外,父组件可以在使用子组件的地方直接用v-on监听子组件触发的事件。

<div id ="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>


Vue.component('button-counter', {
template: '<button v-on:click="incrementCounter">{{ counter }}</button>',
data: function(){
return {
counter: 0
}
},
methods: {
incrementCounter: functiom() {
this.counter += 1
this.$emit('increment')
}
},
})

new Vue({
el:'#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function(){
this.total += 1
}
}
})


给组件绑定原生事件

如果想在某个组件的根元素上监听一个原生事件。可以使用v-on的修饰符.native。例如:

<my-component v-on:click.native="doTheThing"></my-component>


使用自定义事件的表单输入组件(到底说了啥?)

自定义事件可以用来创建自定义的表单输入组件,使用v-model来进行数据双向绑定。

<input v-model="something">


这不过是以下示例的语法糖:

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


所以在组件中使用时,相当于下面的简写:

<custom-input
v-bind:value="something"
v-on:input="something = arguments[0]">
</custom-input>


所以要让组件的v-model生效,它应该:

1.接受一个value prop

2.在有新的值时触发input事件并将新值作为参数

看一个非常简单(?)的货币输入的自定义控件

<currency-input v-model="price"></currency-input>


Vue.component('currency-input', {
template: '\
<span>\
$\
<input\
ref="input"\
v-bind:value="value"\
v-on:input="updateValue($event.target.value)"\
>\
</span>\
',
props: ['value'],
methods: {
// 不是直接更新值,而是使用此方法来对输入值进行格式化和位数限制
updateValue: function (value) {
var formattedValue = value
// 删除两侧的空格符
.trim()
// 保留 2 位小数
.slice(
0,
value.indexOf('.') === -1
? value.length
: value.indexOf('.') + 3
)
// 如果值尚不合规,则手动覆盖为合规的值
if (formattedValue !== value) {
this.$refs.input.value = formattedValue
}
// 通过 input 事件带出数值
this.$emit('input', Number(formattedValue))
}
}
})


自定义组件的v-model

默认情况下,一个组件的 v-model 会使用 value prop 和 input 事件。但是诸如单选框、复选框之类的输入类型可能把 value 用作了别的目的。model 选项可以避免这样的冲突:

 Vue.component('my-checkbox', {
 model: {
 prop: 'checked',
 event: 'change'
},
props: {
checked: Boolean,
value: String
},
//...
})


<my-checkbox v-model="foo" value="some value"></my-checkbox>


上述代码等价于:

<my-checkbox
:checked="foo"
@change="val => { foo = val }"
value="some value">
</my-checkbox>


非父组件的通信

有时候,非父子关系的两个组件之间也需要通信。在简单的场景下,可以使用一个空的 Vue 实例作为事件总线:

var bus = new Vue()


// 触发组件 A 中的事件
bus.$emit('id-selected', 1)


// 在组件 B 创建的钩子中监听事件
bus.$on('id-selected', function (id) {
// ...
})


在复杂的情况下,我们应该考虑使用专门的状态管理模式。

总结:现在脑子就是猪脑子什么都看不进去了,特别是使用自定义事件的表单输入组件不知道讲了什么鬼,等清醒了再回过头来看吧,挖坑先。

9f16
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: