vue 组件之间的常见的几种传值方式

在这里插入图片描述


一、父传子 (自定义属性–props)

父组件向子组件传值,通过自定义属性的方式进行传值,在子组件中用 props 定义自定义属性,然后在父组件中通过 v-bind 指令把需要传递的数据绑定在子组件上,那在子组件中 props 里面的自定义属性可以直接使用

代码演示

父组件代码

<template>
  <div class="app-container">
    <h1>App 根组件</h1>
    <hr />

    <div class="box">
      <!-- 渲染 Son 子组件 -->
      <Son :sonName="uname"></Son>
    </div>
  </div>
</template>

<script>
import Son from './components/Son.vue'
export default {
  components: {
    Son
  },
  data() {
    return {
      uname: 'JavaScript'
    }
  }
}
</script>

<style lang="less">
.app-container {
  padding: 1px 20px 20px;
  background-color: #efefef;
}
.box {
  display: flex;
}
</style>

子组件代码

<template>
  <div class="left-container">
    <h3>Son 子组件</h3>
    <p>{{ sonName }}</p>
  </div>
</template>

<script>
export default {
  props: {
    sonName: String
  }
}
</script>

<style lang="less">
.left-container {
  padding: 0 20px 20px;
  background-color: orange;
  min-height: 250px;
  flex: 1;
}
</style>

在这里插入图片描述


二、子传父 (自定义事件–this.$emit)

子组件向父组件传数据使用自定义事件,vue 组件为我们提供了一个 $emit 方法,使用方式 (this.$emit('自定义事件名', 传递的数据)),子组件传递数据时,触发相应的事件函数,就会自动触发通过 $emit 给父组件绑定的自定义事件,自定义事件接收一个参数,参数就是子组件传递过来的数据

代码演示

父组件代码

<template>
  <div class="app-container">
    <h1>App 根组件</h1>
    <hr />
    <p>{{ perSay }}</p>

    <div class="box">
      <!-- 渲染 Son 子组件 -->
      <Son @pass-value="valueFn"></Son>
    </div>
  </div>
</template>

<script>
import Son from './components/Son.vue'
export default {
  components: {
    Son
  },
  data() {
    return {
      perSay: ''
    }
  },
  methods: {
    valueFn(val) {
      this.perSay = val
    }
  }
}
</script>

<style lang="less">
.app-container {
  padding: 1px 20px 20px;
  background-color: #efefef;
}
.box {
  display: flex;
}
</style>

子组件代码

<template>
  <div class="left-container">
    <h3>Son 子组件</h3>
    <button @click="passFn">点击向父组件传值</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      say: 'hello vue.js'
    }
  },
  methods: {
    passFn() {
      this.$emit('pass-value', this.say)
    }
  }
}
</script>

<style lang="less">
.left-container {
  padding: 0 20px 20px;
  background-color: orange;
  min-height: 250px;
  flex: 1;
}
</style>

在这里插入图片描述


三、兄弟之间传值 (eventBus)

兄弟组件之间的数据传递,通过 eventBus 来做中间的桥梁,传输方通过 Bus.$emit('自定义事件名', 数据)传数据,接收方通过 Bus.$on('自定义事件名', callback)接收数据,两者之间的自定义属性名保持一致

代码演示

兄弟组件传输数据的桥梁(eventBus.js)

import Vue from 'vue'
export default new Vue()

left 组件(传输方)

<template>
  <div class="left-container">
    <h3>Left 组件</h3>
    <hr />
    <button @click="passFn">点击向 Right 组件传值</button>
  </div>
</template>

<script>
import Bus from '@/EventBus.js'
export default {
  data() {
    return {
      say: 'hello vue.js'
    }
  },
  methods: {
    passFn() {
      Bus.$emit('pass-value', this.say)
    }
  }
}
</script>

<style lang="less">
.left-container {
  padding: 0 20px 20px;
  background-color: orange;
  min-height: 250px;
  flex: 1;
}
</style>

right 组件(接收方)

<template>
  <div class="right-container">
    <h3>Right 组件</h3>
    <hr />
    <!--数据渲染-->
    <p>{{ sibilingValue }}</p>
  </div>
</template>

<script>
import Bus from '@/EventBus.js'
export default {
  data() {
    return {
      sibilingValue: ''
    }
  },
  created() {
    Bus.$on('pass-value', val => {
      this.sibilingValue = val
    })
  }
}
</script>

<style lang="less">
.right-container {
  padding: 0 20px 20px;
  background-color: lightskyblue;
  min-height: 250px;
  flex: 1;
}
</style>

在这里插入图片描述


四、通过 Vuex 数据共享

通过 Vuex 存储数据,Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理数据,以相应的规则保证状态以一种可预测的方式发生变化,一变全变,同步更新数据

