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

简介: 在创建项目的时候,官方给出的页面,其实就给出了一个自定义的组件helloworld,里边包含了父传子传值,VUEX的使用,计算属性computed使用,方法的定义以及自定义组件的使用。计算属性computed和方法的定义,这里使用的并不是VUE3的新语法。在《VUE3(八)setup与ref函数》这篇中,setup的第二个参数context对象为我们提供了可触发事件emit,我们可以利用emit将子组件中的值传递给父组件。

QQ图片20220423171716.jpg

在创建项目的时候,官方给出的页面,其实就给出了一个自定义的组件helloworld,里边包含了父传子传值,VUEX的使用,计算属性computed使用,方法的定义以及自定义组件的使用。


计算属性computed和方法的定义,这里使用的并不是VUE3的新语法。


在《VUE3(八)setup与ref函数》这篇中,setup的第二个参数context对象为我们提供了可触发事件emit,我们可以利用emit将子组件中的值传递给父组件。


我这里仍旧使用上一篇中使用的项目来做测试,多说一句,使用VITE来搭建的项目其实挺好用的,就现阶段学习来说。文末会放上此次测试使用的代码仓库(码云)。


一:创建自定义组件以及使用


这个具体参照创建项目的时候给出的示例代码就好了,示例写的很清楚。


二:父组件使用prpos传递数据给子组件


Prpos官方文档:

www.vue3js.cn/docs/zh/gui…


我这里就不对语法多做解释了,说一下我的设计思路


1:首先页面加载的时候,父组件调用子组件,传递header显示标识 false


2:点击下图红框标注的按钮,子组件向父组件传递header显示标识 true


QQ图片20220423171720.png


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


QQ图片20220423171723.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: {},
};


以上代码最终执行效果:


最终代码实现效果:


QQ图片20220423171726.png


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



目录
相关文章
|
22天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
126 64
|
22天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
28 8
|
21天前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
21 1
|
21天前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
32 1
|
25天前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
27天前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
|
1天前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
28天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
32 1
vue学习第一章
|
28天前
|
JavaScript 前端开发 索引
vue学习第三章
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中的v-bind指令,包括基本使用、动态绑定class及style等,希望能为你的前端学习之路提供帮助。持续关注,更多精彩内容即将呈现!🎉🎉🎉
26 1
vue学习第三章
|
28天前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
35 1
vue学习第四章