Vue传参一箩筐(页面、组件)


Posted in Javascript onApril 04, 2019

Vue页面、组件之间传参方式繁多,此处罗列出常用的几种方式,欢迎审阅补充。

一丶路由传参

这里的路由传参以编程式 router.push(...) 为例,声明式 <router-link :to="..."> 与之类似。此处模拟情景为从 componentsA.vue 页面跳转到 componentsB.vue 页面传参。首先,路由配置信息如下:

router.js

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
		}
	]
})

1.1 路由配置传参

首先确定自己要传的参数名,将路由配置修改一下,传name,age,sex三个参数:

{
			path:'/componentsB/:name/:age/:sex',
			name:'componentsB',
			component:componentsB
		}

componentsA.vue 页面通过 this.$router.push 配置与之对应的参数:

componentsA.vue

<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 接收参数:

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会携带参数。

1.2 params传参

首先将刚才路由配置修改部分还原,在 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不会携带参数。

1.3 query传参

这种方式和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会携带参数。

1.4 小结

  • 路由配置传参注意书写格式 /:id ,获取参数都是通过 $route 而不是 $router
  • params 传参和 query 传参区别类似于 postget 方法。 params 传参地址栏不会显示参数,而 query 传参会将参数显示在地址栏中
  • params 传参刷新页面参数会丢失,另外两种不会
  • params 传参对应的路由属性是 name ,而 query 传参对应的路由属性既可以是 name ,也可以是 path

二丶使用缓存

缓存方式即通过 sessionStoragelocalStorageCookie 方式传参,这种方式和是不是用Vue无关,因此,不谈。

三丶父子组件之间传值

在components目录下创建父组件 parent.vue 和子组件 children.vue ,在父组件中引入子组件。为了演示方便,在路由配置中加入 /parent 路径。

3.1 父组件向子组件传值 props

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>

在浏览器中打开:

Vue传参一箩筐(页面、组件)

3.2 子组件向父组件传值 $emit

子组件通过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>

点击按钮浏览器显示:

Vue传参一箩筐(页面、组件)

3.3 小结

props 可以是字符串数组,也可以是对象(可以类型验证、设置默认值等) ;

使用 .native 修饰监听事件,开发中使用了 element-ui 的框架标签时候,使用事件绑定无效。这时候需要使用 .native 修饰 v-on:event ,可以在框架标签或组件的根元素 上监听一个原生事件,例如 <my-component v-on:click.native="doTheThing"></my-component>

 四丶非父子(兄弟)组件之间传值

非父子组件之间传值,需要定义公共实例文件 bus.js ,作为中间仓库来传值,不然路由组件之间达不到传值的效果。在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] ) 进行传值,在 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>

点击按钮,浏览器中显示:

Vue传参一箩筐(页面、组件)

小结

兄弟组件之间与父子组件之间的数据交互,两者相比较,兄弟组件之间的通信其实和子组件向父组件传值有些类似,他们的通信原理都是相同的,例如子向父传值也是 $emit$on 的形式,只是没有 Bus ,但若我们仔细想想,此时父组件其实就充当了 Bus 这个事件总线的角色。

五丶使用Vuex

何为Vuex,看一下官网的解释:

Vuex 是一个专为 Vue.js 应用程序开发的 状态管理模式 。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Vue传参一箩筐(页面、组件)

什么情况下使用Vuex?

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

在components目录下新建 vuexA.vuevuexB.vue ,模拟场景: vuexA.vuevuexB.vue 传值。

首先我们安装vuex, npm install vuex --save ,在src目录下创建vuex目录,然后在vuex目录下新建 index.jsstate.jsgetters.jsactions.jsmutations.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参数:{{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//返回目前城市名称
	}
}

在浏览器中打开:

Vue传参一箩筐(页面、组件)

修改input中的值:

Vue传参一箩筐(页面、组件)

显而易见,当vuexA页面中input值改变时,可同时改变vuexB页面中的值,即将city参数从vuexA页面传到了vuexB页面,从而实现用vuex在组件中传值。

vuex更多详细功能请参考Vuex中文官方文档。

