VUE3(十一)自定义组件子父传值

在创建项目的时候,官方给出的页面,其实就给出了一个自定义的组件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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rttw6WwG-1615184295073)(https://resource.guanchao.site/ueditor/php/upload/image/20210304/1614824136410471.png#pic_center)]

3:父组件收到menu组件传递来的header显示标识,再将这个显示标识传递至header组件。显示header,如下图所示。

22.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: [email protected]
         * @date: 2021-01-10 
         */
        const data = reactive({
    
    
            // 展示header
            showRef: 0,
            // loading 是否显示
            loading: true,
        });
 
        // ===================================================================
        /**
         * @name: 右上角菜单
         * @author: camellia
         * @email: [email protected]
         * @date: 2021-01-10 
         */
        const closeMenu = (param: number) => {
    
    
            // param就是子组件传过来的值
            data.showRef = param;
        }
/**
         * @name: menu子组件传递来的值
         * @author: camellia
         * @email: [email protected]
         * @date: 2021-01-10 
         */
        const showMenuByChild = (param: number) => {
    
    
            data.showRef = param;
        }
        /**
         * @name: 将data绑定值dataRef
         * @author: camellia
         * @email: [email protected]
         * @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: [email protected]
 * @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: [email protected]
   * @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: [email protected]
     * @date: 2021-01-10 
     */
    const data = reactive({
    
    
      // 菜单显示标识
      menuShow: 0,
      // 是否登录标识
      is_login:userinfo.userid ? true : false,
      // 用户头像
      figureurl:'',
      // 登录框样式
      loginstyle: {
    
     },
 
    });
    /**
     * @name: 监听父组件传过来的值变化
     * @author: camellia
     * @email: [email protected]
     * @date: 2021-01-10 
     */
    watch(
      () => props.show,
      (show: number) => {
    
    
        data.menuShow = props.show
      }
    );
 
    /**
     * @name: 展示菜单
     * @author: camellia
     * @email: [email protected]
     * @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: [email protected]
     * @date: 2021-01-10 
     */
    const dataRef = toRefs(data);
    return {
    
          showMenu, 
      ...dataRef
    }
  },
 
  methods: {
    
    },
};

以上代码最终执行效果:

最终代码实现效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9UAKtGIe-1615184430961)(https://resource.guanchao.site/ueditor/php/upload/image/20210304/1614824208835820.gif#pic_center)]

更具体代码实现,请参考我的代码vue3代码库:https://gitee.com/camelliass/vue3blog

有好的建议,请在下方输入你的评论。

欢迎访问个人博客
https://guanchao.site

欢迎访问小程序:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39708228/article/details/114529648
今日推荐