纵有疾风起
人生不言弃

Vue.js 组件 – 自定义事件

Vue.js 组件 – 自定义事件

父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

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

以下实例中子组件已经和它外部完全解耦了。它所做的只是触发一个父组件关心的内部事件。

实例

<
div

id
=

app

>

<
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
>

</
div
>

<
script
>
Vue.component(‘button-counter’, { template: ‘
<
button

v-on:click
=

incrementHandler

>
{{ counter }}
</
button
>
‘, data: function () { return { counter: 0 } }, methods: { incrementHandler: function () { this.counter += 1 this.$emit(‘increment’) } }, }) new Vue({ el: ‘#counter-event-example’, data: { total: 0 }, methods: { incrementTotal: function () { this.total += 1 } } })
</
script
>


尝试一下 »

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

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

data 必须是一个函数

上面例子中,可以看到 button-counter 组件中的 data 不是一个对象,而是一个函数:

data: function () {
  return {
    count: 0
  }
}

这样的好处就是每个实例可以维护一份被返回对象的独立的拷贝,如果 data 是一个对象则会影响到其他实例,如下所示:

实例

<
div

id
=

components-demo3


class
=

demo

>

<
button-counter2
>
</
button-counter2
>

<
button-counter2
>
</
button-counter2
>

<
button-counter2
>
</
button-counter2
>

</
div
>

<
script
>
var buttonCounter2Data = { count: 0 } Vue.component(‘button-counter2’, { /* data: function () { // data 选项是一个函数,组件不相互影响 return { count: 0 } }, */ data: function () { // data 选项是一个对象,会影响到其他实例 return buttonCounter2Data }, template: ‘
<
button

v-on:click
=

count++

>
点击了 {{ count }} 次。
</
button
>
‘ }) new Vue({ el: ‘#components-demo3’ })
</
script
>


尝试一下 »

自定义组件的 v-model

组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件。

<input v-model="parentData">

等价于:

<input 
    :value="parentData"
    @input="parentData = $event.target.value"
>

以下实例自定义组件 runoob-input,父组件的 num 的初始值是 100,更改子组件的值能实时更新父组件的 num:

实例

<
div

id
=

app

>

<
runoob-input

v-model
=

num

>
</
runoob-input
>

<
p
>
输入的数字为:{{num}}
</
p
>

</
div
>

<
script
>
Vue.component(‘runoob-input’, { template: `
<
p
>

<!–
包含了名为 input 的事件
–>

<
input

ref
=

input


:value
=

value

@
input
=

$emit(‘input’, $event.target.value)


>

</
p
>
`, props: [‘value’], // 名为 value 的 prop }) new Vue({ el: ‘#app’, data: { num: 100, } })
</
script
>


尝试一下 »

由于 v-model 默认传的是 value,不是 checked,所以对于对于复选框或者单选框的组件时,我们需要使用 model 选项,model 选项可以指定当前的事件类型和传入的 props。

实例

<
div

id
=

app

>

<
base-checkbox

v-model
=

lovingVue

>
</
base-checkbox
>

<
div

v-show
=

lovingVue

>
如果选择框打勾我就会显示。
</
div
>

</
div
>

<
script
>
// 注册 Vue.component(‘base-checkbox’, { model: { prop: ‘checked’, event: ‘change’ // onchange 事件 }, props: { checked: Boolean }, template: `
<
input

type
=

checkbox


v-bind:checked
=

checked


v-on:change
=

$emit(‘change’, $event.target.checked)


>
` }) // 创建根实例 new Vue({ el: ‘#app’, data: { lovingVue: true } })
</
script
>


尝试一下 »

实例中 lovingVue 的值会传给 checked 的 prop,同时当 <base-checkbox> 触发 change 事件时, lovingVue 的值也会更新。

未经允许不得转载:起风网 » Vue.js 组件 – 自定义事件
分享到: 生成海报

评论 抢沙发

评论前必须登录!

立即登录