vue 组件之间的常见的几种传值方式
一、父传子 (自定义属性–props)父组件向子组件传值,通过自定义属性的方式进行传值,在子组件中用 props 定义自定义属性,然后在父组件中通过 v-bind 指令把需要传递的数据绑定在子组件上,那在子组件中 props 里面的自定义属性可以直接使用代码演示父组件代码<template><div class="app-container"><h1>App 根
一、父传子 (自定义属性–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 中传值方式,后面会多多补充
更多推荐
所有评论(0)