vue传参

组件传参

1、父组件像子组件传参
1.1父组件通过 v-bind/ : 传参数给子组件

注意:
参数名需用使用-代替驼峰
父组件:

<add :msg-val="msg"></add>
data(){
    return {
        msg: [1,2,3]
    };
}
1.2子组件通过props方法接受参数

props中可以通过定义default设置能接受的收据类型,如果不符合会报错
子组件:

props: ['msgVal']
props: {
    msgVal: Array //这样可以指定传入的类型,如果类型不对,会警告
}
   ||
props: {
    msgVal: {
        type: Array, //指定传入的类型
        //type 也可以是一个自定义构造器函数,使用 instanceof 检测。
        default: [0,0,0] //这样可以指定默认的值
    }
}
<span>{{msgVal}}</span>

注意:父子传参,数据是异步请求,可能在数据渲染时会报错
原因:异步请求时,数据还没有获取到但此时可能已经渲染到该节点了
解决:(1)可以在父组件需要传递数据的节点上添加v-if,默认为false,异步请求获取数据后为true
(2)在vue中可以使用this.$nextTick(() => {})解决异步操作

1.3 inheritAttr和$attr

(1)inheritAttr
不希望组件的根元素继承attribute,则可以在组件的选项中设置inheritAttr:false
注意:inheritAttr不会影响style和class的绑定
(2) a t t r 包 含 了 父 作 用 域 中 不 作 为 p r o p 被 识 别 ( 且 获 取 ) 的 特 性 绑 定 ( c l a s s 和 s t y l e 除 外 ) 。 当 一 个 组 件 没 有 声 明 任 何 p r o p 时 , 这 里 会 包 含 所 有 父 作 用 域 的 绑 定 ( c l a s s 和 s t y l e 除 外 ) , 并 且 可 以 通 过 v − b i n d = " attr 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。 当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class和 style 除外),并且可以通过 v-bind=" attrprop()(classstyle)prop(classstyle)vbind="attrs" 传入内部组
如:
父组件

<template>
  	<a href="">
    		<slot></slot>
  	</a>
</template>
<script>
  export default {
    props: {
      name: String,
      href: String
    },

    created() {
      console.log(this.$attrs)
    }
  }
</script>

子组件

<ALink href="/index" name="abc" target="_blank" :class="{isSmall: true, isDisabled: true}">123</ALink>

因为href 和 name 都是 ALink组件内部定义的属性,而$attr又不包含 class 和 style,因此 $attr 的值为

{target: "_blank"}
2、子组件触发父组件方法并传参
2.1子组件通过$emit触发父组件方法

父组件通过 v-on:方法名 定义方法

<blog-post v-on:enlarge-text="postFontSize += 0.1">
</blog-post>

子组件通过 $emit(‘方法名’) 触发方法

<button v-on:click="$emit('enlarge-text')">Enlarge text
</button>
2.2 子组件调用父组件方法并传参

子组件通过 $emit 触发方法,且第二个参数就是需要传递给父组件的参数

<button v-on:click="$emit('enlarge-text', 0.1)">Enlarge text
</button>

父组件通过 $event 访问子组件抛出的参数

<blog-post v-on:enlarge-text="postFontSize += $event">
</blog-post>
  
<blog-post  v-on:enlarge-text="onEnlargeText">
</blog-post>
methods: {
  	onEnlargeText: function (enlargeAmount) {
    		this.postFontSize += enlargeAmount
  	}
}
3、子组件向子组件传参

vue中没有子组件向子组件传参的方法,建议将需要传参的子组件合并为一个大组件
如果一定要子组件向子组件传参,有两种方法
(1)有父组件
可以先由一个子组件传参给父组件,再传给子组件
(2)无父组件
通过eventBus或vuex(小项目少页面用eventBus,大项目多页面使用 vuex)传值

3.1 通过eventBus(即通过v-on监听,$emit触发)
3.1.1定义一个新的vue实例专门用来传递数据,并导出
eventBus.js
import Vue from 'vue'
export default new Vue()

3.1.2 定义传递的方法名和传输内容,点击事件或钩子函数触发eventBus.emit事件
componentA.vue

<template>
    <div class='componentA'>
    	<button @click="emitToB">点击按钮传递数据给兄弟组件B</button>
    </div>
</template>
<script>
    import eventBus from 'api/eventBus.js'
    export default {
        methods: {
            emitToB() {
                eventBus.$emit('eventFORMA', '我是组件A传递给组件B的数据')            
            }        
        }    
    }
</script>
3.1.3 接受传递过来的数据

注意:eventBus是一个新的vue实例,区分两个this所表示的实例
compontB.vue

<template>
    <div class='componentB'>
    	{{title}} //最终显示传递过来的值
    </div>
