• Vue3<script setup>语法糖下,实现父子组件通信以及数据监听的三种方法。


    Vue3的script setup语法糖中,没有办法通过Vue2的ref、props、parent、中央时间总线等等众多方法,通过this指针简单的实现父子组件的通信,网络上也很少有关于script setup语法糖的相关教程,所以决定自己写一个详细教程,方便以后学习查看并记录。
    在这里插入图片描述

    一、通过defineProps()和watch()方法实现父子组件通信以及数据监听。

    1.父组件代码实例:props传值

    <script setup>
    import { ref } from 'vue';
    import { get_article_cates } from "@/api/api.js";
    import Article from "./article/index.vue";
    const cate_list=ref([]);
    const active = ref(0)
    const Cates=()=>{
        get_article_cates().then((res) => {
            cate_list.value=res.data.data;
        }).catch((err) => {
            console.log(err)
        })
    }
    Cates();
    const cates_id=ref();
    const go_cates=(data)=>{
        cates_id.value=data.id;
    };
    
    </script>
    
    <template>
        <div class="hu_box">
            <var-tabs v-model:active="active" color="rgba(255, 255, 255, 0.35)" active-color="#1e131d" inactive-color="#36292f" class="hu_tab">
                <var-tab v-for="(item,index) in cate_list" @click="go_cates(item)">{{item.name}}</var-tab>
            </var-tabs>
            <div class="hu_index">
                <Article :cates_id="cates_id" />
            </div>
        </div>
    </template>
    
    • 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

    2.子组件代码实例:defineProps()方法获取父组件的值,watch()方法监听props的值

    <script setup>
    import { ref, watch } from 'vue';
    import { post_articles_list,get_article_details } from "@/api/api.js";
    const Art_list=ref([]);
    
    //子组件相关方法
    let query={
        classifyID: '',
        page: 1,
        pagesize: 5 
    }
    const Articles_list=()=>{
        post_articles_list(query).then((res) => {
            Art_list.value=res.data.data;
        }).catch((err) => {
            console.log(err)
        });
    }
    
    //通信部分方法
    //传入props数据
    const props = defineProps({
        cates_id: String
    })
    if (props.cates_id==undefined) {
        Articles_list();
    }
    //数据监听
    watch(() => props.cates_id, (newValue, oldValue) => {
      query.classifyID=newValue;
      Articles_list();
    },{ deep: true });
    </script>
    
    <template>
        <div class="hu_article">
            <div class="hu_son_box" v-for="(item,index) in Art_list" :key="index" @click="go_router(item.Id)">
                <div>{{ item.title }}</div>
                <div>{{ item.pub_date }}</div>
            </div>
        </div>
    </template>
    
    • 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

    二、通过defineProps()、watch()、ref()、defineExpose()方法实现父子组件通信以及数据监听。

    1.父组件代码实例:props传值、ref执行子组件方法

    <script setup>
    import { ref } from 'vue';
    import { get_article_cates } from "@/api/api.js";
    import Article from "./article/index.vue";
    const cate_list=ref([]);
    const active = ref(0)
    const Cates=()=>{
        get_article_cates().then((res) => {
            cate_list.value=res.data.data;
        }).catch((err) => {
            console.log(err)
        })
    }
    Cates();
    const cates_id=ref();
    const Son_subassembly = ref();
    const go_cates=(data)=>{
        cates_id.value=data.id;
        if (Son_subassembly.value) {
            Son_subassembly.value?.Articles_list();
        }
    };
    
    </script>
    
    <template>
        <div class="hu_box">
            <var-tabs v-model:active="active" color="rgba(255, 255, 255, 0.35)" active-color="#1e131d" inactive-color="#36292f" class="hu_tab">
                <var-tab v-for="(item,index) in cate_list" @click="go_cates(item)">{{item.name}}</var-tab>
            </var-tabs>
            <div class="hu_index">
                <Article :cates_id="cates_id" ref="Son_subassembly"/>
            </div>
        </div>
    </template>
    
    • 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

    2.子组件代码实例:defineProps()方法获取父组件的值,watch()方法监听props的值,defineExpose()暴露出子组件属性。

    <script setup>
    import { ref, watch } from 'vue';
    import { post_articles_list,get_article_details } from "@/api/api.js";
    const Art_list=ref([]);
    
    //子组件相关方法
    let query={
        classifyID: '',
        page: 1,
        pagesize: 5 
    }
    const Articles_list=()=>{
        post_articles_list(query).then((res) => {
            Art_list.value=res.data.data;
        }).catch((err) => {
            console.log(err)
        });
    }
    
    //通信部分方法
    //传入props数据
    const props = defineProps({
        cates_id: String
    })
    if (props.cates_id==undefined) {
        Articles_list();
    }
    //数据监听
    watch(() => props.cates_id, (newValue, oldValue) => {
      query.classifyID=newValue;
    },{ deep: true });
    //子组件实例暴露出属性:defineExpose
    defineExpose({
        Articles_list
    })
    </script>
    
    <template>
        <div class="hu_article">
            <div class="hu_son_box" v-for="(item,index) in Art_list" :key="index" @click="go_router(item.Id)">
                <div>{{ item.title }}</div>
                <div>{{ item.pub_date }}</div>
            </div>
        </div>
    </template>
    
    • 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
    • 45

    三、通过defineExpose()和pinia实现父子组件通信以及数据监听。

    1.安装pinia,新建stores文件夹,下面新建counter.js

    安装pinia
    npm install pinia
    
    • 1
    stores文件夹下新建counter.js
    import { ref, computed } from 'vue'
    import { defineStore } from 'pinia'
    
    export const useCounterStore = defineStore('counter',  {
      state: () => {
        return {
          Central_data: '',
        }
      },
      persist: true,
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.父组件代码实例:pinia传值、ref执行子组件方法

    <script setup>
    import { ref } from 'vue';
    import { get_article_cates } from "@/api/api.js";
    import Article from "./article/index.vue";
    
    //pinia通信测试
    import { useCounterStore } from "@/stores/counter.js";
    const store = useCounterStore();
    
    const cate_list=ref([]);
    const active = ref(0)
    const Cates=()=>{
        get_article_cates().then((res) => {
            cate_list.value=res.data.data;
        }).catch((err) => {
            console.log(err)
        })
    }
    Cates();
    const cates_id=ref();
    const Son_subassembly = ref();
    const go_cates=(data)=>{
    	cates_id.value=data.id;
        //pinia数据通信测试测试
        store.Central_data=data.id;
        if (Son_subassembly.value) {
            Son_subassembly.value?.Articles_list();
        }
    };
    
    </script>
    
    <template>
        <div class="hu_box">
            <var-tabs v-model:active="active" color="rgba(255, 255, 255, 0.35)" active-color="#1e131d" inactive-color="#36292f" class="hu_tab">
                <var-tab v-for="(item,index) in cate_list" @click="go_cates(item)">{{item.name}}</var-tab>
            </var-tabs>
            <div class="hu_index">
                <Article :cates_id="cates_id" ref="Son_subassembly"/>
            </div>
        </div>
    </template>
    
    • 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

    3.子组件代码实例:pinia获取父组件的值,defineExpose()暴露出子组件属性。

    <script setup>
    import { ref, watch } from 'vue';
    import { post_articles_list,get_article_details } from "@/api/api.js";
    const Art_list=ref([]);
    
    import { useCounterStore } from "@/stores/counter.js";
    const store = useCounterStore();
    
    //子组件相关方法
    let query={
        classifyID: '',
        page: 1,
        pagesize: 5 
    }
    const Articles_list=()=>{
    	query.classifyID=store.Central_data
        post_articles_list(query).then((res) => {
            Art_list.value=res.data.data;
        }).catch((err) => {
            console.log(err)
        });
    }
    
    //通信部分方法
    //传入props数据
    const props = defineProps({
        cates_id: String
    })
    if (props.cates_id==undefined) {
        Articles_list();
    }
    
    //子组件实例暴露出属性:defineExpose
    defineExpose({
        Articles_list
    })
    </script>
    
    <template>
        <div class="hu_article">
            <div class="hu_son_box" v-for="(item,index) in Art_list" :key="index" @click="go_router(item.Id)">
                <div>{{ item.title }}</div>
                <div>{{ item.pub_date }}</div>
            </div>
        </div>
    </template>
    
    • 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
    • 45
    • 46

    本文原创,原创不易,如需转载,请联系作者授权。

  • 相关阅读:
    【Java】之集合大总结(下)
    Linux的TCP连接问题解决调优观察
    [模电课程设计]基于TCP7107的数字式温度计设计
    低代码平台选型时,要注意哪些?
    红黑树的插入(C++实现)
    Opencv项目实战:16 虚拟拖拽系统
    Java - SpringBoot整合Shiro之二(权限授权和认证跳过)
    windows安装ElasticSearch
    MyBatis
    Dubbo面试题(总结最全面的面试题)
  • 原文地址:https://blog.csdn.net/qq_36034945/article/details/133822610