Vue3<script setup>语法糖下,实现父子组件通信以及数据监听的三种方法。
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
在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>
本文原创,原创不易,如需转载,请联系作者授权。
GitHub 加速计划 / vu / vue
82
16
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:4 个月前 )
9e887079
[skip ci] 2 个月前
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 6 个月前
更多推荐
已为社区贡献2条内容
所有评论(0)