在創建項目的時候,官方給出的頁面,其實就給出了一個自定義的組件helloworld,里邊包含了父傳子傳值,VUEX的使用,計算屬性computed使用,方法的定義以及自定義組件的使用。
計算屬性computed和方法的定義,這里使用的並不是VUE3的新語法。
在《VUE3(八)setup與ref函數》這篇中,setup的第二個參數context對象為我們提供了可觸發事件emit,我們可以利用emit將子組件中的值傳遞給父組件。
我這里仍舊使用上一篇中使用的項目來做測試,多說一句,使用VITE來搭建的項目其實挺好用的,就現階段學習來說。文末會放上此次測試使用的代碼倉庫(碼雲)。
一:創建自定義組件以及使用
這個具體參照創建項目的時候給出的示例代碼就好了,示例寫的很清楚。
二:父組件使用prpos傳遞數據給子組件
Prpos官方文檔:
https://www.vue3js.cn/docs/zh/guide/component-props.html#prop-類型
我這里就不對語法多做解釋了,說一下我的設計思路
1:首先頁面加載的時候,父組件調用子組件,傳遞header顯示標識 false
2:點擊下圖紅框標注的按鈕,子組件向父組件傳遞header顯示標識 true
3:父組件收到menu組件傳遞來的header顯示標識,再將這個顯示標識傳遞至header組件。顯示header,如下圖所示。
上代碼:我這里使用Menu組件來做示例
Index.vue
<template >
<!-- 公共loading組件 -->
<load :loading=loading />
<div v-if="loading == false">
<!-- 公共標題組件 -->
<!-- VUE2.0語法,使用$refs 傳值 -->
<Header v-on:closeMenu="closeMenu" :show="showRef" />
<!-- <Header :show=showRef /> -->
<main id="main" >
<!-- 標題加動圖 -->
<!-- banner -->
<div class="preview" >
<!-- 公共導航組件 -->
<Menu v-on:showMenuByChild="showMenuByChild" :show="showRef" />
</div>
</main>
</div>
</template>
<style lang="scss" scoped>
@import "../../assets/css/pc/index.scss";
@import "../../assets/css/pc/public.scss";
</style>
<script lang="ts">
// 引入js文件
import index from "/@/assets/js/pc/index";
// 使用js對象
export default {
...index,
};
</script>
Index.ts
import {
PropType,
ref,
watch,
reactive,
toRefs,
getCurrentInstance,
provide,
inject,
onBeforeMount,// 在組件掛載之前執行的函數
onMounted,
onBeforeUpdate,// 在組件修改之前執行的函數
onUpdated,
onBeforeUnmount,// 在組件卸載之前執行的函數
onUnmounted,
nextTick
} from "vue";
// 引入axios鈎子
import axios from "/@/hooks/axios.ts";
// 引入路由
import { useRouter, useRoute } from "vue-router";
// 引入各個自定義組件
import Header from "/@/components/pc/Header.vue";
import Menu from "/@/components/pc/Menu.vue";
// 引入公共js文件
import utils from "/@/assets/js/public/function";
// 公共狀態文件
import { common } from "/@/hooks/common.ts";
export default {
name: "index",
components: {
Header,
Menu,
},
// VUE3 語法 第一個執行的鈎子函數
// setup官方文檔 :https://www.vue3js.cn/docs/zh/guide/composition-api-setup.html#參數
// setup(props: any, content: any) {
setup(props: any, content: any) {
const router = useRouter();
const route = useRoute()
//獲取上下文實例,ctx=vue2的this
// const { ctx,proxy } = getCurrentInstance();
/**
* @name: 聲明data
* @author: camellia
* @email: guanchao_gc@qq.com
* @date: 2021-01-10
*/
const data = reactive({
// 展示header
showRef: 0,
// loading 是否顯示
loading: true,
});
// ===================================================================
/**
* @name: 右上角菜單
* @author: camellia
* @email: guanchao_gc@qq.com
* @date: 2021-01-10
*/
const closeMenu = (param: number) => {
// param就是子組件傳過來的值
data.showRef = param;
}
/**
* @name: menu子組件傳遞來的值
* @author: camellia
* @email: guanchao_gc@qq.com
* @date: 2021-01-10
*/
const showMenuByChild = (param: number) => {
data.showRef = param;
}
/**
* @name: 將data綁定值dataRef
* @author: camellia
* @email: guanchao_gc@qq.com
* @date: 2021-01-10
*/
const dataRef = toRefs(data);
return {
showMenuByChild,
closeMenu,
...dataRef
}
},//*/
};
Menu.vue
<template>
<div class="preview_self" style="top:0px">
<!-- 菜單icon -->
<nav class="navbar navbar-menu " @click="showMenu()">
<img src="/@/assets/img/more.png" class="img_more" />
</nav>
</div>
</template>
<script lang="ts">
// 引入scss
import "/@/assets/css/components/pc/Menu.scss";
// 引入js文件
import Menu from "/@/assets/js/components/pc/Menu";
// 使用js對象
export default {
...Menu,
};
</script>
Menu.ts
import { useRouter } from "vue-router";
import {
PropType,
ref,
watch,
reactive,
toRefs,
inject,
provide
} from "vue";
import { common,userinfo } from "/@/hooks/common.ts";
/**
* @name: 定義返回的類型
* @author: camellia
* @email: guanchao_gc@qq.com
* @date: 2021-01-10 15:15:53
*/
interface dataRef {
showMenu: () => void;
jumPage: (str: string)=>void;
showSearch:()=>void;
showLogin:() => void;
}
export default {
name: "Menu",
/**
* @name: 父組件傳遞來的參數
* @author: camellia
* @email: guanchao_gc@qq.com
* @date: 2021-01-10
*/
props: {
show: {
// type: Boolean as PropType<boolean>,// 布爾類型
type: Number,// 數字類型
default: 0, // 默認值是0
},
},
// VUE3語法 setup函數
// setup官方文檔 :https://www.vue3js.cn/docs/zh/guide/composition-api-setup.html#參數
setup(props: any, content: any): dataRef {
const router = useRouter();
// let menuShow = inject('menuShow')
/**
* @name: 聲明data
* @author: camellia
* @email: guanchao_gc@qq.com
* @date: 2021-01-10
*/
const data = reactive({
// 菜單顯示標識
menuShow: 0,
// 是否登錄標識
is_login:userinfo.userid ? true : false,
// 用戶頭像
figureurl:'',
// 登錄框樣式
loginstyle: { },
});
/**
* @name: 監聽父組件傳過來的值變化
* @author: camellia
* @email: guanchao_gc@qq.com
* @date: 2021-01-10
*/
watch(
() => props.show,
(show: number) => {
data.menuShow = props.show
}
);
/**
* @name: 展示菜單
* @author: camellia
* @email: guanchao_gc@qq.com
* @date: 2021-01-10
*/
const showMenu = () => {
data.menuShow = 1;
// 子組件向父組件傳值
content.emit('showMenuByChild', data.menuShow);
// 菜單顯示標識(is_menu,is_search,is_login)
common.menuSign = 'is_menu';
};
/**
* @name: 將data綁定值dataRef
* @author: camellia
* @email: guanchao_gc@qq.com
* @date: 2021-01-10
*/
const dataRef = toRefs(data);
return { showMenu,
...dataRef
}
},
methods: {},
};
以上代碼最終執行效果:
最終代碼實現效果:
更具體代碼實現,請參考我的代碼vue3代碼庫:https://gitee.com/camelliass/vue3blog
有好的建議,請在下方輸入你的評論。
歡迎訪問個人博客
https://guanchao.site
歡迎訪問小程序: