vue组传值件

d

1.父传子

父组件内容

<template>
  <div class="about">
    <!-- 基本数据类型 -->
   <!-- <Add :ms="msg"></Add> -->
   <!-- <Add :msg-val="msgs"></Add> -->
   <!-- 引用数据类型 -->
   <Add :msg-vals="posts"></Add>
  </div>
</template>
<script>
// 两种组件的注册类型:全局注册和局部注册
import Add from "../components/add.vue";
export default {
  components: {
    Add,
  },
  data() {
    return {
       msg: "gg",//【基本数据类型】
       msgs:"国剧盛典",
      //  msgss: [1,2,3],

      posts: [
      { id: 1, title: 'My journey with Vue' },
      { id: 2, title: 'Blogging with Vue' },
      { id: 3, title: 'Why Vue is so fun' }
    ]
    };
  },
  methods: {},
};
</script>

子组件内容

<template>
<div class="button-counte">
<!-- <p>{{ms}}</p> -->
<!-- <p>{{msgVal}}</p> -->
<p v-for="(item,index) in  msgVals" :key="index">
    {{item.id}}&emsp;{{item.title}}
</p>
</div>
</template>
<script>
export default {
    data(){
        return {
          
        }
    },
    //子组件通过props接收
    // props: ['ms'],
    // props: ['msgVal'],//需要特别注意,父组件传的是msg-val要将其转化为msgVal(驼峰命名)
    props: ['msgVals']
}
</script>

注意:父子组件传值,数据是异步请求,有可能数据渲染时报错:
原因:异步请求时,数据还没有获取到但是此时已经渲染节点了
解决方案:可以在父组件需要传递数据的节点加上 v-if = isReady(isReady默认为false),异步请求获取数据后(isReady赋值为true),v-if = isRead
2.子传父

子组件

<template>
  <div class="button-counte">
    <!-- 子组件有一个buttton按钮,并为其添加了一个click事件,
    当点击的时候使用$emit()触发事件,把 “子-儿子” 这几个字传给父组件。 -->
    <button @click="fun()">子传父</button>
  </div>
</template>
<script>
export default {
  data() {
    return {};
  },
  methods: {
    fun() {
      // 当点击按钮后,就会执行子组件中的点击事件,
      // 然后就会自动触发childEvent自定义事件,
      // 然后在触发父组件中的方法,进行相应的操作
      //$emit有2个参数:第一个参数为自定义事件,得个参数为要传过去的值
      this.$emit("childEvent", "子-儿子");
    },
  },
};
</script>


父组件

<template>
  <div class="about">
    <p>{{ textval }}</p>
    <!-- 父组件在组件上定义了一个自定义事件childEvent,事件名为parentEvent用于接受子组件传过来的val值 -->
    <Add @childEvent="parentEvent"></Add>
  </div>
</template>
<script>
// 两种组件的注册类型:全局注册和局部注册
import Add from "../components/add.vue";
export default {
  components: {
    Add,
  },
  data() {
    return {
      textval: "父-父亲",
    };
  },
  methods: {
    parentEvent(val) {
      //val就是从子组件传过来的值
      this.textval = val;
    },
  },
};
</script>

在子组件中 通过$emit方法传递参数:子组件有一个buttton按钮,并为其添加了一个click事件,当点击的时候使用$emit()触发事件,把 “子-儿子” 这几个字传给父组件。

在父组件中:父组件在组件上定义了一个自定义事件childEvent,事件名为parentEvent用于接受子组件传过来的value值。

3.兄弟传值

Vue 没有直接子对子传参的方法,建议将需要传递数据的子组件,都合并为一个组件。如果一定需要子对子传参,可以先从传到父组件,再传到子组件。

或者通过eventBus或vuex(小项目少页面用eventBus,大项目多页面使用 vuex)传值:

这里具体说的是通过事件总线来传值:
大致实现方法:

 var Event = new Vue();       //中心事件的调度剂
    Event.$emit(事件名,数据);     触发当前实例上的事件,并传一个参数       
    Event.$on(事件名,回调函数);     监听event事件后运行 */    
            
   //$emit 相当于一个触发事件,在on_change事件触发后,my_say事件自动触发
 

通过创建一个单独的js文件event.js实现

(1)新建js文件夹及event.js文件

import Vue from 'vue'
export default new Vue;

(2)第一个组件

<template>
   <section>
        <div @click="pushMsg">push message</div>
        <br>
    </section>
</template>
<script>
import eventBus from "../utis/eventbus"
export default {
  name:"Add",
  data(){
      return {
         childNum:0
      }
  },
 methods: {
     pushMsg(){
            	// 通过事件总线发送消息
                eventBus.$emit('pushMsg',this.childNum++)
            }
  },
}
</script>

(3)第二个组件

<template>
<section>
        children1传过来的消息:{{msg}}
    </section>
</template>
<script>
import eventBus from "../utis/eventbus"
export default {
  name:"Son",
  data(){
    return {
      msg:""
    }
  },
   mounted() {
        	// 通过事件总线监听消息
            eventBus.$on('pushMsg', (children1Msg) => {
                this.msg = children1Msg
            })
        }

  

}
</script>
<style>

</style>

(3)父组件

<template>
  <div id="app">

  <Add></Add>
  <Son></Son>
   
  </div>
</template>
<script>
  import Add from "./components/add.vue"
  import Son from "./components/Son.vue"

export default {
  name: 'App',
  components: {
    Add,
    Son
  },
    data() {
    return {  
     
    };
  },
  methods: {
    
  },

}
</script>

<style>

</style>

最后,在总结一下兄弟组件传值的流程:

1、兄弟之间传递数据需要借助于事件总线,通过事件总线的方式传递数据
2、创建一个Vue的实例,让各个兄弟共用同一个事件机制。
3、通过 $emit 发射出事件,触发当前实例上的事件,并传一个参数
3、$on监听event事件后运行,通过一个事件触发bus.on(事件名,function(接收数据的参数){用该组件的数据接收传递过来的数据}),此时函数中的this已经发生了改变,可以使用箭头函数。
方法三:

其实传值还可以通过 vuex 和设置 Session Storage缓存的形式进行传递

const orderData = { 'orderId': 123, 'price': 88 } 
// 存值
sessionStorage.setItem('缓存名称', JSON.stringify(orderData))
// 取值  (在另一个组件取出)
const dataB = JSON.parse(sessionStorage.getItem('缓存名称'))
 

 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可以简化些,而且祖跟孙都无需做修改。

8.孙传祖

9.$parent

10.sessionStorage传值

11.vex

     

      

      

     

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值