vue——组件传值

1.父传子

父->子

  • props父子 使用场景: 电商 (松耦合)

  • $parent 子抓父 使用场景: 通用组件(紧耦合)

      <子 :自定义属性="父数据"></..>
      子组件:
        选项
        props:['自定义属性']   props:{自定义属性:{type/default/required/...}}
      展示:	子模板	{
         
         {自定义属性}}
    
      注意: props是只读的
    
      props命名:
        props: ['postTitle']
        <xx post-title="hello!"></xx>
      单向下行绑定: 父级 prop 的更新会向下流动到子组件中,但是反过来则不行
        在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态
    

关系:

  • App -> ChildA -> ChildC
  • App -> ChildB

App.vue

  • 通过v-bind绑定要传过去的自定义属性
<template>
  <div id="app">
	   <h3>app</h3>
	   <ChildA :msgApp="msgapp"></ChildA>
	   <ChildB></ChildB>
  </div>
</template>

<script>
import ChildA from './components/ChildA'
import ChildB from './components/ChildB'

export default {
    
    
  name:'app',
  data(){
    
    
    return{
    
    
      msgapp:'app数据'
    }
  },
  components:{
    
    
    ChildA,ChildB
  },
  methods:{
    
    
    show(){
    
    console.log('app_show')}
  }
}
</script>

<style>

</style>

ChildA.vue

  • 用props来接收自定义属性
  • 可以将接收过来的值依次传给它的子
<template>
  <div class='child-a'>
    <h3>child-a</h3>
   <ChildC :msgA="msga" :msg_App="msgApp"></ChildC>

  </div>
</template>

<script>
import ChildC from './ChildC'
export default{
    
    
  data(){
    
    
    return{
    
    
      msga:'child-a的数据'
    }
  },
  props:['msgApp'],
  components:{
    
    
    ChildC
  }
}
</script>

<style>
.child-a{
    
    
  background:blue;
}
</style>

ChildC.vue

<template>
  <div class='child-c'>
    <h3>child-c</h3>
    {
    
    {
    
    msg_App}}/{
    
    {
    
    msgA}}/{
    
    {
    
    msgc}}
  </div>
</template>

<script>
export default{
    
    
  data(){
    
    
    return{
    
    
      msgc:'child-c的数据'
    }
  },
  props:['msgA','msg_App']
}
</script>

<style>
.child-c{
    
    
  background:yellow;
}
</style>

ChildB.vue

  • 直接通过this.$parent来抓取父的值,其中this可以省略
  • 同时还可以利用this.$parent来调用父的方法
<template>
  <div class='child-b'>
    <h3>child-b</h3>
    {
    
    {
    
    this.$parent.msgapp}}
  </div>
</template>

<script>
export default{
    
    
  data(){
    
    
    return{
    
    
      msgb:'child-b的数据'
    }
  },
  mounted(){
    
    
    console.log(this.$parent)
    console.log('this可以省略,parent指向父',this.$parent.msgapp)
    //调用父的方法
    this.$parent.show()
  }
}
</script>

<style>
.child-b{
    
    
  background:green;
}
</style>

2.子传父

子->父

扫描二维码关注公众号,回复: 17191845 查看本文章
  • 自定义事件$emit 使用场景: 电商 (松耦合)

  • $ ref 引用dom元素/$children 父抓子 使用场景: 通用组件(紧耦合)

    子->父  事件(自定义)
      <子 @自定义事件="父方法"></..>
      子:		this.$emit('自定义事件',子.数据名)
      父:		methods-> 父方法(接受数据){处理}
    
      始终使用 kebab-case 的事件名
    
    父子之间共享数据和方法
      <子 ref="自定义子名称"></..>
    
      父访问子:	this.$refs.自定义子名称.数据名/方法()
      子访问父:	this.$parent.数据名/方法()
    
      $refs 只会在组件渲染完成之后生效,并且它们不是响应式的,避免在模板或计算属性中访问 $refs
    

关系:

  • App -> ChildA -> ChildC
  • App -> ChildB

ChildA.vue

  • 父中写一个自定义事件,同时还要在data里面自定义一个数据,便于拿取子中用$emit传过来的值
<template>
  <div class='child-a'>
    <h3>child-a</h3>
    {
    
    {
    
    msg_c}}
    <ChildC  @send_childc="updateChildC"></ChildC>
  </div>
</template>

<script>
import ChildC from './ChildC'
export default{
    
    
  data(){
    
    
    return{
    
    
      msga:'child-a的数据',
      msg_c:'-'
    }
  },
  components:{
    
    
    ChildC
  },
  methods:{
    
    
    updateChildC(data){
    
    
      console.log('ChildA收到了数据',data),
      this.msg_c=data
    }
  },
}
</script>

