Vue 组件传参的八种方式总结

摘要:
Vue组件传参的八种方式总结Vue组件的使用不管是在平常工作还是在面试面试中,都是频繁出现的。可以随意使用父组件传参的俩种方式第一种静态属性传参注意:在不定义props类型的情况下props接受到的均为String。它包含了父组件中的事件监听器三、$emit通知Vue默认有$on$emit$once$off几种方法来实现发布订阅模式,这也应用在了组件传参上。
Vue 组件传参的八种方式总结

Vue 组件的使用不管是在平常工作还是在面试面试中,都是频繁出现的。因此系统的梳理一下组件之间的传参还是非常有必要的

一、props 传参

子组件定义 props 有三种方式:

// 第一种数组方式
props: [xxx, xxx, xxx]
// 第二种对象方式
props: { xxx: Number, xxx: String}
// 第三种对象嵌套对象方式
props: {
    xxx: {
        //类型不匹配会警告
        type: Number,
        default: 0,
        required: true,
        // 返回值不是 true,会警告
        validator(val) { return val === 10}
    }
}
复制代码

第三种对象默认支持 4 种属性,并且都是非必填的。可以随意使用

父组件传参的俩种方式

第一种静态属性传参

注意:

  1. 在不定义 props 类型的情况下 props 接受到的均为 String。
  2. 当 props 属性指定为 Boolean 时,并且只有属性 key 没有值 value 时接受到的是 true
<!--props 接受到的均为 String -->
<children xxx="123"></children>

<!-- 有只有属性没有值, 这种情况 props 指定类型是 Boolean 则接收到的是 true -->
<children xxx></children>
复制代码

第二种动态属性传参

注意:

  1. 需要区分非简写形式传入的值是对象,则会对应 props 中多个值
  2. 会保留传入值的类型
  3. 如果是表达式则获取到的是表达式的计算结果
<!-- prop 接收到 Number 类型的 123-->
<children :xxx="123"></children>

<!-- prop 接收到 Array 类型的 [1, 2, 3]-->
<children v-bind:xxx="[1, 2, 3]"></children>

<!-- prop 会接收到 xxx1 和 xxx2 俩个参数。这种不支持简写形式-->
<children v-bind="{xxx1: 1, xxx2: 2}"></children>
复制代码
二、attrs 和listeners

$attrs

$attrs 会获取到 props 中未定义的属性(class 和 style 属性除外),支持响应式。常用的场景有俩种:

  1. 组件嵌套组件时可以使用 $attrs 来支持过多的属性支持。比如 elementUI 的 table 组件。支持的属性十几个,而平常封装的时候用的最多的也就一俩个。
  2. 属性默认是添加在父组件上的,有时候想把多余的属性添加在子组件上(可以结合 inheritAttrs: false 属性,让父属性不接受多余的属性)

$listeners定义的事件都在子组件的根元素上,有时候想加到其他元素上。就可以使用 $listerners。它包含了父组件中的事件监听器(除了带有 .native 修饰符的监听器)

三、$emit 通知

Vue 默认有 $on $emit $once $off 几种方法来实现发布订阅模式,这也应用在了组件传参上。在组件上添加的特殊方法 @abc="methods" 就相当于使用了 $on 来监听这个方法。因此组件内可以使用 $emit 来进行通知。

这里有一道考题: for 循环的时候如何拿到子组件的传值和 for 中循环的值

答案有俩种,一是 $event, 二是 闭包。只是需要注意 $event 只能获取到第一个值

<template v-for="item in [1, 2, 3]">
    <children @abc="((val, val2) => getValue(val, item))"></children>
</template>
复制代码
四、v-model

这个其实是一种通过emit,on 的组合方式。优点再于同步值方便,写法优雅。下面三种写法其实是一个意思

// 写法 1
<children v-model="a"></children>
{
    model: {
        prop: 'value',
        event: 'update:a',
    },
    methods: {
        a() { this.$emit('update:a', 1)}
    }
}