</template>
<script>
    import eventBus from 'api/eventBus.js'
    export default {
        data() {
            return {
                title: ''             
            }        
        },
        mouted() {
            this.getEventData()        
        },
        methods: {
            getEventData() {
                const vm = this //这个this是项目vue的实例,用vm接受,与eventBus的vue区分
                eventBus.$on('eventFROMA', function(val) {
                     vm.title = val
                     //this.title = val //这里的this指的是eventBus的vue实例
                })            
            }        
        }
    }
</script>
3.2 vuex进行传值

创建Vuex.Store实例保存到变量store中,最后使用export default导出store
store->index.js

import Vue from 'vue' //引入vue
import Vuex from 'vuex'  //引入vuex
Vue.use(Vuex) //使用Vuex
const store = new Vuex.store({
    state: {
        count: 1    
    },
    getters: {
        getStateCount: function(state) { //state就是上面state
            return state.count + 1        
        }
    },
    mutations: {
        add(state) {
            state.count = state.count + 1        
        },
        reduction(state) {
            state.count = state.count - 1        
        }    
    },
    actions: { //注册actions,类似与methods
        addFun(context) { //接受一个与store实例具有相同方法的属性得context对象
            context.commit('add'')        
        },
        reductionFun(context, n) { //接受一个与store实例具有相同方法的属性得context对象
            context.commit('reduction', n)        
        }
    }
    
})
export default store //导出store

在main.js文件中引入该文件,在文件中添加import store from './store,再在vue实例全局引入store对象:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui'

Vue.config.productionTip = false
var echarts = require('echarts')
Vue.prototype.$echarts = echarts
Vue.use(router)
Vue.use(ElementUI, {
  size: 'mini'
})

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

State:
vuex中的数据源,我们需要保存的数据就保存在这里,可以在页面通过 this.$store.state来获取我们定义的数据;
HelloWorld.vue

<template>
    <div>
    	<h2>{{this.$store.state.count}}</h2>
    </div>
</template>

Getters:
Getter相当于vue中的computed计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算,这里我们可以通过定义vuex的Getter来获取,Getters 可以用于监听、state中的值的变化,返回计算后的结果,这里我们修改HelloWorld.vue文件如下:

<template>
    <div>
    	<h2>{{this.$store.state.count}}</h2>  //1
     	<h2>{{this.$store.getters.getStateCount}}</h2> //2
    </div>
</template>

Mutations:
数据我们在页面是获取到了,但是如果我们需要修改count值怎么办?如果需要修改store中的值唯一的方法就是提交mutation来修改,我们现在Hello World.vue文件中添加两个按钮,一个加1,一个减1;这里我们点击按钮调用add(执行加的方法)和reduction(执行减法的方法),然后在里面直接提交mutations中的方法修改值:

<template>
    <div>
    	<button @click="addFun">-</button>
     	<button @click="reductionFun">+</button>
    </div>
</template>
<script>
method: {
    addFun() {
        this.$store.commit('add')     //add是mutations内的方法
    },
    reductionFun() {
        this.$store.commit('reduction')   //reduction是mutation中的方法 
    }
}
</script>

Actions:
但是,官方并不建议我们这样直接去修改store里面的值,而是让我们去提交一个actions,在actions中提交mutation再去修改状态值,接下来我们修改index.js文件,先定义actions提交mutation的函数:

<template>
    <div>
    	<button @click="add">-</button>
     	<button @click="reduction">+</button>
    </div>
</template>
<script>
method: {
    addFun() {
        this.$store.dispatch('addFun')    //addFun是actions内的方法
    },
    reductionFun() {
        var n = 10;
        this.$store.dispatch('reductionFun', n)    //reductionFun是actions内的方法
    }
}
</script>

4、切换页面时组件之间的传参

4.1 通过路由携带参数进行传参

A -> B
A组件传参

this.$router.push( {
    path: '/componentB', //跳转到组件B
    query: {
        orderId: 123    
    }
})

B组件接收参数

this.$route.query.orderId

传参方式
(1)查询参数query(+path)
查询参数搭配query,刷新页面数据不会丢失
(2)命名路由params(+name)
命名路由搭配params,刷新页面参数回丢失
接受参数使用this.$router后面就是搭配路由的名称,就能获取到参数的值

4.2 路由导航

(1)声明式的导航

<router-link :to='...'>

(2)编程式的导航

router.push(...)
router.replace(...)
4.3 通过设置SessionStorage缓存形式进行传递

A组件缓存orderData

const orderData= {
    'orderId':123,
    'price': 88'
}
//sessionStorage生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过sessionStorage存储的数据也就被清空了。
sessionStorage.setItem('缓存名称',JSON.stringify(orderData))
//localStorage生命周期是永久的,除非用户在浏览器提供的UI上清除localStorage信息,否则这些信息将永远存在
localStorage.setItem('缓存名称',JSON.stringify(orderData))

B组件获取A中设置的缓存

const dataB = JSON.parse(sessionStorage.getItem('缓存名称'))
const dataB = JSON.parse(localStorage.getItem('缓存名称'))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值