<style>
.child-a{
    
    
  background:blue;
}
</style>

ChildC.vue

  • 用$emit来接收自定义事件,并将data返回给父级
<template>
  <div class='child-c'>
    <h3>child-c</h3>
  </div>
</template>

<script>
export default{
    
    
  data(){
    
    
    return{
    
    
      msgc:'child-c的数据'
    }
  },
  mounted(){
    
    
  this.$emit('send_childc',this.msgc)
  }
}
</script>

<style>
.child-c{
    
    
  background:yellow;
}
</style>

App.vue

  • this.$children可以直接在父中拿到子的数据,它返回来的是一个数组
  • this.$refs可以直接给组件命名,这样在拿数据的时候可以直接拿去,比上者更简便些
<template>
  <div id="app">
	  <h3>app</h3>
	  {
    
    {
    
    msg_a}}/{
    
    {
    
    msg_b}}
	  <ChildA ref="a"></ChildA>
	  <ChildB ref="b"></ChildB>
  </div>
</template>

<script>

import ChildA from './components/ChildA'
import ChildB from './components/ChildB'

export default {
    
    
  name:'app',
  data(){
    
    
    return{
    
    
      msgapp:'app数据',
      msg_a:'-',
      msg_b:'-',
    }
  },
  components:{
    
    
    ChildA,ChildB
  },
  methods:{
    
    },
  mounted(){
    
    
    //console.log('app',this.$children);  //访问子,返回的是数组
    //this.msg_b = this.$children[1].msgb;

    //可以用$children也可以用$refs,$children稍微麻烦点,因为还有算组件所处位置;$refs是先把组件命名,再根据命名来获取对应的值

    console.log("app",this.$refs);
    this.msg_b = this.$refs.b.msgb;
    this.$refs.b.show();

    this.msg_a = this.$refs.a.msga;
  }
}

</script>

ChildB.vue

<template>
  <div class='child-b'>
    <h3>child-b</h3>
  </div>
</template>

<script>
export default{
    
    
  data(){
    
    
    return{
    
    
      msgb:'child-b的数据'
    }
  },
  mounted(){
    
    },
  methods:{
    
    
    show(){
    
    
      console.log("b组件的函数")
    }
  }
}
</script>

<style>
.child-b{
    
    
  background:green;
}
</style>

3.兄弟传兄弟

兄弟->兄弟
兄弟A->自定义事件->中间人(父)->props->兄弟B

4.爷传孙

A->...-> C
     A作为祖先传递,C作为后代接受
     <中间层组件 v-bind="$attrs" v-on="$listeners"></..>
     $attrs 如果中间层组件没有接受props,给c的是所有props
     $listeners 如果中间层组件没有触发,给c的是所有自定义事件

关系:

  • App -> ChildA -> ChildC

App.vue

  • 作为根,将要传的属性和事件写在中间的组件,利用中间的组件ChildA能承上启下而传给孙
<template>
  <div id="app">
   <h3>app</h3>
   {
    
    {
    
    msg_c}}
   <ChildA :msgApp="msgapp" @send_childc="updateChildC"></ChildA>
  </div>
</template>

<script>

import ChildA from './components/ChildA'

export default {
    
    
  name:'app',
  data(){
    
    
    return{
    
    
      msgapp:'app数据',
      msg_c:'-'
    }
  },
  components:{
    
    
    ChildA,
  },
  methods:{
    
    
    updateChildC(data){
    
    
      console.log('app收到了数据',data),
      this.msg_c=data
    }
  },
  mounted(){
    
    }
}

</script>

ChildA.vue

  • 作为中间组件,来实现传递,传递给哪个组件记得要写上 v-bind="$ attrs" v-on="$listeners"
<template>
  <div class='child-a'>
    <h3>child-a</h3>
    <ChildC v-bind="$attrs" v-on="$listeners"></ChildC>
  </div>
</template>

<script>
import ChildC from './ChildC'
export default{
    
    
  data(){
    
    
    return{
    
    
      msga:'child-a的数据',
    }
  },
  components:{
    
    
    ChildC
  },
  methods:{
    
    },
  mounted(){
    
    }
}
</script>

<style>
.child-a{
    
    
  background:blue;
}
</style>

ChildC.vue

  • 为孙组件,需要用到props和$emit
<template>
  <div class='child-c'>
    <h3>child-c</h3>
    {
    
    {
    
    msgApp}}
  </div>
</template>

<script>
export default{
    
    
  data(){
    
    
    return{
    
    
      msgc:'child-c的数据'
    }
  },
  props:['msgApp'],
  mounted(){
    
    
    this.$emit('send_childc',this.msgc)
  }
}
</script>

<style>
.child-c{
    
    
  background:yellow;
}
</style>

猜你喜欢

转载自blog.csdn.net/Start_t/article/details/105787268