返回

父子组件绑定及弹窗初值 -- 小技巧系列之vue 实战指南

前端

导言

在 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> 定义了三个插槽:headerbodyfooter。子组件可以通过 <template v-slot:header>...</template><template v-slot:body>...</template><template v-slot:footer>...</template> 的方式向插槽中填充内容。

结语

本文介绍了如何在 Vue 应用中实现