Vue传参一箩筐(页面、组件)
作者:dongfangyiyu 发布时间:2024-05-29 22:44:13
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
传参区别类似于post
和get
方法。params
传参地址栏不会显示参数,而query
传参会将参数显示在地址栏中params
传参刷新页面参数会丢失,另外两种不会params
传参对应的路由属性是name
,而query
传参对应的路由属性既可以是name
,也可以是path
二丶使用缓存
缓存方式即通过 sessionStorage
、 localStorage
、 Cookie
方式传参,这种方式和是不是用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>
在浏览器中打开:
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>
点击按钮浏览器显示:
3.3 小结
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,看一下官网的解释:
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。
来源:https://juejin.im/post/5ca1b720f265da309b7804cb


猜你喜欢
- 【ThinkPHP版本查询】dump(THINK_VERSION);模板获取get参数{$Think.get.pageNumber}或者$R
- 一、分析网页1. 打开网页,在搜索框输入百度翻译并进入百度翻译网站中。F12调出开发者工具,点击Network(网络)\ Fetch/XHR
- 密码已经是我们生活工作中必不可少的工具,但一个不安全的密码有又有可能会给我们造成不必要的损失。作为网站设计者,如果我们在网页中能对用户输入的
- 使用astype实现dataframe字段类型转换# -*- coding: UTF-8 -*-import pandas as pddf
- 项目介绍go-admin 是一个中后台管理系统,基于(gin, gorm, Casbin, Vue, Element UI)实现。主要目的是
- 1、可以在mode参数中添加'b'字符。所有适合文件对象的相同方法。然而,每种方法都希望并返回一个bytes对象。>&
- CentOS7服务器中apache、php7以及mysql5.7的配置代码如下所示:yum upgradeyum install net-t
- 代码如下:CREATE TABLE [dbo].[TbGuidTable]( [TableName] [varchar](50) NOT N
- /*Bresenham画圆算法*/var arc = function(x0,y0,r){/*起点坐标x0,y
- 背景当前很多文章尝试过最优分箱,python上也有cut等方法进行等宽分箱。为了方便日后输出结果以及分箱要求。做一个简单的轮子以供大家日后使
- 树的实质是很多条数据按照一定的内在关系,分层级显示出来。因此每一条数据包括数据项和相互关系。数据项就对应了树中的column,而相互关系对应
- 给定损失函数的输入y,pred,shape均为bxc。若设定loss_fn = torch.nn.MSELoss(reduction=
- #coding=utf8__author__ = 'Administrator'# 当函数的参数不确定时,可以使用*args
- 去掉html中的table代码 Function OutTable(str) dim a,re&nb
- 目录前言一、样式穿透1. 什么是样式穿透?2. 如何使用?二、混入1. 什么是混入?2. 如
- 投资有风险,选择需谨慎。 股票交易数据分析可直观股市走向,对于如何把握股票行情,快速解读股票交易数据有不可替代的作用!1 数据预处
- 本文实例讲述了Python快速排序算法。分享给大家供大家参考,具体如下:快速排序的时间复杂度是O(NlogN)算法描述:① 先从序列中取出一
- python的多线程比较鸡肋,优先使用多进程1 基础知识现在的 PC 都是多核的,使用多线程能充分利用 CPU 来提供程序的执行效率。1.1
- 代数运算定义加法运算图像叠加需要满足该条件:两幅图像的像素必须相同(尺寸,形状)减法运算乘法运算1、图像的局部显示。2、用二值蒙版图像与原图
- Ruby 是一门通用的语言,不仅仅是一门应用于WEB开发的语言,但 Ruby 在WEB应用及WEB工具中的开发是最常见的。使用Ruby您不仅