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


    组件的通信


    父子组件之间通信的方式


    父组件传递给子组件


    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>
    
        <!-- 补充 -->
        <!-- 写成小驼峰personalInfo 也是可以的 -->
        <!-- <show-message :personalInfo="personalInfo"></show-message> -->
        <!-- <show-message :personal-info="personalInfo"></show-message> -->
      </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>
    


  • 相关阅读:
    微分中值定理和泰勒展开
    Burnside引理与Polya定理
    递推关系和母函数
    cogs 1361. 树 线段树
    cogs 247. 售票系统 线段树
    cogs 176. [USACO Feb07] 奶牛聚会 dijkstra
    cogs 1672. [SPOJ 375] 难存的情缘 树链剖分套线段树 易错! 全博客园最长最详细的题解
    cogs 886. [USACO 4.2] 完美的牛栏 二分图 匈牙利算法
    cogs 1254. 最难的任务 Dijkstra + 重边处理
    cogs 364. [HDU 1548] 奇怪的电梯 Dijkstra
  • 原文地址:https://www.cnblogs.com/jianjie/p/14855345.html
Copyright © 2020-2023  润新知