在Vue的框架開發的項目過程中,經常會用到組件來管理不同的功能,有一些公共的組件會被提取出來。這時必然會產生一些疑問和需求?比如一個組件調用另一個組件作為自己的子組件,那么我們如何進行給子組件進行傳值呢?如果是電商網站系統的開發,還會涉及到購物車的選項,這時候就會涉及到非父子組件傳值的情況。當然你也可以用Vuex狀態管理工具來實現,這部分我們后續會單獨介紹。我先給大家介紹Vue開發中常用的三種傳值方式。
Vue常用的三種傳值方式有:
- 父傳子
- 子傳父
- 非父子傳值
引用官網的一句話:父子組件的關系可以總結為 prop 向下傳遞,事件向上傳遞。父組件通過 prop 給子組件下發數據,子組件通過事件給父組件發送消息,如下圖所示:!
image.png
接下來,我們通過實例來看可能會更明白一些:
1 父組件向子組件進行傳值
父組件:
<template>
<div id="app">
<!-- element 測試 -->
<form-test :title="titleVar"></form-test>
<k-button @lalala="handleClick"></k-button>
</div>
</template>
<script>
import FormTest from './components/FormTest.vue';
export default {
name: "app",
components: {
FormTest,
},
data() {
return {
titleVar:'element表單,rules校驗規則',
}
},
methods: {
handleClick(obj){
console.log(obj);
}
}
};
</script>
子組件FormTest:
<template>
<div>
<h3>{{title}}</h3>
</div>
</template>
<script>
export default {
props: {
title: { type: String, required: true }
},
data() {
return {
}
},
methods: {
}
};
</script>
這樣子組件里就可以拿到父組件傳過來的title的值‘element表單,rules校驗規則
2 子組件向父組件進行傳值(通過handleClick 函數)
父組件:
<template>
<div id="app">
<k-button @lalala="handleClick"></k-button>
</div>
</template>
<script>
import KButton from './components/Button.vue';
export default {
name: "app",
components: {
KButton,
},
data() {
return {
}
},
methods: {
handleClick(obj){
console.log(obj); //從子組件傳過來的值 {msg:'hello'}
}
}
};
</script>
子組件KButton:
<template>
<button @click="handleClick">子組件button</button>
</template>
<script>
export default {
methods: {
handleClick() {
this.$emit('lalala', {msg:'hello'})
}
},
}
</script>
這樣父組件里就可以拿到子組件傳過來的msg對象的值 {msg:'hello'}
3\這樣父組件里就可以拿到子組件傳過來的msg對象的值 {msg:'hello'}
非父子組件之間傳值,需要定義個公共的公共實例文件bus.js,作為中間倉庫來傳值,不然路由組件之間達不到傳值的效果。
- 3.1方式一,也是我自己使用的方式(推薦使用,簡單)
大概思路是 :在main.js,也就是入口文件中,我們在vue的原型上添加一個bus對象;
具體實現方式如下:
面的組件A和組件B可以是項目中任意兩個組件
下面的組件A和組件B可以是項目中任意兩個組件
- 3.2 方式二:稍微有點麻煩,但也很容易理解
大概的實現思路: 新建一個bus.js文件, 在這個文件里實例化一下vue;然后在組件A和組件B中分別引入這個bus.js文件,將事件監聽和事件觸發都掛到bus.js這個實例上,這樣就可以實現全局的監聽與觸發了
公共bus.js文件
//bus.js
import Vue from 'vue'
export default new Vue()
組件A:
<template>
<div>
A組件:
<span>{{elementValue}}</span>
<input type="button" value="點擊觸發" @click="elementByValue">
</div>
</template>
<script>
// 引入公共的bus,來做為中間傳達的工具
import Bus from './bus.js'
export default {
data () {
return {
elementValue: 4
}
},
methods: {
elementByValue: function () {
Bus.$emit('val', this.elementValue)
}
}
}
</script>
組件B:
<template>
<div>
B組件:
<input type="button" value="點擊觸發" @click="getData">
<span>{{name}}</span>
</div>
</template>
<script>
import Bus from './bus.js'
export default {
data () {
return {
name: 0
}
},
mounted: function () {
var vm = this
// 用$on事件來接收參數
Bus.$on('val', (data) => {
console.log(data)
vm.name = data
})
},
methods: {
getData: function () {
this.name++
}
}
}
</script>