vue Several common value transfer methods between components
One 、 Father's son ( Custom properties --props)
The parent component passes values to the child component , Pass values through custom attributes , Use... In a subcomponent props Define custom properties , Then in the parent component through v-bind The instruction binds the data to be passed to the sub component , That's in the subassembly props The custom attributes inside can be used directly
Code demonstration
Parent component code
<template>
<div class="app-container"> <h1>App The root component </h1> <hr /> <div class="box"> <!-- Rendering Son Child components --> <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>
Copy code
Subcomponent code
<template>
<div class="left-container"> <h3>Son Child components </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>
Copy code
Two 、 Son father ( Custom events --this.$emit)
The child component transmits data to the parent component using a custom event ,vue Component provides us with a $emit
Method , Usage mode (this.$emit(' Custom event name ', Data transferred )
), When a subcomponent passes data , Trigger the corresponding event function , Will automatically trigger through $emit
Custom events bound to parent components , Custom events receive a parameter , Parameters are the data passed by the sub components
Code demonstration
Parent component code
<template>
<div class="app-container"> <h1>App The root component </h1> <hr /> <p>{{ perSay }}</p> <div class="box"> <!-- Rendering Son Child components --> <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>
Copy code
Subcomponent code
<template>
<div class="left-container"> <h3>Son Child components </h3> <button @click="passFn"> Click to pass the value to the parent component </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>
Copy code
3、 ... and 、 Pass values between brothers (eventBus)
Data transfer between sibling components , adopt eventBus To be a bridge in the middle , The transmitting party passes Bus.$emit(' Custom event name ', data )
The data transfer , The receiver passes Bus.$on(' Custom event name ', callback)
receive data , The custom attribute names between the two are consistent
Code demonstration
A bridge for brother components to transmit data (eventBus.js)
import Vue from 'vue'
export default new Vue()
Copy code
left Components ( Transmitter )
<template>
<div class="left-container"> <h3>Left Components </h3> <hr /> <button @click="passFn"> Click to Right Component transfer value </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>
Copy code
right Components ( The receiving party )
<template>
<div class="right-container"> <h3>Right Components </h3> <hr /> <!-- Data rendering --> <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>
Copy code
Four 、 adopt Vuex Data sharing
adopt Vuex Store the data ,Vuex Is a special for Vue.js Application development State management mode . It uses Centralized Storage management data , Ensure that the state changes in a predictable way with corresponding rules , One change, all change , Update data synchronously
Code demonstration
Vuex --- store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
// register 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
Copy code
The root component
introduce , register , Use components
<template>
<div class="app-container"> <h1>App The root component </h1> <hr /> <div class="box"> <!-- Rendering Left Components and Right Components --> <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>
Copy code
left Child components
<template>
<div class="left-container"> <h3>Left Components -- {{ 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>
Copy code
right Child components
<template>
<div class="right-container"> <h3>Right Components -- {{ 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>
Copy code
5、 ... and 、 adopt v-model To transfer data
adopt v-model Bidirectional data binding can also realize value transfer between components ,v-model In addition to being able to bind to input On the frame , It can also be bound to components
<input type="text" v-model="text" />
// Equate to
<input type="text" :value="text" @input="val => text = val" />
Copy code
Code demonstration
Parent component
<template>
<div class="app-container"> <h1>App The root component </h1> <input type="text" v-model="say" /> <hr /> <div class="box"> <!-- Rendering Son Child components --> <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>
Copy code
Son Child components
<template>
<div class="left-container"> <h3>Son Child components </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>
Copy code
Empathy , Child components can also pass data to parent components
6、 ... and 、 adopt ref/refs The data transfer
ref References can act on h5 On the label , It can also act on component labels , It works on h5 On the label is obtained is DOM object , Act on component labels , adopt this.$refs
Get the build instance object
Code demonstration
Parent component
<template>
<div class="app-container"> <h1>App The root component --- {{ value }}</h1> <button @click="refFn"> Click to get data </button> <hr /> <div class="box"> <!-- Rendering Left Components and Right Components --> <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>
Copy code
Son Child components
<template>
<div class="left-container"> <h3>Son Child components </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>
Copy code
Here is just a list of 6 Intermediate value transmission mode , More will be added later