首页 > 其他 > 详细

680 vue3组件的通信:过props,$emit,非Prop的Attribute

时间:2021-06-06 16:25:45      阅读:35      评论:0      收藏:0      [点我收藏+]

组件的通信

技术分享图片


父子组件之间通信的方式

技术分享图片


父组件传递给子组件

技术分享图片


Props的数组用法

技术分享图片


Props的对象用法

技术分享图片


细节一:type的类型都可以是哪些呢?

技术分享图片


细节二:对象类型的其他写法

技术分享图片


细节三:Prop 的大小写命名

技术分享图片


非Prop的Attribute

技术分享图片


禁用Attribute继承和多根节点

技术分享图片


App.vue

<template>
  <div>
    <show-message id="abc" class="why" title="哈哈哈" content="我是哈哈哈哈" message-info=""></show-message>
    <show-message title="呵呵呵" content="我是呵呵呵呵"></show-message>
    <show-message :title="title" :content="content"></show-message>

    <show-message :title="message.title" :content="message.content"></show-message>
    <show-message v-bind="message"></show-message>

    <multi-root-element id="aaaa"></multi-root-element>
  </div>
</template>

<script>
  import ShowMessage from ‘./ShowMessage.vue‘;
  import MultiRootElement from ‘./MultiRootElement.vue‘;

  export default {
    components: {
      ShowMessage,
      MultiRootElement
    },
    data() {
      return {
        title: "嘻嘻嘻",
        content: "我是嘻嘻嘻嘻",
        message: {
          title: "嘿嘿嘿",
          content: "我是嘿嘿嘿"
        }
      }
    }
  }

  console.log()
</script>

<style scoped>
</style>

ShowMessage.vue

<template>
  <div>
    <h2 v-bind="$attrs">{{title}}</h2>
    <p>{{content}}</p>
  </div>
</template>

<script>
  export default {
    // props: [‘title‘, ‘content‘]
    inheritAttrs: false,
    props: {
      title: String,
      content: {
        type: String,
        required: true,
        default: "123"
      },
      counter: {
        type: Number
      },
      info: {
        type: Object,
        default() {
          return {name: "why"}
        }
      },
      messageInfo: {
        type: String
      }
    }
  }
</script>

<style scoped>
</style>

MultiRootElement.vue

<template>
  <h2>MultiRootElement</h2>
  <h2>MultiRootElement</h2>
  <h2 :id="$attrs.id">MultiRootElement</h2>
</template>

<script>
  export default {
    
  }
</script>

<style scoped>
</style>

子组件传递给父组件

技术分享图片


自定义事件的流程

技术分享图片


自定义事件的参数和验证

技术分享图片


App.vue

<template>
  <div>
    <h2>当前计数: {{ counter }}</h2>
    <counter-operation @add="addOne" @sub="subOne" @addN="addNNum"></counter-operation>
  </div>
</template>

<script>
import CounterOperation from ‘./CounterOperation.vue‘;

export default {
  components: {
    CounterOperation
  },
  data() {
    return {
      counter: 0
    }
  },
  methods: {
    addOne() {
      this.counter++
    },
    subOne() {
      this.counter--
    },
    addNNum(num, name, age) {
      console.log(name, age);
      this.counter += num;
    }
  }
}
</script>

<style scoped>
</style>

CounterOperation.vue

<template>
  <div>
    <button @click="increment">+1</button>
    <button @click="decrement">-1</button>
    <hr>
    <input type="text" v-model.number="num">
    <button @click="incrementN">+n</button>
  </div>
</template>

<script>
  export default {
    // 先注册
    emits: ["add", "sub", "addN"],
    // 对象写法的目的是为了进行参数的验证
    // emits: {
    //   add: null, // null表示不需要验证
    //   sub: null,
    //   addN: (num, name, age) => {
    //     console.log(num, name, age);
    //     if (num > 10) {
    //       return true
    //     }
    //     return false;
    //   }
    // },
    data() {
      return {
        num: 0
      }
    },
    methods: {
      increment() {
        console.log("+1");
        this.$emit("add");
      },
      decrement() {
        console.log("-1");
        this.$emit("sub");
      },
      incrementN() {
        this.$emit(‘addN‘, this.num, "why", 18);
      }
    }
  }

  new Array()
</script>

<style scoped>
/* CEBE8C  D8BE88  CEBE8E */
</style>

组件间通信案例练习

技术分享图片


App.vue

<template>
  <div>
    <tab-control :titles="titles" @titleClick="titleClick"></tab-control>
    <h2>{{contents[currentIndex]}}</h2>
  </div>
</template>

<script>
  import TabControl from ‘./TabControl.vue‘;

  export default {
    components: {
      TabControl
    },
    data() {
      return {
        titles: ["衣服", "鞋子", "裤子"],
        contents: ["衣服页面", "鞋子页面", "裤子页面"],
        currentIndex: 0
      }
    },
    methods: {
      titleClick(index) {
        this.currentIndex = index;
      }
    }
  }
</script>

<style scoped>
</style>

TabControl.vue

<template>
  <div class="tab-control">
    <div class="tab-control-item" 
         :class="{active: currentIndex === index}"
         v-for="(title, index) in titles" 
         :key="title"
         @click="itemClick(index)">
      <span>{{title}}</span>
    </div>
  </div>
</template>

<script>
const 
  export default {
    emits: ["titleClick"],
    props: {
      titles: {
        type: Array,
        default() {
          return []
        }
      }
    },
    data() {
      return {
        currentIndex: 0
      }
    },
    methods: {
      itemClick(index) {
        this.currentIndex = index;
        this.$emit("titleClick", index);
      }
    }
  }
</script>

<style scoped>
  .tab-control {
    display: flex;
  }

  .tab-control-item {
    flex: 1;
    text-align: center;
  }

  .tab-control-item.active {
    color: red;
  }

  .tab-control-item.active span {
    border-bottom: 3px solid red;
    padding: 5px 10px;
  }
</style>


680 vue3组件的通信:过props,$emit,非Prop的Attribute

原文:https://www.cnblogs.com/jianjie/p/14855345.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!