一文极简了解 Vue3 父子组件的 v-model 双向绑定

一文极简了解 Vue3 父子组件的 v-model 双向绑定

自从使用 Vue3 做前端,就一直被这个问题困扰着。无论是官方文档,还是网上的文章教程,都说的不够通俗易懂。

我一直也是迷迷糊糊的用着,反正页面能跑就行了,这次彻底把这个逻辑搞明白。

这篇文章不说任何底层技术,也不说双向绑定、单向绑定、数据流向这样的概念解释,咱就用代码去解释,一切都在注释中。

父组件代码

<template>
  <div>
    <!-- 双向绑定 visible -->
    <!-- 非双向绑定 count,需要使用 @update-count 绑定更新事件 -->
    <Camera v-model:visible="cameraVisible" :count="cameraCount" @update-count="handleCountUpdate" />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const cameraVisible = ref(false)
const cameraCount = ref(0)

function handleCountUpdate(newCount) {
  cameraCount.value = newCount
}
</script>

子组件代码

<template>
  <el-dialog v-model="visible" @close="handleClose">
    <button @click="incrementCount">Increment Count</button>
  </el-dialog>
</template>

<script setup>
  import { ref, watch } from 'vue'

  // 通过 props 接收父组件传过来的值
  const props = defineProps({
    visible: boolean,
    count: number
  })

  // 使用 defineEmits 声明子组件可以发送的事件
  // visible 是双向绑定的数据,因此使用 update: 事件,这里需要和父组件 props 名称相同
  // count 是非双向绑定的数据,使用自定义事件(事件名称可以自定义,如:update-count1、update-count2)
  const emit = defineEmits(['update:visible', 'update-count'])

  // 将 props 接收到的值转换为本地响应式数据,方便子组件使用
  const visible = ref(props.visible)
  const count = ref(props.count)

  // 监听父组件 visible 的值,如果父组件值变化,同步更新本地响应式数据
  watch(() => props.visible, (newVal) => {
    visible.value = newVal
  })

  // 监听本地响应式数据的变化,发送 update:visible 事件,由于是双向绑定,父组件的值会直接改变。这里传递的 visible 是 ref 对象,可以直接传递,Vue 自动解包数据,也可使用 () => visible.value
  watch(visible, (newVal) => {
    emit('update:visible', newVal)
  })

  // 同上
  watch(() => props.count, (newVal) => {
    count.value = newVal
  })

  // 逻辑同上,但 count 是非双向绑定,因此父组件需要做额外处理以更新父组件的值
  watch(count, (newVal) => {
    emit('update-count', newVal)
  })

  // 子组件在不同情况下修改 visible 和 count 的值
  function handleClose() {
    visible.value = false
  }
  function incrementCount() {
    count.value++
  }
</script>

小结

  • 双向绑定不局限于单个值,哪些数据使用双向绑定视需求而定,看明白了上面的代码,可再深入了解双向绑定和非双向绑定的区别
  • 无论是否双向绑定,子组件均需要使用 emit 向父组件发送数据,唯一不同的是父组件接收数据的方式

以上。