Vue傳參一籮筐(頁(yè)面、組件)
Vue頁(yè)面、組件之間傳參方式繁多,此處羅列出常用的幾種方式,歡迎審閱補(bǔ)充。
一丶路由傳參
這里的路由傳參以編程式 router.push(...) 為例,聲明式 <router-link :to="..."> 與之類(lèi)似。此處模擬情景為從 componentsA.vue 頁(yè)面跳轉(zhuǎn)到 componentsB.vue 頁(yè)面?zhèn)鲄ⅰJ紫?,路由配置信息如下?/p>
router.js
import Vue from 'vue'
import Router from 'vue-router'
import componentsA from './components/componentsA' //在components下創(chuàng)建componentsA.vue
import componentsB from './components/componentsB' //在components下創(chuàng)建componentsB.vue
Vue.use(Router)
export default new Router({
routes:[
{
path:'/componentsA',
name:'componentsA',
component:componentsA
},
{
path:'/componentsB',
name:'componentsB',
component:componentsB
}
]
})
1.1 路由配置傳參
首先確定自己要傳的參數(shù)名,將路由配置修改一下,傳name,age,sex三個(gè)參數(shù):
{
path:'/componentsB/:name/:age/:sex',
name:'componentsB',
component:componentsB
}
在 componentsA.vue 頁(yè)面通過(guò) this.$router.push 配置與之對(duì)應(yīng)的參數(shù):
componentsA.vue
<template>
<div>
<div>我是組件A</div>
<button @click='routerToB1'>方式一跳轉(zhuǎn)到組件B</button>
</div>
</template>
<script>
export default{
data(){
return{
person:{name:'Gene',age:'18',sex:'male'}
}
},
methods: {
routerToB1() {
this.$router.push({
path:`componentsB/${this.person.name}/${this.person.age}/${this.person.sex}`
})
}
},
}
</script>
<style>
</style>
然后在 componentsB.vue 頁(yè)面用 this.$route.params 接收參數(shù):
componentsB.vue
<template>
<div>
<div>我是組件B</div>
</div>
</template>
<script>
export default{
created(){
this.getRouterData()
},
methods: {
getRouterData(){
const param = this.$route.params
console.log(param)//{name:'Gene',age:'18',sex:'male'}
}
},
}
</script>
<style>
</style>
點(diǎn)擊按鈕"方式一跳轉(zhuǎn)到組件B",componentsB頁(yè)面打印出 {name:'Gene',age:'18',sex:'male'} ,成功獲取到A頁(yè)面?zhèn)鬟^(guò)來(lái)的參數(shù),并且地址欄顯示為 localhost:8889/#/componentsB/Gene/18/male (端口號(hào)根據(jù)自己設(shè)置的來(lái)),表明這種傳參方式url會(huì)攜帶參數(shù)。
1.2 params傳參
首先將剛才路由配置修改部分還原,在 componentsA.vue 頁(yè)面添加按鈕"方式二跳轉(zhuǎn)到組件B":
componentsA.vue
<template> <div> <div>我是組件A</div> <button @click='routerToB1'>方式一跳轉(zhuǎn)到組件B</button> <button @click='routerToB2'>方式二跳轉(zhuǎn)到組件B</button> </div> </template>
在 methods 中添加方法 routerToB2 ,使用路由屬性 name 來(lái)確定匹配的路由,使用屬性 params 來(lái)傳遞參數(shù):
componentsA.vue
routerToB2(){
this.$router.push({
name:'componentsB',
params:{
exa:'我是傳到組件B的參數(shù)'
}
})
},
componentsB.vue 保持不變,params傳參方式獲取參數(shù)也是通過(guò) this.$route.params ,點(diǎn)擊A頁(yè)面新添加的按鈕"方式二跳轉(zhuǎn)到組件B",在B頁(yè)面打印出 {exa: "我是傳到組件B的參數(shù)"} ,傳參成功,地址欄為 localhost:8889/#/componentsB ,表明這種方式url不會(huì)攜帶參數(shù)。
1.3 query傳參
這種方式和params傳參方式類(lèi)似,在 componentsA.vue 頁(yè)面繼續(xù)添加按鈕"方式三跳轉(zhuǎn)到組件B":
componentsA.vue
<template> <div> <div>我是組件A</div> <button @click='routerToB1'>方式一跳轉(zhuǎn)到組件B</button> <button @click='routerToB2'>方式二跳轉(zhuǎn)到組件B</button> <button @click='routerToB3'>方式三跳轉(zhuǎn)到組件B</button> </div> </template>
在 methods 中添加方法 routerToB3 ,使用路由屬性 name 或者 path 來(lái)確定匹配的路由,使用屬性 query 來(lái)傳參:
componentsA.vue
routerToB3(){
this.$router.push({
name:'componentsB',// path:'/componentsB'
query:{
que:'我是通過(guò)query傳到組件B的參數(shù)'
}
})
}
在 componentsB.vue 頁(yè)面通過(guò) this.$route.query 來(lái)獲取參數(shù):
componentsB.vue
getRouterData(){
const query = this.$route.query
console.log(query)//{que: "我是通過(guò)query傳到組件B的參數(shù)"}
}
查看地址欄為 localhost:8889/#/componentsB?que=我是通過(guò)query傳到組件B的參數(shù) ,顯然這種方式url會(huì)攜帶參數(shù)。
1.4 小結(jié)
- 路由配置傳參注意書(shū)寫(xiě)格式
/:id,獲取參數(shù)都是通過(guò)$route而不是$router params傳參和query傳參區(qū)別類(lèi)似于post和get方法。params傳參地址欄不會(huì)顯示參數(shù),而query傳參會(huì)將參數(shù)顯示在地址欄中params傳參刷新頁(yè)面參數(shù)會(huì)丟失,另外兩種不會(huì)params傳參對(duì)應(yīng)的路由屬性是name,而query傳參對(duì)應(yīng)的路由屬性既可以是name,也可以是path
二丶使用緩存
緩存方式即通過(guò) sessionStorage 、 localStorage 、 Cookie 方式傳參,這種方式和是不是用Vue無(wú)關(guān),因此,不談。
三丶父子組件之間傳值
在components目錄下創(chuàng)建父組件 parent.vue 和子組件 children.vue ,在父組件中引入子組件。為了演示方便,在路由配置中加入 /parent 路徑。
3.1 父組件向子組件傳值 props
在 parent.vue 的子組件標(biāo)簽上注冊(cè)message1,在 children.vue 中通過(guò) props 接收message1,如果傳遞的值為變量,則使用 v-bind: 或直接用 : ,參考如下:
parent.vue
<template>
<div>
<div>我是父組件</div>
<children message1='我是直接參數(shù)' v-bind:message2='msg' :message3='obj'></children>
</div>
</template>
<script>
import Children from './children'
export default{
components:{
Children
},
data(){
return{
msg:'我是父組件的參數(shù)'
}
},
created(){
this.obj = {a:'1',b:'2',c:'3'}
}
}
</script>
<style>
</style>
children.vue
<template>
<div>
<div>我是子組件</div>
<div>{{message1}}</div>
<div>{{message2}}</div>
<div>{{message3}}</div>
</div>
</template>
<script>
export default{
props:['message1','message2','message3'],
created(){
console.log(this.message3)
}
}
</script>
<style>
</style>
在瀏覽器中打開(kāi):

