vue组件传值的方式:1、父传子;2、子传父;3、兄弟传值;4、问号传值,冒号传值和父子组件传值;5、使用“$ref”传值;6、使用“inject”给当前实例注入父组件的数据;7、祖传孙;8、孙传祖;9、$parent;10、sessionstorage传值;11、vuex。
1、父组件传给子组件
在子组件里定义一个props,即props:[‘msg’],msg可以是对象也可以是基本数据类型
如果你想定义一个默认值,即 props:{msg: {type: string, default: ‘hello world’}},
若默认值是对象类型:props: { msg: { type: object, default: () => { return { name: ‘dan_seek’ } } }}
需要注意的是这种传值是单向的,你无法改变父组件的值(当然引用类型例外);而且如果直接修改props的值会报一个警告。
推荐的写法是在data()里重新定义一个变量(见children.vue),并把props赋值给它,当然计算属性也行。
children.vue
<template> <section> 父组件传过来的消息是:{{mymsg}} </section></template><script> export default { name: "children", components: {}, props:['msg'], data() { return { mymsg:this.msg } }, methods: {} }</script>
parent.vue
<template> <div class="parent"> <children :msg="message"></children> </div></template><script>import children from '../components/children'export default { name: 'parent', components: { children }, data() { return { message:'hello world'}},}</script>
2、子组件传给父组件
这里需要使用自定义事件,在子组件中使用this.$emit(‘myevent’) 触发,然后在父组件中使用@myevent监听
children.vue
<template> <section> <br> <div @click="clickme">click me</div> </section></template><script> export default { name: "children", components: {}, data() { return { childnum:0 } }, methods: { clickme(){ // 通过自定义事件addnum把值传给父组件 this.$emit('addnum',this.childnum++) } } }</script>
parent.vue
<template> <div class="parent"> 这里是计数:{{parentnum}} <children-com @addnum="getnum"></children-com> </div></template><script> import childrencom from '../components/children' export default { name: 'parent', components: { childrencom }, data() { return { parentnum: 0 } }, methods:{ // childnum是由子组件传入的 getnum(childnum){ this.parentnum = childnum } } }</script>
3、兄弟组件间传值
运用自定义事件emit的触发和监听能力,定义一个公共的事件总线eventbus,通过它作为中间桥梁,我们就可以传值给任意组件了。而且通过eventbus的使用,可以加深emit的理解。
eventbus.js
import vue from 'vue'export default new vue()children1.vue<template> <section> <div @click="pushmsg">push message</div> <br> </section></template><script> import eventbus from './eventbus' export default { name: "children1", components: {}, data() { return { childnum:0 } }, methods: { pushmsg(){ // 通过事件总线发送消息 eventbus.$emit('pushmsg',this.childnum++) } } }</script>
children2.vue
<template> <section> children1传过来的消息:{{msg}} </section></template><script> import eventbus from './eventbus' export default { name: "children2", components: {}, data() { return { msg: '' } }, mounted() { // 通过事件总线监听消息 eventbus.$on('pushmsg', (children1msg) => { this.msg = children1msg }) } }</script>
parent.vue
<template> <div class="parent"> <children1></children1> <children2></children2> </div></template><script> import children1 from '../components/children1' import children2 from '../components/children2' export default { name: 'parent', components: { children1, children2 }, data() { return { } }, methods:{ } }</script>
github上还有一个开源vue-bus库,可以参考下: https://github.com/yangmingshan/vue-bus#readme
4、路由间传值
i.使用问号传值
a页面跳转b页面时使用 this.$router.push(‘/b?name=danseek’)
b页面可以使用 this.$route.query.name 来获取a页面传过来的值
上面要注意router和route的区别
ii.使用冒号传值
配置如下路由:
{ path: '/b/:name', name: 'b', component: () => import( '../views/b.vue') },
在b页面可以通过 this.$route.params.name 来获取路由传入的name的值
iii.使用父子组件传值
由于router-view本身也是一个组件,所以我们也可以使用父子组件传值方式传值,然后在对应的子页面里加上props,因为type更新后没有刷新路由,所以不能直接在子页面的mounted钩子里直接获取最新type的值,而要使用watch。
<router-view :type="type"></router-view>// 子页面......props: ['type']......watch: { type(){ // console.log("在这个方法可以时刻获取最新的数据:type=",this.type) }, },
5、使用$ref传值
通过$ref的能力,给子组件定义一个id,父组件通过这个id可以直接访问子组件里面的方法和属性
首先定义一个子组件children.vue
<template> <section> 传过来的消息:{{msg}} </section></template><script> export default { name: "children", components: {}, data() { return { msg: '', desc:'the use of ref' } }, methods:{ // 父组件可以调用这个方法传入msg updatemsg(msg){ this.msg = msg } }, }</script>
然后在父组件parent.vue中引用children.vue,并定义ref属性
<template> <div class="parent"> <!-- 给子组件设置一个id ref="children" --> <children ref="children"></children> <div @click="pushmsg">push message</div> </div></template><script> import children from '../components/children' export default { name: 'parent', components: { children, }, methods:{ pushmsg(){ // 通过这个id可以访问子组件的方法 this.$refs.children.updatemsg('have you received the clothes?') // 也可以访问子组件的属性 console.log('children props:',this.$refs.children.desc) } }, }</script>
6、使用依赖注入传给后代子孙曾孙
假设父组件有一个方法 getname(),需要把它提供给所有的后代
provide: function () { return { getname: this.getname() }}
provide 选项允许我们指定我们想要提供给后代组件的数据/方法
然后在任何后代组件里,我们都可以使用 inject 来给当前实例注入父组件的数据/方法:
inject: ['getname']
parent.vue
<template> <div class="parent"> <children></children> </div></template><script> import children from '../components/children' export default { name: 'parent', components: { children, }, data() { return { name:'dan_seek' } }, provide: function () { return { getname: this.name } }, }</script>
children.vue
<template> <section> 父组件传入的值:{{getname}} </section></template><script> export default { name: "children", components: {}, data() { return { } }, inject: ['getname'], }</script>
7、祖传孙 $attrs
正常情况下需要借助父亲的props作为中间过渡,但是这样在父亲组件就会多了一些跟父组件业务无关的属性,耦合度高,借助$attrs可以简化些,而且祖跟孙都无需做修改
grandparent.vue
<template> <section> <parent name="grandparent" sex="男" age="88" hobby="code" @sayknow="sayknow"></parent> </section></template><script> import parent from './parent' export default { name: "grandparent", components: { parent }, data() { return {} }, methods: { sayknow(val){ console.log(val) } }, mounted() { } }</script>
parent.vue
<template> <section> <p>父组件收到</p> <p>祖父的名字:{{name}}</p> <children v-bind="$attrs" v-on="$listeners"></children> </section></template><script> import children from './children' export default { name: "parent", components: { children }, // 父组件接收了name,所以name值是不会传到子组件的 props:['name'], data() { return {} }, methods: {}, mounted() { } }</script>
children.vue
<template> <section> <p>子组件收到</p> <p>祖父的名字:{{name}}</p> <p>祖父的性别:{{sex}}</p> <p>祖父的年龄:{{age}}</p> <p>祖父的爱好:{{hobby}}</p> <button @click="sayknow">我知道啦</button> </section></template><script> export default { name: "children", components: {}, // 由于父组件已经接收了name属性,所以name不会传到子组件了 props:['sex','age','hobby','name'], data() { return {} }, methods: { sayknow(){ this.$emit('sayknow','我知道啦') } }, mounted() { } }</script>
显示结果
父组件收到
祖父的名字:grandparent
子组件收到
祖父的名字:
祖父的性别:男
祖父的年龄:88
祖父的爱好:code
8、孙传祖
借助$listeners中间事件,孙可以方便的通知祖,代码示例见7
9、$parent
通过parent可以获父组件实例,然后通过这个实例就可以访问父组件的属性和方法,它还有一个兄弟root,可以获取根组件实例。
语法:
// 获父组件的数据this.$parent.foo// 写入父组件的数据this.$parent.foo = 2// 访问父组件的计算属性this.$parent.bar// 调用父组件的方法this.$parent.baz()
于是,在子组件传给父组件例子中,可以使用this.$parent.getnum(100)传值给父组件。
10、sessionstorage传值
sessionstorage 是浏览器的全局对象,存在它里面的数据会在页面关闭时清除 。运用这个特性,我们可以在所有页面共享一份数据。
语法:
// 保存数据到 sessionstoragesessionstorage.setitem('key', 'value');// 从 sessionstorage 获取数据let data = sessionstorage.getitem('key');// 从 sessionstorage 删除保存的数据sessionstorage.removeitem('key');// 从 sessionstorage 删除所有保存的数据sessionstorage.clear();
注意:里面存的是键值对,只能是字符串类型,如果要存对象的话,需要使用 let objstr = json.stringify(obj) 转成字符串然后再存储(使用的时候 let obj = json.parse(objstr) 解析为对象)。
这样存对象是不是很麻烦呢,推荐一个库 good-storage ,它封装了sessionstorage ,可以直接用它的api存对象
// localstorage storage.set(key,val) storage.get(key, def) // sessionstorage storage.session.set(key, val) storage.session.get(key, val)
11、vuex
这里我也不打算介绍这个大名鼎鼎的vuex怎么用,因为要把它写清楚篇幅太长了…
如果您不打算开发大型单页应用,使用 vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您也许不需要使用 vuex。
以上就是vue组件传值的方式的详细内容。