父子组件绑定及弹窗初值 -- 小技巧系列之vue 实战指南
2024-01-22 19:24:42
导言
在 Vue 应用中,父子组件通信是开发人员经常会遇到的场景之一。父子组件之间如何传递数据、如何操作子组件、如何设置子组件的初始值,都是需要解决的问题。此外,当使用子组件弹窗时,也经常需要设置初始值,例如在“复制弹窗”中需要将文件名称的初始值加上 "_副本" 的文字。
本文将针对这些问题,从原理和实践的角度出发,详细介绍如何实现父子组件绑定,如何设置子组件的初始值,以及如何在 Vue 应用中复用弹窗组件。
一、父子组件绑定
在 Vue 应用中,父子组件绑定是指父组件可以访问子组件的属性和方法,而子组件也可以访问父组件的属性和方法。这种绑定可以通过以下三种方式实现:
1. props
props 是 Vue 中父子组件通信最常用的一种方式。props 是父组件向子组件传递数据的属性,子组件可以通过 this.props.
的方式访问父组件传递的数据。例如:
// 父组件
<template>
<child-component :message="message" />
</template>
<script>
export default {
data() {
return {
message: 'Hello, Vue!'
}
}
}
</script>
// 子组件
<template>
<p>{{ message }}</p>
</template>
<script>
export default {
props: ['message'],
}
</script>
在上面的例子中,父组件通过 :message="message"
将 message
数据传递给子组件,子组件通过 this.props.message
访问父组件传递的数据。
2. $parent
$parent
属性允许子组件访问其父组件的实例。子组件可以通过 this.$parent
的方式访问父组件的属性和方法。例如:
// 子组件
<template>
<p>{{ $parent.message }}</p>
</template>
<script>
export default {
mounted() {
console.log(this.$parent.message) // 输出: Hello, Vue!
}
}
</script>
在上面的例子中,子组件通过 this.$parent.message
访问父组件的 message
数据。
3. 事件
事件是父子组件通信的另一种方式。父组件可以通过向子组件发出事件的方式通知子组件执行某些操作,子组件可以通过监听父组件发出的事件来响应父组件的操作。例如:
// 父组件
<template>
<button @click="handleClick">点击我</button>
</template>
<script>
export default {
methods: {
handleClick() {
this.$emit('child-event')
}
}
}
</script>
// 子组件
<template>
<p @click="handleChildEvent">点击子组件</p>
</template>
<script>
export default {
methods: {
handleChildEvent() {
console.log('子组件被点击了')
}
},
mounted() {
this.$on('child-event', this.handleChildEvent)
},
beforeDestroy() {
this.$off('child-event', this.handleChildEvent)
}
}
</script>
在上面的例子中,父组件通过 @click="handleClick"
监听 click
事件,当点击按钮时触发 handleClick
方法,handleClick
方法通过 this.$emit('child-event')
向子组件发出 child-event
事件。子组件通过 @click="handleChildEvent"
监听 click
事件,当点击子组件时触发 handleChildEvent
方法,handleChildEvent
方法通过 this.$on('child-event', this.handleChildEvent)
监听 child-event
事件,当父组件发出 child-event
事件时触发 handleChildEvent
方法。
二、子组件弹窗的初始值
在 Vue 应用中,使用子组件弹窗时经常需要设置初始值。例如在“复制弹窗”中需要将文件名称的初始值加上 "_副本" 的文字。
1. props
可以使用 props 的方式设置子组件的初始值。例如:
// 父组件
<template>
<child-component :initial-value="initialValue" />
</template>
<script>
export default {
data() {
return {
initialValue: '文件名称_副本'
}
}
}
</script>
// 子组件
<template>
<input v-model="value">
</template>
<script>
export default {
props: ['initialValue'],
data() {
return {
value: this.initialValue
}
},
}
</script>
在上面的例子中,父组件通过 :initial-value="initialValue"
将 initialValue
数据传递给子组件,子组件通过 this.props.initialValue
访问父组件传递的数据,并将 initialValue
数据作为 input
的初始值。
2. $emit
也可以使用 $emit
的方式设置子组件的初始值。例如:
// 父组件
<template>
<child-component @update="updateInitialValue" />
</template>
<script>
export default {
data() {
return {
initialValue: '文件名称_副本'
}
},
methods: {
updateInitialValue(value) {
this.initialValue = value
}
}
}
</script>
// 子组件
<template>
<input v-model="value" @input="handleInput">
</template>
<script>
export default {
data() {
return {
value: ''
}
},
methods: {
handleInput(event) {
this.$emit('update', event.target.value)
}
},
}
</script>
在上面的例子中,父组件通过 @update="updateInitialValue"
监听子组件发出的 update
事件,当子组件发出 update
事件时触发 updateInitialValue
方法,updateInitialValue
方法更新父组件的 initialValue
数据。子组件通过 @input="handleInput"
监听 input
事件,当 input
的值发生变化时触发 handleInput
方法,handleInput
方法通过 this.$emit('update', event.target.value)
向父组件发出 update
事件,并将 input
的值作为参数传递给父组件。
三、弹窗复用
在 Vue 应用中,弹窗组件经常会复用。例如在“复制弹窗”和“重命名”弹窗中,除了弹窗名字不同,其他内容基本相同。
1. 动态组件
可以使用动态组件的方式复用弹窗组件。例如:
<template>
<component :is="componentName" />
</template>
<script>
export default {
data() {
return {
componentName: 'copy-dialog'
}
},
}
</script>
在上面的例子中,通过 :is="componentName"
动态地渲染组件。componentName
的值可以是任何组件的名称,包括自定义组件和内置组件。
2. 插槽
也可以使用插槽的方式复用弹窗组件。例如:
<template>
<dialog>
<template v-slot:header>
<h1>弹窗标题</h1>
</template>
<template v-slot:body>
<p>弹窗内容</p>
</template>
<template v-slot:footer>
<button @click="closeDialog">关闭</button>
</template>
</dialog>
</template>
<script>
export default {
methods: {
closeDialog() {
this.$emit('close')
}
}
}
</script>
在上面的例子中,通过 <slot>
定义了三个插槽:header
、body
和 footer
。子组件可以通过 <template v-slot:header>...</template>
、<template v-slot:body>...</template>
和 <template v-slot:footer>...</template>
的方式向插槽中填充内容。
结语
本文介绍了如何在 Vue 应用中实现