在创建项目的时候,官方给出的页面,其实就给出了一个自定义的组件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
1.png3:父组件收到menu组件传递来的header显示标识,再将这个显示标识传递至header组件。显示header,如下图所示。
2.png上代码:我这里使用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: {},
};
以上代码最终执行效果:
最终代码实现效果:
3.gif更具体代码实现,请参考我的代码vue3代码库:https://gitee.com/camelliass/vue3blog
有好的建议,请在下方输入你的评论。
欢迎访问个人博客
https://guanchao.site
网友评论