在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>
本文原创,原创不易,如需转载,请联系作者授权。