前端基础开发的组件之间传递数据

一、相邻组件传值(父子之间)

这是组件之间传值中最基础也是最直接的传值关系
1.第一种方法是父组件通过props的方式向子组件传递数据,子组件通过**$emit的方式向父组件进行传递,在父组件用v-on**方法接收
在这里插入图片描述
例如下面这个例子:

首先是父组件:

<template>
  <div>这是父组件的div

    <son v-bind:something="something">这是子组件的自定义组件</son> // 绑定前者是自定义名称便于子组件调用,后者要传递数据名
  </div>
</template>

<script>
import Son from "./son.vue"  //这里首先引入子组件

export default {
  name: Father,
  data() {
    return {
      something: "good",  //这是要传给子组件的数据
    }
  },
  components: {
    "son": Son,  //这里是在引入子组件后相当于实例化的操作
  }
}
</script>

<style>

</style>

然后是子组件:

<template>
  <div>
      这是子组件的div
  </div>
</template>

<script>
export default {
    name: Son,
    // 这里首先要写好props
    props: { 
        // props里面就是需要使用的父组件的数据,字段名要和父组件定义的保持一致
        something: {
            type: String,
            required: true,
        }
    },
    data() {

    }
}
</script>

<style>

</style>

上面是父组件向子组件进行传值,接下来就是子组件向父组件传值,相对操作会更多一些
这次首先看子组件:

<template>
  <div>
    这是子组件的div

    <button @click="transfData">点击我触发发送数据</button>
  </div>
</template>

<script>
export default {
  name: Son,
  // 这里首先要写好props
  props: {
    // props里面就是需要使用的父组件的数据,字段名要和父组件定义的保持一致
    something: {
      type: String,
      required: true,
    },
  },
  data() {
    return {
      otherthing: "nice", //这个是需要传给父组件的数据
    };
  },
  methods: {
    transfData() {
      this.$emit("trans", this.otherthing);
    },
  },
};
</script>

<style>
</style>

然后看父组件:


<template>
  <div>这是父组件的div

    <son
      :trans="trans"  
    >  // 采用v-on方式对子组件提交的数据进行绑定,这里的等号前的名字都要和子组件emit() 里面传的第一个值保持一致, 然后等号后是在methods进行处理的方法名

    这是子组件的自定义组件</son>

  </div>
</template>

<script>
import Son from "./son.vue"  //这里首先引入子组件

export default {
  name: Father,
  data() {
    return {
      something: "good",  //这是要传给子组件的数据
    }
  },
  components: {
    "son": Son,  //这里是在引入子组件后相当于实例化的操作
  },
  methods: {
    // 这里的方法名同样要和绑定的一致,参数val就是子组件emit() 里面传过来的第二个参数
    trans(val) {
      console.log(val);
    }
  }
}
</script>

<style>

</style>

2.第二种方法是采用ref:如果在普通的DOM元素上使用,引用指向的就是DOM元素;如果用在子组件上,引用就指向组件实例,使用后可以直接得到组件实例,使用后可以直接调用组件的方法或访问数据。
举个例子先看父组件:


<template>
  <div>这是父组件的div

    <son
      ref="son" 
    ></son>

  </div>
</template>

<script>
import Son from "./son.vue"  //这里首先引入子组件

export default {
  name: Father,
  mounted() {
    let otherthing = this.$refs.son  //这里用ref实例化一个对象
    console.log(otherthing.say);  //直接用实例化对象调用子组件的属性和方法
    console.log(otherthing.transfData);
  }
}
</script>

<style>

</style>

然后看子组件:

<template>
  <div>
    这是子组件的div
  </div>
</template>

<script>
export default {
  name: Son,
  data() {
    return {
      say: "nice", //这个是需要传给父组件的数据
    };
  },
  methods: {
    transfData() {
      console.log("数据传送成功");
    },
  },
};
</script>

<style>
</style>

这种方法只能在父子组件之间通信,无法跨组件进行通信

二、祖孙组件之间数据传递

1.使用\$attrs和$listeners方法可以进行祖孙组件相互传值
例如,先看祖组件:


<template>
  <div>这是父组件的div

    <son
      :a="a"
      :b="b" 
    ></son>

  </div>
</template>

<script>
import Son from "./son.vue"  //这里首先引入子组件

export default {
  name: Father,
  data: {
    a: 1,
    b: 2,
  },
  components: {
    "son": Son,
  }
}
</script>

<style>

</style>

然后看子组件:

<template>
  <div>
    <div>{{$attrs}}</div>
  </div>
</template>

<script>
export default {
  mounted() {
    console.log(this.$attrs); //{"a":1,"b":2}
  }
}
</script>

<style>
</style>

我理解的是这是对于props的一种简捷写法,因为$attrs可以将父组件v-bind的所有属性打包成一个对象传给自己,不需要再单独写props进行接收和实例化

2.还有一种是使用ref写法,这种组件之间主要适用于祖先组件和子孙后代组件之间,不论组件层次有多深,在上下游关系成立的时间里始终生效,但是不适用于兄弟组件这种非直接关系的组件之间。
比如先看祖组件:

<template>
  <div>
    这是祖组件的div
	  <son
      ref="son" 
    ></son>
  </div>
  
</template>

<script>
import Son from "./son.vue"  //这里首先引入子组件

export default {
  inject: ['something'],
  mounted () {
    console.log(this.something);  // good
  },
  components: {
    "son": Son
  }
}
</script>

<style>
</style>

然后再看子组件:


<template>
  <div>这是子孙组件的div

  </div>
</template>

<script>

export default {
  provide: {
    something: 'good'
  }
}

</script>

<style>

</style>

这种方法类似于父子组件之间通信用的props,在祖组件里面,我们设置一个provide属性,并且设置了一个值,目的就是将这个值传递给所有子孙组件,然后子孙组件通过inject注入祖组件提供的值,然后子孙组件用this.属性名就可以直接获取使用祖组件的值。
但是provide和inject传值并不是响应式的,除了所传递的是一个可监听对象以外,也就是说如果子孙组件接受并使用的祖组件的值,但是之后祖组件这个值发生变化之后子孙组件不会随之变化,如果要使用响应式的传递,最优方法是使用Vue.observable 优化响应式 provide,这个已经是有人在网上讲解过的了,因为我自己还没有用到这个高阶用法,这里就先不做讲述

三、跨组件或非直接关系组件传值

所以目前情况下,在这种需要响应式的跨组件传值以及非直接关系的组件之间传值,我一般使用vuex,接下来讲一下基本的vuex的使用方法以及步骤:
首先在项目目录下找到src\sotre目录:
在这里插入图片描述
目录里面的几个文件含义大概是:
state (类似存储全局变量的数据)
getters (提供用来获取state数据的方法)
actions (提供跟后台接口打交道的方法,并调用mutations提供的方法)
mutations (提供存储设置state数据的方法)
一般情况下,我们需要使用的是getters.js,mutations.js和state.js
首先要在state.js里面定义我们需要传递的字段:

export const state = {
	something: '', // 定义所要进行传值的字段
}

紧接着去mutation.js里面进行设置字段属性值的方法:

export const mutations = {
	setSomething(state, data) {
	state.something = data
}

最后去getter.js里面设置获取字段属性值的方法:

export const something = (state) => {
  return state.something
}

个人理解总结:
父子之间传值:$emit()方法或者ref绑定
祖孙之间传值:$attrs()方法更加便捷和实用
跨组件传值:vuex适用范围更广而且实用性更高

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值