// 写法 2
<children :a="a" @update:a="a = $event"></children>
{
    props: ['a']
    methods: {
        a() { this.$emit('update:a', 1)}
    }
}
// 写法 3 
// 1. 事件名必须是 update: + 属性名
// 2. 参数不能是表达式,最好是 data 里面的属性
<children :a.sync="a"></children>
{
    props: ['a']
    methods: {
        a() { this.$emit('update:a', 1)}
    }
}
复制代码
五、插槽
<template>
    <div>
        <!--默认插槽-->
        <slot></slot>
        <!--另一种默认插槽的写法-->
        <slot name="default"></slot>
        <!--具名插槽-->
        <slot name="footer"></slot>
        <!--传参插槽-->
        <slot v-bind:user="user" name="header"></slot>
    </div>
</template>

<!--使用-->
<children>
    <!--跑到默认插槽中去-->
    <div>123</div>
    <!--另一种默认插槽的写法-->
    <template v-slot:default></template>
    <!--跑到具名插槽 footer 中去-->
    <template v-slot:footer></template>
    <!--缩写形式-->
    <template #footer></template>
    <!--获取子组件的值-->
    <template v-slot:header="slot">{{slot.user}}</template>
    <!--结构插槽值-->
    <template v-slot:header="{user: person}">{{person}}</template>
    <!--老式写法,可以写到具体的标签上面-->
    <template slot="footer" slot-scope="scope"></template>
</children>
复制代码
六、$refs, $root, $parent, $children
  1. $root 获取根组件
  2. $parent 获取父组件
  3. $children 获取子组件(所有的子组件,不保证顺序)
  4. $refs 组件获取组件实例,元素获取元素
七、project / inject

注意:注入的值是非响应的

<!--父组件 提供-->
{
    project() {
        return {
            parent: this
        }
    }
}
<!--子组件 注入-->
{
    // 写法一
    inject: ['parent']
    // 写法二
    inject: { parent: 'parent' }
    // 写法三
    inject: {
        parent: {
            from: 'parent',
            default: 222
        }
    }
}
复制代码
八、Vuex

这个相当于单独维护的一组数据,就不过多的说了。

免责声明:文章转载自《Vue 组件传参的八种方式总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mini2440 w35 制作开机logo 去除logo光标AFO下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

vue--渲染后修改数据不刷新

问题: 在使用 vue 进行开发的过程中,可能会遇到一种情况:当生成vue实例后,再次给数据赋值时,有时候并不会自动更新到视图上去。也就是如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。 vue遍历数组对象进行渲染 <div class="hisItem" v-for="(item,index) in historyNo...

vue配置请求转发解决跨域问题

通过nodejs的请求转发到后台,前端地址:http://localhost:8080 后端地址:http://localhost:8081 vue.config.js内容如下: let proxyObj={} proxyObj['/']={ //websocket ws:false, target:'http://localho...

循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合

循序渐进VUE+Element 前端应用开发的系列文章中,前面介绍了系统各个功能的处理实现,本篇随笔从一个主线上介绍前后端开发的整合,让我们从ABP框架后端的查询接口的处理,前端API接口调用的封装,以及前端Element界面的整个调用过程进行一个完整的介绍。 我们前面介绍了Vue+Element前端的接口是调用后端的ABP框架发布的API接口服务,API...

Vue-脚手架(一)

Vue脚手架:Vue-Cli,可方便快捷地开发完整地系统 通过 @vue/cli 实现的交互式的项目脚手架。 通过 @vue/cli + @vue/cli-service-global 实现的零配置原型开发。 一个运行时依赖 (@vue/cli-service),该依赖: 可升级; 基于 webpack 构建,并带有合理的默认配置; 可以通...

CKEditor5入门教程

下载CKEditor5 使用CK5原因 因为CK4的内联编辑与VUE不兼容 CK4-VUE可定制内容太少 所以选择CK5 但是在兼容性上 CK5 不如CK4 网上关于CKEditor教程实在太少 有用点个赞 下载地址:https://ckeditor.com/ckeditor-5/download/ 下载后的目录结构 现在尝试安装官方提供的数学公式插件和高...

Vue笔记(三):Components—slot

Solt - 内容分发 父组件模板的内容在父组件作用域内编译,子组件模板的内容在子组件作用域内编译。 组件的作用域相互独立,子组件中定义的数据只能在子组件模板内使用,父组件也如此。如果子组件想要使用父组件的数据,需要子组件定义 props 属性来实现。 为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板,这个过程被称为内容分发。Vue...