Vue单向数据流下双向绑定父子组件数据

单向数据流

Vue遵循单向数据流原则,父组件向子组件传递props,子组件不能更改props,否则会报错,也即数据只能由父组件流向子组件,子组件不能修改父组件数据。

双向数据绑定

那么在一些场景下,如弹窗场景,子组件的确需要更新父组件数据,要怎么处理呢?Vue推荐是父组件使用props传递数据给子组件,子组件再通过自定义事件通知父组件修改数据,这样一来数据就始终是由父组件控制的了。

xml 复制代码
<!-- 父组件 -->
<template>
  <button @click="show = true">打开</button>
  <Dialog
    :show="show"
    @update:show="e => show = e"
  >
  </Dialog>
</template>
<script>
  export default{
    data(){
      return {
        show: false
      }
    }
  }
</script>
xml 复制代码
<!-- 子组件 -->
<template>
  <div v-if="show">
    <button @click="$emit('update:show', false)">关闭</button>
  </div>
</template>
<script>
  export default {
    props: {
      show: {
        type: Boolean,
        default: false
      }
    }
  }
</script>

Vue2使用.sync语法糖

在Vue2中提供了修饰符.sync作为双向数据绑定的语法糖,使用.sync修饰符,父组件可以写为

ini 复制代码
<Dialog :show.sync="show"></Dialog>

子组件不变,同样通过this.$emit更新数据。

Vue3使用v-model

Vue3中则是移除了.sync修饰符,选择用v-model实现双向数据绑定,在Vue3中可以写成

ini 复制代码
<Dialog v-model:show="show"></Dialog>

子组件中同样通过emit自定义事件更新数据,注意Vue3中不能用this.$emit,而是要defineEmits("update:show")定义事件。

xml 复制代码
<!-- 子组件 -->
<template>
  <div v-if="show">
    <button @click="$emit('update:show', false)">关闭</button>
  </div>
</template>
<script setup>
  import { defineEmits } from "vue"
  const $emit=defineEmits(['update:show'])
</script>

defineModel

在Vue3.4+中还提供了defineModel宏,使得双向绑定的实现更加简洁,在使用子组件时直接defineModel声明一个model prop,这样,在子组件内部直接修改这个声明的值就会自动触发update事件。

如果第一个参数是一个字符串字面量,它将被用作 prop 名称;否则,prop 名称将默认为 "modelValue"。

xml 复制代码
<!-- 子组件 -->
<template>
  <div v-if="show">
    <button @click="show=false">关闭</button>
  </div>
</template>
<script setup>
 const show=defineModel('show',{type: Boolean,default: false})
</script>
相关推荐
溪语流沙35 分钟前
【Web全栈进阶】Nginx反向代理 + HTTPS:正式上线
前端·vue.js·python·nginx·https·fastapi
夕阳_醉了2 小时前
让 AI 回答“打字般”浮现:用 Vue 3 + DeepSeek 实现流式聊天
前端·vue.js·人工智能
酷炫码神2 小时前
Day 9|Vue Router:把单页后台拆成能跳转的多页面
前端·javascript·vue.js
Java后端的Ai之路19 小时前
前端技术Vue-09-webpack-vuejs-实战
前端·vue.js·webpack
tryCbest20 小时前
Vue3——第 7 篇:组件基础——从注册到使用的完整流程
前端·javascript·vue.js
weixin_BYSJ198720 小时前
【计算机毕设】房屋租赁系统02647
java·vue.js·spring boot·python·django·课程设计
时间的情敌21 小时前
Electron 设置-webkit-app-region: drag;实现拖拽后, 无法响应鼠标划过事件及点击事件的解决方式
前端·vue.js
专业程序开发源1 天前
springboot校企合作双选会一站式预约与面试系统16010-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·面试·php·课程设计
凯凯姜1 天前
Vue 3 深入学习笔记 16:API 请求封装与统一错误处理
vue.js·笔记·学习
Java后端的Ai之路1 天前
前端框架Vue-07_原生的Vue.js
前端·vue.js·前端框架