组件事件
在组件模板的表达式中,可以使用 $emit 方法来触发一个自定义事件。
目的是为了让父组件可以监听这个事件,并在事件回调中处理逻辑。
继续使用上一篇文章的 ParentComponent.vue 和 ChildComponent.vue 组件。
ParentComponent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div> <h2>ParentComponent</h2> <ChildComponent @my-event="handleMyEvent" /> </div> </template>
<script> import ChildComponent from './ChildComponent.vue'
export default { components: { ChildComponent }, methods: { handleMyEvent() { console.log('handleMyEvent') } } } </script>
|
ChildComponent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div> <h2>ChildComponent</h2> <button @click="handleClick">click me</button> </div> </template>
<script> export default { methods: { handleClick() { this.$emit('my-event') } } } </script>
|
在 ParentComponent.vue 组件中,我们监听了 ChildComponent.vue 组件中触发的 my-event 事件,并在事件回调中打印了一句话。
在 ChildComponent.vue 组件中,我们在 handleClick 方法中调用了 $emit 方法,并传递了一个参数,该参数就是我们要触发的事件的名称。
配合 v-model 使用
在 Vue3 中,我们可以使用 v-model 指令来实现双向数据绑定。
例如,我们希望在用户输入的时候,实时的将用户输入的内容显示在页面上。
ParentComponent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <div> <h2>ParentComponent</h2> <p>{{ search }}</p> <ChildComponent @searchEvent="getSearch" /> </div> </template>
<script> import ChildComponent from './ChildComponent.vue'
export default { components: { ChildComponent }, data() { return { search: '' } }, methods: { getSearch(value) { this.search = value } } } </script>
|
ChildComponent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div> <h2>ChildComponent</h2> <input type="text" v-model="search" /> </div> </template>
<script> export default { data() { return { search: '' } }, watch: { search(newValue) { this.$emit('searchEvent', newValue) } } } </script>
|
在 ParentComponent.vue 组件中,我们监听了 ChildComponent.vue 组件中触发的 searchEvent 事件,并在事件回调中将传递过来的参数赋值给了 search 属性。
在 ChildComponent.vue 组件中,我们在 search 属性上使用了 v-model 指令,这样就可以实现双向数据绑定。
组件数据传递
利用 props 可以将数据从父组件传递到子组件。在这一小节主要是传递一个函数。
ParentComponent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <div> <h2>ParentComponent</h2> <p>父元素 {{ massge }}</p> <ChildComponent title="子组件" :onEvent="dataFn" /> </div> </template> <script> import ChildComponent from './ChildComponent.vue'
export default { components: { ChildComponent }, data() { return { massge: '' } }, methods: { dataFn(data) { this.massge = data } } } </script>
|
ChildComponent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <template> <div> <h2>ChildComponent</h2> <p>{{ title }}</p> <p>{{ onEvent('数据传递') }}</p> </div> </template> <script> export default { data() { return { } }, props: { title: String, onEvent: Function }, } </script>
|
透传 Attribute
“透传” 是指将一个组件的属性应用在另一个元素上。
透传属性是指那些没有在 props / emits 中声明的属性或是 v-on 事件监听器。常见的透传属性有 class、style、id 等。
当组件的根元素是一个普通的 HTML 元素时,这些属性会被添加到根元素上。
当然,我们也可以通过 inheritAttrs 选项来关闭这个特性。
ParentComponent.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div> <h2>ParentComponent</h2> <ChildComponent class="parent" /> </div> </template>
<script> import ChildComponent from './ChildComponent.vue'
export default { components: { ChildComponent } } </script>
|
ChildComponent.vue
1 2 3 4 5 6 7 8 9 10 11
| <template> <div> <h2>ChildComponent</h2> </div> </template>
<script> export default { inheritAttrs: false } </script>
|