3.2 子組件向父組件傳值 $emit
子組件通過(guò)vm.$emit( event, […args] ),觸發(fā)當(dāng)前實(shí)例上的事件。附加參數(shù)都會(huì)傳給監(jiān)聽(tīng)器回調(diào)。父組件在子組件標(biāo)簽上監(jiān)聽(tīng)事件獲得參數(shù)。
children.vue
<template>
<div style="margin-top: 100px;">
<div>我是子組件</div>
<div>{{message1}}</div>
<div>{{message2}}</div>
<div>{{message3}}</div>
<button @click='ChildToParent'>點(diǎn)我傳愛(ài)</button>
</div>
</template>
<script>
export default{
props:['message1','message2','message3'],
data(){
return{
loud:'I love xx'
}
},
methods:{
ChildToParent(){
this.$emit('emitToParent',this.loud)
}
},
created(){
console.log(this.message3)
}
}
</script>
<style>
</style>
parent.vue
<template>
<div>
<div>我是父組件</div>
<div>大聲告訴我你愛(ài)誰(shuí):{{loveWho}}</div>
<children @emitToParent='parentSayLove' message1='我是直接參數(shù)' v-bind:message2='msg' :message3='obj'></children>
</div>
</template>
<script>
import Children from './children'
export default{
components:{
Children
},
data(){
return{
msg:'我是父組件的參數(shù)',
loveWho:''
}
},
methods:{
parentSayLove(data){
this.loveWho = data
}
},
created(){
this.obj = {a:'1',b:'2',c:'3'}
}
}
</script>
<style>
</style>
點(diǎn)擊按鈕瀏覽器顯示:

