• Vue前端框架11 组件事件与v-mode配合使用、组件数据传递(父传子)、插槽Slot、具名插槽、插槽中的数据传递(双向)


    一、组件事件与v-model配合使用

    组件A的数据变化
    组件B可以实时显示

    <template>
      <h3>Main</h3>
      <p>搜索内容为:{{search}}</p>
      <component-b @searchEvent="getSearch"></component-b>
    </template>
    
    <script>
    import ComponentB from "@/components/componentB";
    export default {
      name: "componentA",
      components: {ComponentB},
      data(){
        return{
          search:""
        }
      },
      methods:{
        getSearch(data){
          this.search=data
        }
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    <template>
      搜索: <input type="text" v-model="search">
    </template>
    
    <script>
    export default {
      name: "componentB",
      data(){
        return{
          search:""
        }
      },
      //侦听器
      watch:{
        search(newvValue,oldValue){
          console.log(oldValue)
          this.$emit("searchEvent",newvValue)
        }
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    二、组件数据传递(子传父)

    利用父组件的函数回调

    <template>
      <h3>Main</h3>
      <p>搜索内容为:{{search}}</p>
      <component-b @searchEvent="getSearch" :onEvent="dataFn"></component-b>
      <p>this:{{message}}</p>
    </template>
    
    <script>
    import ComponentB from "@/components/componentB";
    export default {
      name: "componentA",
      components: {ComponentB},
      data(){
        return{
          search:"",
          message:""
        }
      },
      methods:{
        getSearch(data){
          this.search=data
        },
        dataFn(data){
          this.message=data
        }
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    <template>
      搜索: <input type="text" v-model="search">
      <p>{{onEvent(age)}}</p>
    </template>
    
    <script>
    export default {
      name: "componentB",
      data(){
        return{
          search:"",
          age:22
        }
      },
      //侦听器
      watch:{
        search(newvValue,oldValue){
          console.log(oldValue)
          this.$emit("searchEvent",newvValue)
        }
      },props:{
        onEvent:Function
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    三、插槽Slots

    解决的是组件传输一个完整的html结构 也就是一个模板内容

    <template>
      <parent-demo></parent-demo>
      <component-a></component-a>
      <slot-demo>
        <div>
          <h3>插槽标题</h3>
    <!--      插槽内容不是写死的 而是动态的-->
          <p>{{ message }}</p>
        </div>
      </slot-demo>
    </template>
    
    <script>
    
    
    import ParentDemo from "@/components/parentDemo";
    import ComponentA from "@/components/componentA";
    import SlotDemo from "@/components/slotDemo";
    export default {
      name: 'App',
      components: {SlotDemo, ComponentA, ParentDemo},
      data(){
        return{
          message:"hello"
        }
      }
    }
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    <template>
      <h3>插槽基础知识</h3>
    <!--  slot 是一个插槽的出口 标示了 父元素提供的插槽内容将要在哪里被渲染 -->
    <!--  如果没有传插槽 在标签中间的内容 就是默认值-->
      <slot>插槽默认值</slot>
    </template>
    
    <script>
    export default {
      name: "slotDemo"
    }
    </script>
    
    <style scoped>
    
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    四、具名插槽

    <template>
      <parent-demo></parent-demo>
      <component-a></component-a>
      <slot-demo>
    <!--   通过template中的 v-slot属性 和 slot标签的 name对应 -->
    <!--    v-slot的简写 可以 简写为# -->
        <template v-slot:header>
          <h3>插槽标题</h3>
        </template>
        <template #main>
          <p>{{ message }}</p>
        </template>
    
      </slot-demo>
    </template>
    
    <script>
    
    
    import ParentDemo from "@/components/parentDemo";
    import ComponentA from "@/components/componentA";
    import SlotDemo from "@/components/slotDemo";
    export default {
      name: 'App',
      components: {SlotDemo, ComponentA, ParentDemo},
      data(){
        return{
          message:"hello"
        }
      }
    }
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    <template>
      <h3>插槽基础知识</h3>
    <!--  slot 是一个插槽的出口 标示了 父元素提供的插槽内容将要在哪里被渲染 -->
    <!--  如果没有传插槽 在标签中间的内容 就是默认值-->
      <slot name="header">插槽默认值</slot>
      <hr>
      <slot name="main"></slot>
    </template>
    
    <script>
    export default {
      name: "slotDemo"
    }
    </script>
    
    <style scoped>
    
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    五、插槽中的数据传递

    在某些情况下,插槽的内容可能同时需要用到父子两个组件的数据,所以需要方法将子组件在渲染时候将一部分数据提供给插槽

    <template>
      <parent-demo></parent-demo>
      <component-a></component-a>
      <slot-demo>
    <!--   通过template中的 v-slot属性 和 slot标签的 name对应 -->
    <!--    v-slot的简写 可以 简写为# -->
        <template v-slot:header>
          <h3>插槽标题</h3>
        </template>
        <template #main>
          <p>{{ message }}</p>
        </template>
      </slot-demo>
    
      <SlotAttr>
    <!--    建议指明对应的插槽名称-->
        <template v-slot:main="slotProps">
          <p>{{currentTest}}</p>
          <p>{{slotProps.msg}}</p>
        </template>
      </SlotAttr>
    </template>
    
    <script>
    
    
    import ParentDemo from "@/components/parentDemo";
    import ComponentA from "@/components/componentA";
    import SlotDemo from "@/components/slotDemo";
    import SlotAttr from "@/components/slotAttr";
    export default {
      name: 'App',
      components: {SlotAttr, SlotDemo, ComponentA, ParentDemo},
      data(){
        return{
          message:"hello",
          currentTest:"测试内容"
        }
      }
    }
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    <template>
      <h3>插槽plus</h3>
    <!--  子元素的数据想要显示 则需要将数据传给父元素
          父元素接收后和父元素原本的内容 一起传给子元素
    -->
      <slot :msg="childMessage" name="main">
    
      </slot>
    </template>
    
    <script>
    export default {
      name: "slotAttr",
      data(){
        return{
          childMessage:"子组件数据"
        }
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    Android Studio 导出JavaDoc文档
    跟艾文学编程《Python基础》PyCharm 安装
    Docker V24 及 Docker Compose V2 的安装及使用
    前端论坛项目(九)------如何实现UserProfileInfo里面的关注按钮
    Java - 缓冲输入输出流 (BufferedInputStream、BufferedOutputStream)
    山西电力市场日前价格预测【2023-09-12】
    ffmpeg之去除视频水印
    vue3 + typescript + vite + naive ui + tailwindcss + jsx 仿苹果桌面系统
    LeetCode 42. 接雨水
    LeetCode - 搜索二维矩阵
  • 原文地址:https://blog.csdn.net/Wantfly9951/article/details/132863365