vue中两个div均有click时间且div重合_Vue中组件通信的方式

vue是数据驱动视图更新的框架, 所以对于vue来说组件间的数据通信非常重要;我们常用的方式莫过于通过props传值给子组件,但是vue还有其他很多不常用的通信方式,了解他们,也许在以后在写代码的时候能给你带来更多的思路和选择。

prop/$emit

父组件通过prop的方式向子组件传递数据,而通过$emit子组件可以向父组件通信。

//Parent.vue
<template>
  <div>
    当前选中:{
    {
     current }}
    <Child :list="list" @change="changeCurrent"></Child>
  </div>
</template>
<script>
import Child from "./child";
export default {
    
  data() {
    
    return {
    
      current: 0,
      list: ["红楼梦", "水浒传", "三国演义", "西游记"]
    };
  },
  components: {
     Child },
  methods: {
    
    changeCurrent(num) {
    
      this.current = num;
    }
  }
};
</script>

我们可以通过prop向子组件传递数据;用一个形象的比喻来说,父子组件之间的数据传递相当于自上而下的下水管子,管子中的水就像数据,水只能从上往下流,不能逆流。这也正是Vue的设计理念之单向数据流。而prop正是管道与管道之间的一个衔接口,这样水(数据)才能往下流。

//Child.vue
<template>
  <div>
    <template v-for="(item, index) in list">
      <div @click="clickItem(index)" :key="index">{
    {
     item }}</div>
    </template>
  </div>
</template>
<script>
export default {
    
  props: {
    
    list: {
    
      type: Array,
      default: () => {
    
        return [];
      }
    }
  },
  methods: {
    
    clickItem(index) {
    
      this.$emit("change", index);
    }
  }
};
</script>

9c765e88e5565f0f57e3088b451f3007.png

在子组件中我们通过props对象定义了接收父组件值的类型和默认值,然后通过$emit()触发父组件中的自定义事件。prop/$emit传递数据的方式在日常开发中用的非常多,一般涉及到组件开发都是基于通过这种方式;通过父组件中注册子组件,并在子组件标签上绑定对自定义事件的监听。他的优点是传值取值方便简洁明了,但是这种方式的缺点是:

  1. 由于数据是单向传递,如果子组件需要改变父组件的props值每次需要给子组件绑定对应的监听事件。
  2. 如果父组件需要给孙组件传值,需要子组件进行转发,较为不便。

.sync修饰符

有些情况下,我们希望在子组件能够“直接修改”父组件的prop值,但是双向绑定会带来维护上的问题;vue提供了一种解决方案,通过语法糖.sync修饰符。

.sync修饰符在 vue1.x 的时候曾作为双向绑定功能存在,即子组件可以修改父组件中的值。但是它违反了单向数据流的设计理念,所以在 vue2.0 的时候被干掉了。但是在 vue2.3.0+ 以上版本又重新引入了。但是这次它只是作为一个编译时的语法糖存在。它会被扩展为一个自动更新父组件属性的v-on监听器。说白了就是让我们手动进行更新父组件中的值了,从而使数据改动来源更加的明显。

//Parent.vue
<template>
  <div>
    <Child :msg.sync="msg" :num.sync="num"></Child>
  </div>
</template>
<script>
import Child from "./child";
export default {
    
  name: "way2",
  components: {
    
    Child
  },
  data() {
    
    return {
    
      msg: "hello every guys",
      num: 0
    };
  }
};
</script>

我们在Child组件传值时给每个值添加一个.sync修饰,在编译时会被扩展为如下代码:

<Child :msg="msg" @update.msg="val => msg = val" :num.sync="num" @update.num="val => num = val"></Child>

因此子组件中只需要显示的触发update的更新事件:

//Child.vue
<template>
  <div>
    <div @click="clickRevert">点击更新字符串:{
    {
     msg }}</div>
    <div>当前值:{
    {
     num }}</div>
    <div @click="clickOpt('add')" class="opt">+</div>
    <div @click="clickOpt('sub')" class="opt">-</div>
  </div>
</template>
<script>
export default {
    
  props: {
    
    msg: {
    
      type: String,
      default: ""
    },
    num: {
    
      type: Number,
      default: 0
    }
  },
  methods: {
    
    clickRevert() {
    
      let {
     msg } = this;
      this.$emit("update:msg",msg.split("").reverse().join(""));
    },
    clickOpt(type = "") {
    
      let {
     num } = this;
      if (type == "add") {
    
        num++;
      } else {
    
        num--;
      }
      this.$emit("update:num", num);
    }
  }
};
</script>

2780993a7ed9e097c43e4e94131b8b1e.png

这种“双向绑定”的操作是不是看着似曾相识?是的,v-model本质上也是一种语法糖,只不过它触发的不是update方法而是input方法;而且v-model没有.sync来的更加灵活,v-model只能绑定一个值。

总结:.sync修饰符优化了父子组件通信的传值方式,不需要在父组件再写多余的函数来修改赋值。

$attrs和$listeners

当需要用到从A到C的跨级通信时,我们会发现prop传值非常麻烦,会有很多冗余繁琐的转发操作;如果C中的状态改变还需要传递给A,使用事件还需要一级一级的向上传递,代码可读性就更差

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值