3.3 小結(jié)
props 可以是字符串?dāng)?shù)組,也可以是對(duì)象(可以類(lèi)型驗(yàn)證、設(shè)置默認(rèn)值等) ;
使用 .native 修飾監(jiān)聽(tīng)事件,開(kāi)發(fā)中使用了 element-ui 的框架標(biāo)簽時(shí)候,使用事件綁定無(wú)效。這時(shí)候需要使用 .native 修飾 v-on:event ,可以在框架標(biāo)簽或組件的根元素 上監(jiān)聽(tīng)一個(gè)原生事件,例如 <my-component v-on:click.native="doTheThing"></my-component> 。
四丶非父子(兄弟)組件之間傳值
非父子組件之間傳值,需要定義公共實(shí)例文件 bus.js ,作為中間倉(cāng)庫(kù)來(lái)傳值,不然路由組件之間達(dá)不到傳值的效果。在components目錄下新建 first.vue 和 second.vue 以及公共文件 bus.js 。
bus.js
import Vue from 'vue' export default new Vue()
在 first.vue 和 second.vue 中分別引入bus.js。
import Bus from '../bus.js'
模擬情景: first.vue 向 second.vue 傳值。在 first.vue 通過(guò)在事件中添加 Bus.$emit( event, […args] ) 進(jìn)行傳值,在 second.vue 中通過(guò) Bus.$on(event,callBack) 進(jìn)行監(jiān)聽(tīng)。
first.vue
<template>
<div>
<div>我是first.vue</div>
<button @click="firstToSecond">點(diǎn)擊傳值給second.vue</button>
</div>
</template>
<script>
import Bus from '../bus.js'
export default{
data(){
return{
msg:'我是first.vue傳到second.vue的參數(shù)'
}
},
methods:{
firstToSecond(){
Bus.$emit('emitToSecond',this.msg)
}
}
}
</script>
<style>
</style>
second.vue
<template>
<div>
<div>我是second.vue</div>
{{info}}
</div>
</template>
<script>
import Bus from '../bus.js'
export default{
data(){
return{
info:''
}
},
mounted(){
const that = this;
Bus.$on('emitToSecond',function(data){
that.info = data
})
}
}
</script>
<style>
</style>
點(diǎn)擊按鈕,瀏覽器中顯示:

小結(jié)
兄弟組件之間與父子組件之間的數(shù)據(jù)交互,兩者相比較,兄弟組件之間的通信其實(shí)和子組件向父組件傳值有些類(lèi)似,他們的通信原理都是相同的,例如子向父?jìng)髦狄彩?$emit 和 $on 的形式,只是沒(méi)有 Bus ,但若我們仔細(xì)想想,此時(shí)父組件其實(shí)就充當(dāng)了 Bus 這個(gè)事件總線(xiàn)的角色。
五丶使用Vuex
何為Vuex,看一下官網(wǎng)的解釋?zhuān)?/p>
Vuex 是一個(gè)專(zhuān)為 Vue.js 應(yīng)用程序開(kāi)發(fā)的 狀態(tài)管理模式 。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。

