乐趣区

关于前端:Vue-组件间传参的6种方式

思否上款式文本款式用不习惯,同步更新到本人的语雀,能够移步
https://www.yuque.com/diracke…

1、父组件通过属性值传递给子组件(子组件 props 接管),子组件 $emit 触发事件同时携带参数,父组件通过触发的事件绑定的回调函数传参接管子组件传递的参数。
父 -> 子 属性值传递。
// Father.vue
<div>
<children fill-color=”#ABC”/>
</div>

子 -> 父 子组件 $emit 触发事件,携带参数,父组件接管事件参数。
// Children.vue
<template>
<div>
<button @click=”eventExample”></button>
</div>
</template>

<script>
methods: {
eventExample(){
this.$emit(“successUpload”, [“1.jpg”,“2.jpg”]);
}
}
</script>

// Father.vue
<template>
<div>
<children @successUpload=”uploadImg”/>
</div>
</template>

<script>
methods: {
uploadImg(val) {

this.formData.imageList = val;
    // console.log(val); // [“1.jpg”,“2.jpg”]
}

}
</script>
留神:属性的名字如果用短横线连贯,传入子组件后 props 里的变量名主动变为小驼峰模式。

2、自定义组件应用 v -model(2.2.0+ 新增)
vue 默认的 v -model 常见于 input 标签上,v-model 的实质也是语法糖。
<template>
<input v-model=”message”></input>
<!– 下面的 v -model 就是上面:value 和 @input 的简写 –>
<input :value=”message” @input=”handleChange”></input>
</template>
<script>
methods: {
handleChange(e) {
this.message = e.target.value;
}
}
</script>
对下面的 input,v-model 是 value 属性和 input 事件的简写。对 raido、select、checkbox 等,v-model 都有对应的属性和事件。

上图来自官网 https://cn.vuejs.org/v2/guide…

如果须要自定义组件反对 v -model,须要为自定义组件配置一个 model 对象。
// Children.vue
<template>
<div>
<button @click=”eventExample”></button>
</div>
</template>
<script>
model: {
prop: “uploadImg”,
event: “imgListChange”
},
props: {
uploadImg: {
type: Array,
default: []
},
}
methods: {
eventExample(){
this.$emit(“imgListChange”, […this.newList]);
}
}
</script>
// Father.vue
<template>
<div>
<children v-model=”curImgList”/>
</div>
</template>

<script>
data() {
return {
curImgList:[]
}
}
</script>
v-model 只反对一个属性的传递,如果自定义的组件想要同时反对多个属性的双向绑定,那么能够用上面一种形式。(.sync)

3、.sync 修饰符(2.3.0+ 新增)
.sync 修饰符也是语法糖
<text-document :title.sync=”doc.title”></text-document>
<!– 下面的:title.sync 就是上面:title 和 @update:title 的简写 –>
<text-document :title=”doc.title” @update:title=”doc.title = $event” ></text-document>
这种写法须要在子组件中 $emit(“update:title”,value)来传值。

// Children.vue
<template>
<div>
<button @click=”eventExample”></button>
</div>
</template>
<script>
props: {
uploadImg: {
type: Array,
default: []
},
}
methods: {
eventExample(){
this.$emit(“updata:imgList”, […this.newList]);
}
}
</script>
// Father.vue
<template>
<div>
<children :upload-img.sync=”curImgList”/>
</div>
</template>

<script>
data() {
return {
curImgList:[]
}
}
</script>

4、vuex
这个很常见,不说。

5、vue 内置的高级属性 provide / inject(业务开发不举荐)

// ChildrenA.vue
<script>
data() {
return {
color:“skyblue”,
fontSize:“20px”
}
},
provide() {
return {

theme: {

color: this.color, // 这种写法 this.color 不是响应式
fontSize: this.fontSize,
}
},
}
</script>

// ChildrenE.vue
<template>
<div>
<h3 :style=”{color: theme.color}”>E </h3>
</div>
</template>

<script>
data() {
return {
}
},
inject() {
theme {
default: () => ({})
}
}
</script>
// ChildrenE.vue
<template>
<div>
<h3 :style=”{color: theme.color}”>E </h3>
</div>
</template>

<script>
data() {
return {
}
},
inject() {
theme1 {
from:“theme”, // 防止重名
default: () => ({})
}
}
</script>

官网倡议将 provide 和 inject 用于高阶插件 / 组件库开发,并不举荐间接用于利用程序代码中。
业务开发优先思考用 vuex 治理状态,因为 provide inject 会有一个相似冒泡的个性,数据源有可能在两头被“打断”,甚至是有可能被组件库中的组件打断,或者打断组件库中先人元素的 provide,不利于保护。

6、eventBus
次要用到两个办法,$emit 发送音讯,$on 接管音讯

// 发送音讯
EventBus.$emit(channel: string, callback(payload1,…))
// 监听接管音讯
EventBus.$on(channel: string, callback(payload1,…))

eventBus 非全局应用
// event-bus.js
import Vue from ‘vue’
export const EventBus = new Vue()

// A.vue
<template>
<button @click=”sendMsg()”>-</button>
</template>

<script>
import {EventBus} from “../event-bus.js”;
export default {
methods: {
sendMsg() {
EventBus.$emit(“aMsg”, ‘ 来自 A 页面的音讯 ’);
}
}
};
</script>

// B.vue
<template>
<p>{{msg}}</p>
</template>

<script>
import {EventBus} from “../event-bus.js”;
export default {
data(){
return {
msg: undefined
}
},
mounted() {
EventBus.$on(“aMsg”, (msg) => {
// A 发送来的音讯
this.msg = msg;
});
}
};
</script>

全局应用
// main.js
Vue.prototype.$eventBus = new Vue()

任意组件的办法中通过
this.$eventBus.$emit(‘nameOfEvent’, payloadData);
this.$eventBus.$on(‘nameOfEvent’, callback(payloadData));

退出移动版