代码演示

Vuex — store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
// 注册 Vuex
Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 100
  },
  mutations: {
    addCount(state, val = 1) {
      state.count += val
    },
    subCount(state, val = 1) {
      state.count -= val
    }
  }
})

export default store

根组件

引入,注册,使用组件

<template>
  <div class="app-container">
    <h1>App 根组件</h1>
    <hr />

    <div class="box">
      <!-- 渲染 Left 组件和 Right 组件 -->
      <Left></Left>
      <Right></Right>
    </div>
  </div>
</template>

<script>
import Left from './components/Left.vue'
import Right from './components/Right.vue'
export default {
  components: {
    Left,
    Right
  }
}
</script>

<style lang="less">
.app-container {
  padding: 1px 20px 20px;
  background-color: #efefef;
}
.box {
  display: flex;
}
</style>

left 子组件

<template>
  <div class="left-container">
    <h3>Left 组件 -- {{ count }}</h3>
    <hr />
    <button @click="add">+1</button>
  </div>
</template>

<script>
import { mapState } from 'vuex'
export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    add() {
      this.$store.commit('addCount')
    }
  }
}
</script>

<style lang="less">
.left-container {
  padding: 0 20px 20px;
  background-color: orange;
  min-height: 250px;
  flex: 1;
}
</style>

right 子组件

<template>
  <div class="right-container">
    <h3>Right 组件 -- {{ count }}</h3>
    <hr />
    <button @click="sub">-1</button>
  </div>
</template>

<script>
import { mapState } from 'vuex'
export default {
  computed: {
    ...mapState(['count'])
  },
  methods: {
    red() {
      this.$store.commit('subCount')
    }
  }
}
</script>

<style lang="less">
.right-container {
  padding: 0 20px 20px;
  background-color: lightskyblue;
  min-height: 250px;
  flex: 1;
}
</style>

在这里插入图片描述


五、通过 v-model 传递数据

通过 v-model 双向数据绑定也可以实现组建之间的传值,v-model 除了能够绑定在 input 框上,也能绑定到组件上

<input type="text" v-model="text" />
// 等同于
<input type="text" :value="text" @input="val => text = val" />
代码演示

父组件

<template>
  <div class="app-container">
    <h1>App 根组件</h1>

    <input type="text" v-model="say" />
    <hr />
    <div class="box">
      <!-- 渲染 Son 子组件 -->
      <Son v-model="say"></Son>
    </div>
  </div>
</template>

<script>
import Son from './components/Son.vue'
export default {
  components: {
    Son
  },
  data() {
    return {
      say: 'hello vue.js'
    }
  }
}
</script>

<style lang="less">
.app-container {
  padding: 1px 20px 20px;
  background-color: #efefef;
}
.box {
  display: flex;
}
</style>

Son 子组件

<template>
  <div class="left-container">
    <h3>Son 子组件</h3>
    <hr />
    <p>{{ value }}</p>
  </div>
</template>

<script>
export default {
  props: {
    value: String
  }
}
</script>

<style lang="less">
.left-container {
  padding: 0 20px 20px;
  background-color: orange;
  min-height: 250px;
  flex: 1;
}
</style>

同理,子组件也可以向父组件传递数据

在这里插入图片描述


六、通过 ref/refs 传数据

ref 引用可以作用在 h5 标签上,也可作用在组件标签上,作用在 h5 标签上是获取的是 DOM 对象, 作用在组件标签上,通过this.$refs获取的是组建实例对象

代码演示

父组件

<template>
  <div class="app-container">
    <h1>App 根组件 --- {{ value }}</h1>
    <button @click="refFn">点击拿数据</button>
    <hr />
    <div class="box">
      <!-- 渲染 Left 组件和 Right 组件 -->
      <Son ref="son"></Son>
    </div>
  </div>
</template>

<script>
import Son from './components/Son.vue'
export default {
  components: {
    Son
  },
  data() {
    return {
      value: ''
    }
  },
  methods: {
    refFn() {
      this.value = this.$refs.son.say
    }
  }
}
</script>

<style lang="less">
.app-container {
  padding: 1px 20px 20px;
  background-color: #efefef;
}
.box {
  display: flex;
}
</style>

Son 子组件

<template>
  <div class="left-container">
    <h3>Son 子组件</h3>
    <hr />
  </div>
</template>

<script>
export default {
  data() {
    return {
      say: 'hello vue.js'
    }
  }
}
</script>

<style lang="less">
.left-container {
  padding: 0 20px 20px;
  background-color: orange;
  min-height: 250px;
  flex: 1;
}
</style>

在这里插入图片描述


这里只列举了 6 中传值方式,后面会多多补充

  • 11
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值