溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Vue傳參一籮筐(頁面、組件)

發(fā)布時(shí)間:2020-10-08 07:09:31 來源:腳本之家 閱讀:264 作者:dongfangyiyu 欄目:web開發(fā)

Vue頁面、組件之間傳參方式繁多,此處羅列出常用的幾種方式,歡迎審閱補(bǔ)充。

一丶路由傳參

這里的路由傳參以編程式 router.push(...) 為例,聲明式 <router-link :to="..."> 與之類似。此處模擬情景為從 componentsA.vue 頁面跳轉(zhuǎn)到 componentsB.vue 頁面?zhèn)鲄?。首先,路由配置信息如下?/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 頁面通過 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 頁面用 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頁面打印出 {name:'Gene',age:'18',sex:'male'} ,成功獲取到A頁面?zhèn)鬟^來的參數(shù),并且地址欄顯示為 localhost:8889/#/componentsB/Gene/18/male (端口號(hào)根據(jù)自己設(shè)置的來),表明這種傳參方式url會(huì)攜帶參數(shù)。

1.2 params傳參

首先將剛才路由配置修改部分還原,在 componentsA.vue 頁面添加按鈕"方式二跳轉(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 來確定匹配的路由,使用屬性 params 來傳遞參數(shù):

componentsA.vue

		routerToB2(){
				this.$router.push({
					name:'componentsB',
					params:{
						exa:'我是傳到組件B的參數(shù)'
					}
				})
			},

componentsB.vue 保持不變,params傳參方式獲取參數(shù)也是通過 this.$route.params ,點(diǎn)擊A頁面新添加的按鈕"方式二跳轉(zhuǎn)到組件B",在B頁面打印出 {exa: "我是傳到組件B的參數(shù)"} ,傳參成功,地址欄為 localhost:8889/#/componentsB ,表明這種方式url不會(huì)攜帶參數(shù)。

1.3 query傳參

這種方式和params傳參方式類似,在 componentsA.vue 頁面繼續(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 來確定匹配的路由,使用屬性 query 來傳參:

componentsA.vue

routerToB3(){
				this.$router.push({
					name:'componentsB',// path:'/componentsB'
					query:{
						que:'我是通過query傳到組件B的參數(shù)'
					}
				})
			}

componentsB.vue 頁面通過 this.$route.query 來獲取參數(shù):

componentsB.vue

getRouterData(){
				const query = this.$route.query
				console.log(query)//{que: "我是通過query傳到組件B的參數(shù)"}
			}

查看地址欄為 localhost:8889/#/componentsB?que=我是通過query傳到組件B的參數(shù) ,顯然這種方式url會(huì)攜帶參數(shù)。

1.4 小結(jié)

  • 路由配置傳參注意書寫格式 /:id ,獲取參數(shù)都是通過 $route 而不是 $router
  • params 傳參和 query 傳參區(qū)別類似于 postget 方法。 params 傳參地址欄不會(huì)顯示參數(shù),而 query 傳參會(huì)將參數(shù)顯示在地址欄中
  • params 傳參刷新頁面參數(shù)會(huì)丟失,另外兩種不會(huì)
  • params 傳參對(duì)應(yīng)的路由屬性是 name ,而 query 傳參對(duì)應(yīng)的路由屬性既可以是 name ,也可以是 path

二丶使用緩存

緩存方式即通過 sessionStoragelocalStorage 、 Cookie 方式傳參,這種方式和是不是用Vue無關(guān),因此,不談。

三丶父子組件之間傳值

在components目錄下創(chuàng)建父組件 parent.vue 和子組件 children.vue ,在父組件中引入子組件。為了演示方便,在路由配置中加入 /parent 路徑。

3.1 父組件向子組件傳值 props

parent.vue 的子組件標(biāo)簽上注冊(cè)message1,在 children.vue 中通過 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>

在瀏覽器中打開:

Vue傳參一籮筐(頁面、組件)

3.2 子組件向父組件傳值 $emit

子組件通過vm.$emit( event, […args] ),觸發(fā)當(dāng)前實(shí)例上的事件。附加參數(shù)都會(huì)傳給監(jiān)聽器回調(diào)。父組件在子組件標(biāo)簽上監(jiān)聽事件獲得參數(shù)。

children.vue

<template>
	<div >
		<div>我是子組件</div>
		<div>{{message1}}</div>
		<div>{{message2}}</div>
		<div>{{message3}}</div>
		<button @click='ChildToParent'>點(diǎn)我傳愛</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>大聲告訴我你愛誰:{{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)擊按鈕瀏覽器顯示:

Vue傳參一籮筐(頁面、組件)

3.3 小結(jié)

props 可以是字符串?dāng)?shù)組,也可以是對(duì)象(可以類型驗(yàn)證、設(shè)置默認(rèn)值等) ;

