Vue頁面、組件之間傳參方式繁多,此處羅列出經常使用的幾種方式,歡迎審閱補充。
html
這裏的路由傳參以編程式router.push(...)
爲例,聲明式<router-link :to="...">
與之相似。此處模擬情景爲從componentsA.vue
頁面跳轉到componentsB.vue
頁面傳參。首先,路由配置信息以下:vue
router.js
git
import Vue from 'vue'
import Router from 'vue-router'
import componentsA from './components/componentsA' //在components下建立componentsA.vue
import componentsB from './components/componentsB' //在components下建立componentsB.vue
Vue.use(Router)
export default new Router({
routes:[
{
path:'/componentsA',
name:'componentsA',
component:componentsA
},
{
path:'/componentsB',
name:'componentsB',
component:componentsB
}
]
})複製代碼
首先肯定本身要傳的參數名,將路由配置修改一下,傳name,age,sex三個參數:github
{
path:'/componentsB/:name/:age/:sex',
name:'componentsB',
component:componentsB
}複製代碼
在componentsA.vue
頁面經過this.$router.push
配置與之對應的參數:vue-router
componentsA.vue
vuex
<template>
<div>
<div>我是組件A</div>
<button @click='routerToB1'>方式一跳轉到組件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
接收參數:npm
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>複製代碼
點擊按鈕"方式一跳轉到組件B",componentsB頁面打印出{name:'Gene',age:'18',sex:'male'}
,成功獲取到A頁面傳過來的參數,而且地址欄顯示爲localhost:8889/#/componentsB/Gene/18/male
(端口號根據本身設置的來),代表這種傳參方式url會攜帶參數。element-ui
首先將剛纔路由配置修改部分還原,在componentsA.vue
頁面添加按鈕"方式二跳轉到組件B":數組
componentsA.vue
<template>
<div>
<div>我是組件A</div>
<button @click='routerToB1'>方式一跳轉到組件B</button>
<button @click='routerToB2'>方式二跳轉到組件B</button>
</div>
</template>複製代碼
在methods
中添加方法routerToB2
,使用路由屬性name
來肯定匹配的路由,使用屬性params
來傳遞參數:
componentsA.vue
routerToB2(){
this.$router.push({
name:'componentsB',
params:{
exa:'我是傳到組件B的參數'
}
})
},複製代碼
componentsB.vue
保持不變,params傳參方式獲取參數也是經過this.$route.params
,點擊A頁面新添加的按鈕"方式二跳轉到組件B",在B頁面打印出{exa: "我是傳到組件B的參數"}
,傳參成功,地址欄爲localhost:8889/#/componentsB
,代表這種方式url不會攜帶參數。
這種方式和params傳參方式相似,在componentsA.vue
頁面繼續添加按鈕"方式三跳轉到組件B":
componentsA.vue
<template>
<div>
<div>我是組件A</div>
<button @click='routerToB1'>方式一跳轉到組件B</button>
<button @click='routerToB2'>方式二跳轉到組件B</button>
<button @click='routerToB3'>方式三跳轉到組件B</button>
</div>
</template>複製代碼
在methods
中添加方法routerToB3
,使用路由屬性name
或者path
來肯定匹配的路由,使用屬性query
來傳參:
componentsA.vue
routerToB3(){
this.$router.push({
name:'componentsB',// path:'/componentsB'
query:{
que:'我是經過query傳到組件B的參數'
}
})
}複製代碼
在componentsB.vue
頁面經過this.$route.query
來獲取參數:
componentsB.vue
getRouterData(){
const query = this.$route.query
console.log(query)//{que: "我是經過query傳到組件B的參數"}
}複製代碼
查看地址欄爲localhost:8889/#/componentsB?que=我是經過query傳到組件B的參數
,顯然這種方式url會攜帶參數。
/:id
,獲取參數都是經過$route
而不是$router
params
傳參和query
傳參區別相似於post
和get
方法。params
傳參地址欄不會顯示參數,而query
傳參會將參數顯示在地址欄中params
傳參刷新頁面參數會丟失,另外兩種不會params
傳參對應的路由屬性是name
,而query
傳參對應的路由屬性既能夠是name
,也能夠是path
緩存方式即經過sessionStorage
、localStorage
、Cookie
方式傳參,這種方式和是否是用Vue無關,所以,不談。
在components目錄下建立父組件parent.vue
和子組件children.vue
,在父組件中引入子組件。爲了演示方便,在路由配置中加入/parent
路徑。
在parent.vue
的子組件標籤上註冊message1,在children.vue
中經過props
接收message1,若是傳遞的值爲變量,則使用v-bind:
或直接用:
,參考以下:
parent.vue
<template>
<div>
<div>我是父組件</div>
<children message1='我是直接參數' v-bind:message2='msg' :message3='obj'></children>
</div>
</template>
<script>
import Children from './children'
export default{
components:{
Children
},
data(){
return{
msg:'我是父組件的參數'
}
},
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>複製代碼
在瀏覽器中打開:
子組件經過vm.$emit( event, […args] ),觸發當前實例上的事件。附加參數都會傳給監聽器回調。父組件在子組件標籤上監聽事件得到參數。
children.vue
<template>
<div style="margin-top: 100px;">
<div>我是子組件</div>
<div>{{message1}}</div>
<div>{{message2}}</div>
<div>{{message3}}</div>
<button @click='ChildToParent'>點我傳愛</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='我是直接參數' v-bind:message2='msg' :message3='obj'></children>
</div>
</template>
<script>
import Children from './children'
export default{
components:{
Children
},
data(){
return{
msg:'我是父組件的參數',
loveWho:''
}
},
methods:{
parentSayLove(data){
this.loveWho = data
}
},
created(){
this.obj = {a:'1',b:'2',c:'3'}
}
}
</script>
<style>
</style>複製代碼
點擊按鈕瀏覽器顯示:
props
能夠是字符串數組,也能夠是對象(能夠類型驗證、設置默認值等) ;.native
修飾監聽事件,開發中使用了element-ui
的框架標籤時候,使用事件綁定無效。這時候須要使用.native
修飾v-on:event
,能夠在框架標籤或組件的根元素 上監聽一個原生事件,例如 <my-component v-on:click.native="doTheThing"></my-component>
。非父子組件之間傳值,須要定義公共實例文件bus.js
,做爲中間倉庫來傳值,否則路由組件之間達不到傳值的效果。在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
經過在事件中添加Bus.$emit( event, […args] )
進行傳值,在second.vue
中經過Bus.$on(event,callBack)
進行監聽。
first.vue
<template>
<div>
<div>我是first.vue</div>
<button @click="firstToSecond">點擊傳值給second.vue</button>
</div>
</template>
<script>
import Bus from '../bus.js'
export default{
data(){
return{
msg:'我是first.vue傳到second.vue的參數'
}
},
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>複製代碼
點擊按鈕,瀏覽器中顯示:
兄弟組件之間與父子組件之間的數據交互,二者相比較,兄弟組件之間的通訊其實和子組件向父組件傳值有些相似,他們的通訊原理都是相同的,例如子向父傳值也是$emit
和$on
的形式,只是沒有Bus
,但若咱們仔細想一想,此時父組件其實就充當了Bus
這個事件總線的角色。
何爲Vuex,看一下官網的解釋:
Vuex 是一個專爲 Vue.js 應用程序開發的 狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
什麼狀況下使用Vuex?
Vuex 能夠幫助咱們管理共享狀態,並附帶了更多的概念和框架。這須要對短時間和長期效益進行權衡。
若是您不打算開發大型單頁應用,使用 Vuex 多是繁瑣冗餘的。確實是如此——若是您的應用夠簡單,您最好不要使用 Vuex。一個簡單的 store 模式 就足夠您所需了。可是,若是您須要構建一箇中大型單頁應用,您極可能會考慮如何更好地在組件外部管理狀態,Vuex 將會成爲天然而然的選擇。
在components目錄下新建vuexA.vue
和vuexB.vue
,模擬場景:vuexA.vue
向vuexB.vue
傳值。
首先咱們安裝vuex,npm install vuex --save
,在src目錄下建立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參數:{{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參數:{{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//設置新的值
}
}複製代碼
getter.js
export default{
getCity(state){
return state.city//返回目前城市名稱
}
}複製代碼
在瀏覽器中打開:
修改input中的值:
顯而易見,當vuexA頁面中input值改變時,可同時改變vuexB頁面中的值,即將city參數從vuexA頁面傳到了vuexB頁面,從而實現用vuex在組件中傳值。
vuex更多詳細功能請參考Vuex中文官方文檔。
所有實例代碼已上傳至個人GitHub,歡迎訪問Fork。