子组件中$emit和update更新传递变量

vue2.6之后才可以使用update更新,vue2.6以下版本使用input和v-model

需求描述:蒙层上展示弹窗,弹窗点击关闭,需要向父传递关闭的信息

方法1,简便直接传递变量visible(或者不改名isModalVisible也是可以的)修改,相应的父组件中使用sync修饰符
方法2,子组件中传递变量visible(或者不改名isModalVisible也是可以的),父组件中使用@update自定义事件把这个传递过去赋值
子组件中写法都一样,区别在于父组件有两种写法,sync修饰符是语法糖。当要处理更多逻辑推荐2,否则推荐方法1。

子组件中

<template>
  <div class="subscribe-modal" @click.stop>
    <!-- 右上角关闭角标 -->
    <div class="modal-close" @click="closeCom"/>我是关闭<div>
  </div>
</template>

<script>
export default {
    name: "Son",
    data() {
        return {
        }
    },
    methods: {
        closeCom() {
            console.log('点击了关闭')
            // 方法1,简便直接传递变量visible(或者不改名isModalVisible也是可以的)修改,相应的父组件中使用sync修饰符
            this.$emit('update:visible',false)
            // 方法2,子组件中传递变量visible(或者不改名isModalVisible也是可以的),父组件中使用@update自定义事件把这个传递过去赋值
            this.$emit('update:visible',false)
        }
    }

}
</script>

<style lang="less">

</style>

父组件中

<template>
	<!-- 蒙层 -->
    <div v-if="isModalVisible" class="show-modal" @click="closeModal">
      <!-- 某个弹窗 -->
      <!-- visible是子组件的一个 prop 名称,和子组件传递过来的对应就好,后面的isModalVisible是父组件的属性 -->
      <!-- <Son :visible.sync="isModalVisible"></Son> -->
      <!-- visible是子组件的一个 prop 名称,和子组件传递过来的对应就好,后面的handleVisibilityUpdate是自定义事件,事件内处理赋值 -->
       <Son @update:visible="handleVisibilityUpdate"></Son>
    </div>
  </template>
  
  <script>
  import SubscribeModal from './modal/SubscribeModal.vue';
  export default {
    name: "ShowModal",
    components: {
      SubscribeModal
    },
    data() {
      return {
        isModalVisible: true, // 控制弹窗显示状态
      };
    },
    methods: {
      closeModal() {
        // 关闭了打开的弹窗和蒙层
        this.isModalVisible = false;
      },
      handleVisibilityUpdate(newValue) {
        this.isModalVisible = newValue;  // 传递过来的visible
      }
      
    },
  };
  </script>
  
  <style lang="less" scoped>
  .show-modal{
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.86);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .modal-content {
    z-index: 1001; /* 确保内容在蒙层之上 */
  }
  </style>
### Vue 3 中子组件修改父组件变量的实现方法 在 Vue 3 中,子组件可以通过 `$emit` 方法向父组件发送事件并携带数据,从而间接修改父组件中的变量。以下是具体的实现方式以及相关说明。 --- #### 使用 `.sync` 修饰符(Vue 2 风格) 尽管 `.sync` 是 Vue 2 的特性之一,但它仍然可以在 Vue 3 中使用。`.sync` 可以简化父子组件之间的双向绑定过程[^1]。 ##### 父组件代码 ```vue <template> <child :num.sync="numParent"></child> </template> <script> import Child from './Child.vue'; export default { components: { Child }, data() { return { numParent: 0, }; }, }; </script> ``` ##### 子组件代码 ```vue <template> <button @click="changeNum">Change Num</button> </template> <script> export default { props: ['num'], methods: { changeNum() { this.$emit('update:num', 666); // 发送更新事件给父组件 }, }, }; </script> ``` 通过 `.sync` 修饰符,父组件能够自动接收到子组件发出的 `update:num` 事件,并同步更新自身的 `numParent` 值[^1]。 --- #### 使用 `$emit` 自定义事件 这是更为通用的一种方式,适用于大多数场景。子组件通过 `$emit` 向外广播事件,父组件监听该事件并对自己的状态进行调整。 ##### 父组件代码 ```vue <template> <child @update-parent-data="handleUpdate"></child> </template> <script> import Child from './Child.vue'; export default { components: { Child }, data() { return { parentData: '初始值', }; }, methods: { handleUpdate(newData) { this.parentData = newData; // 更新父组件的数据 }, }, }; </script> ``` ##### 子组件代码 ```vue <template> <button @click="sendDataToParent">Send Data to Parent</button> </template> <script> export default { methods: { sendDataToParent() { this.$emit('update-parent-data', '新值'); // 触发自定义事件并向上传递数据 }, }, }; </script> ``` 这种方法的核心在于子组件通过 `$emit` 将数据传递给父组件,而父组件通过监听对应的事件来处理这些数据[^3]。 --- #### 使用 `ref` `defineExpose` 显式暴露接口 如果希望父组件主动获取或设置子组件的状态,可以使用 Vue 3 新增的功能:`ref` 结合 `defineExpose`[^2]。 ##### 父组件代码 ```vue <template> <children ref="childRef" /> </template> <script setup> import { ref, onMounted } from 'vue'; import Children from './Children.vue'; const childRef = ref(null); onMounted(() => { if (childRef.value && typeof childRef.value.updateParent === 'function') { childRef.value.updateParent('来自父组件的新值'); } }); </script> ``` ##### 子组件代码 ```vue <template></template> <script setup> import { defineExpose } from 'vue'; const updateParent = (newValue) => { console.log('子组件调用了父组件的逻辑:', newValue); }; defineExpose({ updateParent, // 暴露方法供父组件调用 }); </script> ``` 在这种方式中,父组件通过 `ref` 获取子组件实例,并调用由子组件显式暴露的方法或属性。这种方式更加灵活,但也增加了耦合度[^2]。 --- ### 总结 以上三种方法分别适用于不同的场景: - **`.sync` 修饰符**:简单快捷,适合基本的双向绑定需求。 - **`$emit` 自定义事件**:灵活性高,推荐作为主流方案。 - **`ref` `defineExpose`**:适合需要直接操作子组件内部逻辑的复杂场景。 无论选择哪种方式,都应遵循单向数据流的原则,即父组件负责维护状态,子组件仅能请求更改而非直接篡改。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lanmy_dl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值