使用 .native 修飾監(jiān)聽事件,開發(fā)中使用了 element-ui 的框架標(biāo)簽時(shí)候,使用事件綁定無效。這時(shí)候需要使用 .native 修飾 v-on:event ,可以在框架標(biāo)簽或組件的根元素 上監(jiān)聽一個(gè)原生事件,例如 <my-component v-on:click.native="doTheThing"></my-component> 。

 四丶非父子(兄弟)組件之間傳值

非父子組件之間傳值,需要定義公共實(shí)例文件 bus.js ,作為中間倉庫來傳值,不然路由組件之間達(dá)不到傳值的效果。在components目錄下新建 first.vuesecond.vue 以及公共文件 bus.js 。

bus.js

import Vue from 'vue'
export default new Vue()

first.vuesecond.vue 中分別引入bus.js。

import Bus from '../bus.js'

模擬情景: first.vuesecond.vue 傳值。在 first.vue 通過在事件中添加 Bus.$emit( event, […args] ) 進(jìn)行傳值,在 second.vue 中通過 Bus.$on(event,callBack) 進(jìn)行監(jiān)聽。

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)擊按鈕,瀏覽器中顯示:

Vue傳參一籮筐(頁面、組件)

小結(jié)

兄弟組件之間與父子組件之間的數(shù)據(jù)交互,兩者相比較,兄弟組件之間的通信其實(shí)和子組件向父組件傳值有些類似,他們的通信原理都是相同的,例如子向父傳值也是 $emit$on 的形式,只是沒有 Bus ,但若我們仔細(xì)想想,此時(shí)父組件其實(shí)就充當(dāng)了 Bus 這個(gè)事件總線的角色。

五丶使用Vuex

何為Vuex,看一下官網(wǎng)的解釋:

Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的 狀態(tài)管理模式 。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。

Vue傳參一籮筐(頁面、組件)

什么情況下使用Vuex?

Vuex 可以幫助我們管理共享狀態(tài),并附帶了更多的概念和框架。這需要對(duì)短期和長期效益進(jìn)行權(quán)衡。

如果您不打算開發(fā)大型單頁應(yīng)用,使用 Vuex 可能是繁瑣冗余的。確實(shí)是如此——如果您的應(yīng)用夠簡單,您最好不要使用 Vuex。一個(gè)簡單的store 模式就足夠您所需了。但是,如果您需要構(gòu)建一個(gè)中大型單頁應(yīng)用,您很可能會(huì)考慮如何更好地在組件外部管理狀態(tài),Vuex 將會(huì)成為自然而然的選擇。

在components目錄下新建 vuexA.vuevuexB.vue ,模擬場(chǎng)景: vuexA.vuevuexB.vue 傳值。

首先我們安裝vuex, npm install vuex --save ,在src目錄下創(chuàng)建vuex目錄,然后在vuex目錄下新建 index.jsstate.js 、 getters.jsactions.js 、 mutations.js

Vue傳參一籮筐(頁面、組件)

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//返回目前城市名稱
	}
}

在瀏覽器中打開:

Vue傳參一籮筐(頁面、組件)

修改input中的值:

Vue傳參一籮筐(頁面、組件)

顯而易見,當(dāng)vuexA頁面中input值改變時(shí),可同時(shí)改變vuexB頁面中的值,即將city參數(shù)從vuexA頁面?zhèn)鞯搅藇uexB頁面,從而實(shí)現(xiàn)用vuex在組件中傳值。

vuex更多詳細(xì)功能請(qǐng)參考Vuex中文官方文檔。

全部實(shí)例代碼已上傳至 我的GitHub,歡迎訪問Fork。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI