vue组件通信_单向数据流 / 父向子 / 子向父 自定义事件

这篇博客探讨了Vue中组件通信的原理,强调了props的只读特性,防止子组件直接修改导致数据不一致。通过实例展示了如何通过自定义事件实现子组件向父组件传递数据,从而更新父组件状态,达到子组件影响父组件的效果,确保数据的单向流动。
摘要由CSDN通过智能技术生成

vue组件通信_单向数据流

目标: props变量本身是只读不能重新赋值

目标:从父到子的数据流向,叫单向数据流

原因: 子组件修改, 不通知父级, 造成数据不一致性

如果第一个MyProduct.vue内自己修改商品价格为5.5, 但是App.vue里原来还记着18.8 - 数据 不一致了

所以: Vue规定props里的变量, 本身是只读

在这里插入图片描述
父组件

<template>
  <div>
      <!--3. 使用组件 -->
<MyproDuct 
v-for="item  in list"
:key="item.id"
:title="item.proname"
:price="item.proprice"
:info="item.info"
></MyproDuct>
  </div>
</template>

<script>
// 1.引入组件
import MyproDuct from './components/MyproDuct.vue'
export default {
    data () {
        return {
    list: [
    { id: 1, proname: "超级好吃的棒棒糖", proprice: 18.8, info: '开业大酬宾, 全场8折' },
    { id: 2, proname: "超级好吃的大鸡腿", proprice: 34.2, info: '好吃不腻, 快来买啊' },
    { id: 3, proname: "超级无敌的冰激凌", proprice: 14.2, info: '炎热的夏天, 来个冰激凌了' },
    ],
        }
    },
    //2. 注册组件
components: {
    MyproDuct:MyproDuct
}
}
</script>

<style>

</style>

子组件

<template>
  <div class="my-product">
    <h3>标题: {{title}}</h3>
    <p>价格: {{price}}</p>
    <p>{{info}}</p>
    <button @click="btn">是兄弟就来砍一刀</button>
  </div>
</template>

<script>
export default {
  methods: {
    btn(){
      // 💥浏览器报错 :避免直接改变属性,因为每当父组件重新渲染时,该值将被覆盖
      this.price -= 1
    }
  },
  // 声明变量。由父组件传值过来
    props: ['title','price','info']
}
</script>

<style>
.my-product {
  width: 400px;
  padding: 20px;
  border: 2px solid #000;
  border-radius: 5px;
  margin: 10px;
}
</style>

报错
在这里插入图片描述

总结: 所以props变量本身是不能重新赋值的

问题: 那我怎么才能修改子组件接收到的值呢? - 其实要影响父亲, 然后数据响应式来影响儿子们

vue组件通信_子向父

目标: 从子组件把值传出来给外面使用

需求: 课上例子, 砍价功能, 子组件点击实现随机砍价-1功能

在这里插入图片描述

语法:

  • 父: @自定义事件名=“父methods函数”
  • 子: this.$emit(“自定义事件名”, 传值) - 执行父methods里函数代码

父组件
在这里插入图片描述

<template>
  <div>
      <!-- 
          目标:父(当前的 vue 文件) -> 子(MyproDuct.vue)分别传值进入
          需求:每次组件显示不同的数据信息
          步骤(口诀):
          1.子组件 - props - 变量(准备接收)
          2.父组件 - 传值进去 - 标签属性传值

          目标2:子触发父组件的自定义事件,实现修改父组件数据
          父组件:
          @自定义事件 = "事件处理函数"
          子组件:
          this.$emit('自定义事件',值)
       -->
      <!--3. 使用组件 -->
<MyproDuct 
v-for="(item,index)  in list"
:key="item.id"
:title="item.proname"
:price="item.proprice"
:info="item.info"
:index ="index"
@kanPrice ="kanFn"
></MyproDuct>
  </div>
</template>

<script>
// 1.引入组件
import MyproDuct from './components/MyproDuct.vue'
export default {
    data () {
        return {
    list: [
    { id: 1, proname: "超级好吃的棒棒糖", proprice: 18.8, info: '开业大酬宾, 全场8折' },
    { id: 2, proname: "超级好吃的大鸡腿", proprice: 34.2, info: '好吃不腻, 快来买啊' },
    { id: 3, proname: "超级无敌的冰激凌", proprice: 14.2, info: '炎热的夏天, 来个冰激凌了' },
    ],
        }
    },
    methods: {
        // 自定义事件的处理函数
      kanFn(index,price){
        //   低于 1 块钱,就不给砍了
          if(this.list[index].proprice < 1 ) return alert('再砍就凉凉了!')
        //   根据索引减少价格
          this.list[index].proprice = (this.list[index].proprice - price).toFixed(2)
      }  
    },
    //2. 注册组件
components: {
    MyproDuct:MyproDuct
}
}
</script>

<style>

</style>

子组件:MyproDuct.vue
在这里插入图片描述

<template>
  <div class="my-product">
    <h3>标题: {{title}}</h3>
    <p>价格: {{price}}</p>
    <p>{{info}}</p>
    <button @click="btn">是兄弟就来砍一刀</button>
  </div>
</template>

<script>
export default {
  methods: {
    btn(){
      // 💥浏览器报错 :避免直接改变属性,因为每当父组件重新渲染时,该值将被覆盖
      // this.price -= 1
      // 🔔 子组件通过自定义事件,触发对应的事件处理函数
      this.$emit('kanPrice' , this.index , 1)
    }
  },
  // 声明变量。由父组件传值过来
    props: ['title','price','info','index']
}
</script>

<style>
.my-product {
  width: 400px;
  padding: 20px;
  border: 2px solid #000;
  border-radius: 5px;
  margin: 10px;
}
</style>

总结: 父自定义事件和方法, 等待子组件触发事件给方法传值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Henry_ww

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

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

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

打赏作者

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

抵扣说明:

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

余额充值