什么情況下使用Vuex?
Vuex 可以幫助我們管理共享狀態(tài),并附帶了更多的概念和框架。這需要對(duì)短期和長(zhǎng)期效益進(jìn)行權(quán)衡。
如果您不打算開(kāi)發(fā)大型單頁(yè)應(yīng)用,使用 Vuex 可能是繁瑣冗余的。確實(shí)是如此——如果您的應(yīng)用夠簡(jiǎn)單,您最好不要使用 Vuex。一個(gè)簡(jiǎn)單的store 模式就足夠您所需了。但是,如果您需要構(gòu)建一個(gè)中大型單頁(yè)應(yīng)用,您很可能會(huì)考慮如何更好地在組件外部管理狀態(tài),Vuex 將會(huì)成為自然而然的選擇。
在components目錄下新建 vuexA.vue 和 vuexB.vue ,模擬場(chǎng)景: vuexA.vue 向 vuexB.vue 傳值。
首先我們安裝vuex, npm install vuex --save ,在src目錄下創(chuàng)建vuex目錄,然后在vuex目錄下新建 index.js 、 state.js 、 getters.js 、 actions.js 、 mutations.js :

vuex/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state.js'
import mutations from './mutations.js'
import getters from './getters.js'
import actions from './actions.js'
Vue.use(Vuex)
export default new Vuex.Store({
state,
getters,
mutations,
actions
})
在main.js中引入vuex/index.js并注入到Vue中:
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './vuex'
Vue.config.productionTip = false
new Vue({
store,
router,
render: h => h(App),
}).$mount('#app')
state.js
export default{
city:'nanjing'
}
vuexA.vue
<template>
<div>
<div>我是vuexA中city參數(shù):{{city}}</div>
<input type="text" :value="city" @change="change">
</div>
</template>
<script>
export default{
methods:{
change(e){
this.$store.dispatch('setCityName',e.target.value)
}
},
computed:{
city(){
return this.$store.getters.getCity
}
}
}
</script>
<style>
</style>
vuexB.vue
<template>
<div>
<div>我是vuexB中的city參數(shù):{{city}}</div>
</div>
</template>
<script>
export default{
data(){
return{
}
},
computed:{
city(){
return this.$store.state.city
}
}
}
</script>
<style>
</style>
actions.js
export default{
setCityName({commit,state},name){
commit('setCity',name)
}
}
mutations.js
export default{
setCity(state,name){
state.city = name//設(shè)置新的值
}
}
getter.js
export default{
getCity(state){
return state.city//返回目前城市名稱(chēng)
}
}
在瀏覽器中打開(kāi):

修改input中的值:

顯而易見(jiàn),當(dāng)vuexA頁(yè)面中input值改變時(shí),可同時(shí)改變vuexB頁(yè)面中的值,即將city參數(shù)從vuexA頁(yè)面?zhèn)鞯搅藇uexB頁(yè)面,從而實(shí)現(xiàn)用vuex在組件中傳值。
vuex更多詳細(xì)功能請(qǐng)參考Vuex中文官方文檔。
全部實(shí)例代碼已上傳至 我的GitHub,歡迎訪(fǎng)問(wèn)Fork。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用Vue動(dòng)態(tài)生成form表單的實(shí)例代碼
這篇文章主要介紹了使用Vue動(dòng)態(tài)生成form表單的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-04-04
詳解vue-cli快速構(gòu)建vue應(yīng)用并實(shí)現(xiàn)webpack打包
這篇文章主要介紹了詳解vue-cli快速構(gòu)建vue應(yīng)用并實(shí)現(xiàn)webpack打包,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Vue?keepAlive實(shí)現(xiàn)不同的路由共用一個(gè)組件component的緩存問(wèn)題(推薦)
這篇文章主要介紹了Vue?keepAlive實(shí)現(xiàn)不同的路由共用一個(gè)組件component的緩存問(wèn)題,實(shí)現(xiàn)方式使用Vue?keepAlive實(shí)現(xiàn)頁(yè)面緩存,需要的朋友可以參考下2022-08-08
vue項(xiàng)目中v-model父子組件通信的實(shí)現(xiàn)詳解
vue.js,是一個(gè)構(gòu)建數(shù)據(jù)驅(qū)動(dòng)的 web 界面的庫(kù)。Vue.js 的目標(biāo)是通過(guò)盡可能簡(jiǎn)單的 API 實(shí)現(xiàn)響應(yīng)的數(shù)據(jù)綁定和組合的視圖組件。下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目中v-model父子組件通信實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下。2017-12-12
vue-baidu-map實(shí)現(xiàn)區(qū)域圈線(xiàn)和路徑的漸變色
這篇文章主要介紹了vue-baidu-map實(shí)現(xiàn)區(qū)域圈線(xiàn)和路徑的漸變色方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07