全部实例代码已上传至 我的GitHub,欢迎访问Fork。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
FLASH 广告之外的链接
Dec 16 Javascript
javascript面向对象入门基础详细介绍
Sep 05 Javascript
JQuery入门——移除绑定事件unbind方法概述及应用
Feb 05 Javascript
node.js正则表达式获取网页中所有链接的代码实例
Jun 03 Javascript
JS选中checkbox后获取table内一行TD所有数据的方法
Jul 01 Javascript
详解maxlength属性在textarea里奇怪的表现
Dec 27 Javascript
js简单倒计时实现代码
Apr 30 Javascript
JavaScript基本类型值-Undefined、Null、Boolean
Feb 23 Javascript
Vue.js与 ASP.NET Core 服务端渲染功能整合
Nov 16 Javascript
详解如何理解vue的key属性
Apr 14 Javascript
vue从一个页面跳转到另一个页面并携带参数的解决方法
Aug 12 Javascript
Vue组件基础用法详解
Feb 05 Javascript
Vue使用.sync 实现父子组件的双向绑定数据问题
Apr 04 #Javascript
小程序getLocation需要在app.json中声明permission字段
Apr 04 #Javascript
Vue组件内部实现一个双向数据绑定的实例代码
Apr 04 #Javascript
详解JavaScript的变量
Apr 04 #Javascript
vue elementUI table表格数据 滚动懒加载的实现方法
Apr 04 #Javascript
js 计算图片内点个数的示例代码
Apr 04 #Javascript
在node中使用jwt签发与验证token的方法
Apr 03 #Javascript
You might like
解析PHP处理换行符的问题 \r\n
2013/06/13 PHP
10 个经典PHP函数
2013/10/17 PHP
laravel 解决后端无法获取到前端Post过来的值问题
2019/10/22 PHP
ThinkPHP类似AOP思想的参数验证的实现方法
2019/12/18 PHP
JQuery困惑—包装集 DOM节点
2009/10/16 Javascript
一个js导致的jquery失效问题的解决方法
2013/11/27 Javascript
HTML5+setCutomValidity()函数验证表单实例分享
2015/04/24 Javascript
微信和qq时间格式模板实例详解
2016/10/21 Javascript
Bootstrap提示框效果的实例代码
2017/07/12 Javascript
详解vue-cli + webpack 多页面实例配置优化方法
2017/07/13 Javascript
玩转Koa之核心原理分析
2018/12/29 Javascript
记录一次开发微信网页分享的步骤
2019/05/07 Javascript
微信小程序实现3D轮播图效果(非swiper组件)
2019/09/21 Javascript
在vue中实现给每个页面顶部设置title
2020/07/29 Javascript
Vue 按照创建时间和当前时间显示操作(刚刚,几小时前,几天前)
2020/09/10 Javascript
[48:27]EG vs Liquid 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
跟老齐学Python之玩转字符串(2)更新篇
2014/09/28 Python
彻底搞懂Python字符编码
2018/01/23 Python
Python使用min、max函数查找二维数据矩阵中最小、最大值的方法
2018/05/15 Python
解决Matplotlib图表不能在Pycharm中显示的问题
2018/05/24 Python
解决python中遇到字典里key值为None的情况,取不出来的问题
2018/10/17 Python
浅谈Python中的bs4基础
2018/10/21 Python
Python使用Shelve保存对象方法总结
2019/01/28 Python
Python3常用内置方法代码实例
2019/11/18 Python
如何使用PyCharm将代码上传到GitHub上(图文详解)
2020/04/27 Python
python轮询机制控制led实例
2020/05/03 Python
超酷炫 CSS3垂直手风琴菜单
2016/06/28 HTML / CSS
阻止移动设备(手机、pad)浏览器双击放大网页的方法
2014/06/03 HTML / CSS
应届行政管理专业个人自我评价
2013/12/28 职场文书
幼儿教育感言
2014/02/05 职场文书
农村改厕实施方案
2014/03/22 职场文书
2014年乡镇安全生产工作总结
2014/12/02 职场文书
2016元旦主持人开场白
2015/12/03 职场文书
党员干部学习十八届五中全会精神心得体会
2016/01/05 职场文书
PHP连接MSSQL数据库案例,PHPWAMP多个PHP版本连接SQL Server数据库
2021/04/16 PHP
Dashboard管理Kubernetes集群与API访问配置
2022/04/01 Servers