Vue自定义事件
1. 事件的命名规范
组件上事件的命名推荐使用分隔符写法(** kebab-case **),如下面的add-size
,因为html是大小写不敏感的,v-on
后面跟的事件名都会转成小写的。用大写的会导致监听不到事件。
<div id="dynamic-component-demo" class="demo"> <base-checkbox v-on:add-size="doSomething"></base-checkbox> </div> <script> Vue.component('base-checkbox', { template: ` <button v-on:click="$emit('add-size')">按钮</button> ` }) new Vue({ el: "#dynamic-component-demo", data: { lovingVue: true, }, methods: { doSomething: function () { alert(1); } } }); </script>
2. 自定义组件的v-model
允许一个自定义组件在使用 v-model 时定制 prop 和 event。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突。
如下复选框:利用model定义了v-model把checked用作prop,把change作为event
<div id="dynamic-component-demo" class="demo"> <base-checkbox v-model="lovingVue"></base-checkbox> </div> <script> Vue.component('base-checkbox', { model: { prop: 'checked', event: 'change' }, props: { checked: Boolean }, template: ` <div> <input type="checkbox" v-bind:checked="checked" v-on:change="$emit('change', $event.target.checked)" > </div> ` }) new Vue({ el: "#dynamic-component-demo", data: { lovingVue: true, } }); </script>
3. 将原生事件绑到组件
重点:.native修饰符的使用 和 $listeners的使用
用 .native修饰符
如下代码的第10行,如果用 v-on:focus.native="focus",那么第20行的label包裹标签要去掉才有用,因为.native表示该事件直接作用于该组件的根元素上,根元素是input时,focus事件才发挥作用
$listeners
为了避免上述根元素变掉,导致加载组件上原生事件不起作用的问题,vue引入了$listeners,如下,第10行的.native不需要了,在组件模板中input上加上 v-on="$listeners" ,表示加在组件上的原生事件都应用在模板中input元素上。
问题解决,完美! 完整demo如下:
<div id="dynamic-component-demo" class="demo"> <base-input data-date-picker="activated" v-bind:label="pleae" label2="dd" v-bind:value="aa" v-model="username" required placeholder="Enter your username" v-on:focus="onFocus" // v-on:focus.native="focus" ></base-input> </div> <script> Vue.component('base-input', { inheritAttrs: false, props: ['label', 'value'], template: ` <label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on:input="$emit('input', $event.target.value)" v-on="$listeners" > </label> ` }) new Vue({ el: "#dynamic-component-demo", data: { aa:1, username:'cc', pleae:'pleae' }, methods:{ onFocus:function () { console.log('focus') } } });
4. .sync修饰符
子组件改变父组件属性的值,实现双向数据绑定
如下代码中使用 sync修饰符,使代码由三行变成一行,更简洁。
<div id="dynamic-component-demo"> <!-- <text-document v-bind:title="doc.title" v-on:update:title="doc.title = $event" ></text-document>--> <!-- .sync这种写法是上面写法的简写方式 --> <text-document v-bind:title.sync="doc.title"></text-document> </div> <script> Vue.component('text-document', { props: ['title'], template: ` <div> <h1>{{title}}</h1> <button v-on:click="changeTitle">change title</button> </div> ` , methods: { changeTitle: function () { // 改变了父组件中title属性的值,实现了双向数据绑定 this.$emit('update:title', 'new Title'); } } }) new Vue({ el: "#dynamic-component-demo", data: { doc: { title: 'hello vue' } } }); </script>