Bootstrap

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

在Vue3的script setup语法糖中,没有办法通过Vue2的ref、props、parent、中央事件总线(bus)等等众多方法,通过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>

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>

二、通过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>

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>

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

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

安装pinia
npm install pinia
stores文件夹下新建counter.js
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter',  {
  state: () => {
    return {
      Central_data: '',
    }
  },
  persist: true,
})

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>

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>

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

;