阅读 394

vue组件传参的八种方式

① props传参

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

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

父组件传参:

静态属性传参 1.  在不定义 props 类型的情况下 props 接受到的均为 String。 <children xxx="123"></children> 2.  当 props 属性指定为 Boolean 时,并且只有属性 key 没有值 value 时接受到的是 true -- 有只有属性没有值, 这种情况 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 会获取到 props 中未定义的属性(class 和 style 属性除外),支持响应式 常用的场景有俩种 1.组件嵌套组件时可以使用 $attrs 来支持过多的属性支持。比如 elementUI 的 table 组件。支持的属性十几个,而平常封装的时候用的最多的也就一俩个。 2.属性默认是添加在父组件上的,有时候想把多余的属性添加在子组件上(可以结合 inheritAttrs: false 属性,让父属性不接受多余的属性) $listener 包含了父作用域中的 (不含 `.native` 修饰器的) `v-on` 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。 简单点讲它是一个对象,里面包含了作用在这个组件上所有的监听器(监听事件),可以通过 v-on="$listeners" 将事件监听指向这个组件内的子元素(包括内部的子组件)。 下面是例子     <div id="app">       <child1         :p-child1="child1"         :p-child2="child2"         :p-child-attrs="1231"         v-on:test1="onTest1"         v-on:test2="onTest2">       </child1>     </div>       Vue.component("Child1", {         inheritAttrs: true,         props: ["pChild1"],         template: `         <div>         <p>in child1:</p>         <p>props: {{pChild1}}</p>         <p>$attrs: {{this.$attrs}}</p>         <hr>         <child2 v-bind="$attrs" v-on="$listeners"></child2></div>`,         mounted: function() {           this.$emit("test1");         }       });       Vue.component("Child2", {         inheritAttrs: true,         props: ["pChild2"],         template: `         <div>         <p>in child->child2:</p>         <p>props: {{pChild2}}</p>         <p>$attrs: {{this.$attrs}}</p>           <button @click="$emit('test2','按钮点击')">触发事件</button>         <hr> </div>`,         mounted: function() {           this.$emit("test2");         }       });       const app = new Vue({         el: "#app",         data: {           child1: "pChild1的值",           child2: "pChild2的值"         },         methods: {           onTest1() {             console.log("test1 running...");           },          onTest2(value) {             console.log("test2 running..." + value);           }         }       });  上例中,父组件在`child1`组件中设置两个监听事件`test1`和`test2`,分别在`child1`组件和`child1`组件内部的`child2`组件中执行。还设置了三个属性`p-child1`、`p-child2`、`p-child-attrs`。其中`p-child1`、`p-child2`被对应的组件的`prop`识别。所以:\ `p-child1`组件中`$attrs`为`{ "p-child2": "pChild2的值", "p-child-attrs": 1231 }`;\ `p-child2`组件中`$attrs`为`{ "p-child-attrs": 1231 }`。 再点击`child2`组件中的按钮,触发事件  控制台打印出 test2 running...按钮点击       复制代码

③ $emit 通知

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

④ v-model

// 写法 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> 复制代码

⑥ refs root parent children

组件获取组件实例,元素获取元素  根组件  父组件  子组件(所有的子组件,不保证顺序) 复制代码

⑦ project/inject 注入的值是非响应的

// 父组件 提供 project(){     return{         parent:this     } } //子组件 注入 inject: ['parent'] inject: { parent: 'parent' } inject: {     parent: {         from:"parent",         default:2     } }


作者:糖小雨
链接:https://juejin.cn/post/7019945353872932878

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