站长资讯网
最全最丰富的资讯网站

vue组件怎么传值

传值方法:1、利用props实现父传子;2、子传父,需要自定义事件,在子组件中用“this.$emit(‘事件名’)”触发,而父中用“@事件名”监听;3、兄弟间,通过公有父元素作为桥接,结合父子props传参、子父自定义事件;4、用路由传值;5、用$ref传值;6、用依赖注入传给后代子孙曾孙;7、利用$attrs;8、借助$listeners中间事件;9、用$parent传等。

vue组件怎么传值

本教程操作环境:windows7系统、vue3版,DELL G3电脑。

本篇文章带大家聊聊vue组件传值的10种方式,常用的也有五六种,先上一张总结图:

vue组件怎么传值

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>     <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>
登录后复制

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 是浏览器的全局对象,存在它里面的数据会在页面关闭时清除 。运用这个特性,我们可以在所有页面共享一份数据。

语法:

// 保存数据到 sessionStorage sessionStorage.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)
登录后复制

赞(0)
分享到: 更多 (0)