加入收藏 | 设为首页 | 会员中心 | 我要投稿 广西网 (https://www.guangxiwang.cn/)- 分布式数据库、建站、网络、内容创作、业务安全!
当前位置: 首页 > 教程 > 正文

vue组件怎么传值

发布时间:2023-07-12 10:54:24 所属栏目:教程 来源:转载
导读:   这篇文章主要介绍“vue组件如何传值”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue组件如何传值”文章能帮助大家
  这篇文章主要介绍“vue组件如何传值”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue组件如何传值”文章能帮助大家解决问题。
 
  传值方法:1、利用props实现父传子;2、子传父,需要自定义事件,在子组件中用“this.$emit(‘事件名’)”触发,而父中用“@事件名”监听;3、兄弟间,通过公有父元素作为桥接,结合父子props传参、子父自定义事件;4、用路由传值;5、用$ref传值;6、用依赖注入传给后代子孙曾孙;7、利用$attrs;8、借助$listeners中间事件;9、用$parent传等。
 
  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)
 

(编辑:广西网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!