Communication details of 7 components of Vue3
- 2021-11-24 00:46:39
- OfStack
1. Communication mode of Vue3 component
props
$emit
expose / ref
$attrs
v-model
provide / inject
Vuex
2. Vue3 communication usage writing
2.1 props
Use
props
There are two ways to pass data to subcomponents, as follows
Method 1: Mixed writing
// Parent.vue Transmission
<child :msg1="msg1" :msg2="msg2"></child>
<script>
import child from "./child.vue"
import { ref, reactive } from "vue"
export default {
data(){
return {
msg1:" This is the information of the passing subcomponent 1"
}
},
setup(){
// Create 1 Responsive data
// Writing style 1 Applicable to underlying types ref There are other uses, which are described in the following chapters
const msg2 = ref(" This is the information of the passing subcomponent 2")
// Writing style 2 Applicable to complex types, such as arrays, objects
const msg2 = reactive([" This is the information of the passing subcomponent 2"])
return {
msg2
}
}
}
</script>
// Child.vue Receive
<script>
export default {
props: ["msg1", "msg2"],// If this line is not written, it will not be received below
setup(props) {
console.log(props) // { msg1:" This is the information passed to the child component 1", msg2:" This is the information passed to the child component 2" }
},
}
</script>
Method 2: Pure Vue3 writing
// Parent.vue Transmission
<child :msg2="msg2"></child>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const msg2 = ref(" This is the information passed to the child component 2")
// Or complex types
const msg2 = reactive([" This is the information of the passing subcomponent 2"])
</script>
// Child.vue Receive
<script setup>
// There is no need to introduce Direct use
// import { defineProps } from "vue"
const props = defineProps({
// Writing style 1
msg2: String
// Writing style 2
msg2:{
type:String,
default:""
}
})
console.log(props) // { msg2:" This is the information of the passing subcomponent 2" }
</script>
Note:
If the parent component is mixed, the child component is pure
Vue3
If written, it cannot be received in the parent component
data
You can only receive the attributes passed from the setup function in the parent component
If the parent component is pure
Vue3
Writing method, mixed writing method of subcomponents, which can be passed
props
Received
data
And
setup
Function, but if a child component is received in setup, it can only be received in the parent component
setup
The property in the function cannot receive the property in data
The official also said that since 3 is used, don't write 2, so mixed writing is not recommended. In the following example, Law 1 is only written in pure Vue3, so it is not written in mixed writing
2.2 $emit
//Child. vue Distribution
<
template
>
//Writing 1
<
button @click="emit('myClick')"
>
Button
<
/buttom
>
//Writing 2
<
button @click="handleClick"
>
Button
<
/buttom
>
<
/template
>
<
script setup
>
//Method 1 is applicable to Vue version 3.2 without introduction
// import { defineEmits } from "vue"
//Corresponding writing 1
const emit = defineEmits(["myClick","myClick2"])
//Corresponding writing 2
const handleClick = ()=
>
{
emit ("myClick", "This is the message sent to the parent component")
}
//Method 2 does not apply to Vue version 3.2, which useContext () is obsolete
import { useContext } from "vue"
const { emit } = useContext()
const handleClick = ()=
>
{
emit ("myClick", "This is the message sent to the parent component")
}
<
/script
>
// Parent.vue Response
<template>
<child @myClick="onMyClick"></child>
</template>
<script setup>
import child from "./child.vue"
const onMyClick = (msg) => {
console.log(msg) // This is the message received by the parent component
}
</script>
2.3 expose / ref
The parent component gets the properties of the child component or calls the child component method
// Child.vue
<script setup>
// Method 1 Not applicable to Vue3.2 Version, which version useContext() Abandoned
import { useContext } from "vue"
const ctx = useContext()
// Expose attribute methods to the outside world, etc.
ctx.expose({
childName: " This is the property of the child component ",
someMethod(){
console.log(" This is the method of the subcomponent ")
}
})
// Method 2 Applicable to Vue3.2 Version , There is no need to introduce
// import { defineExpose } from "vue"
defineExpose({
childName: " This is the property of the child component ",
someMethod(){
console.log(" This is the method of the subcomponent ")
}
})
</script>
// Parent.vue Attention ref="comp"
<template>
<child ref="comp"></child>
<button @click="handlerClick"> Button </button>
</template>
<script setup>
import child from "./child.vue"
import { ref } from "vue"
const comp = ref(null)
const handlerClick = () => {
console.log(comp.value.childName) // Gets externally exposed properties of child components
comp.value.someMethod() // Calling methods exposed by subcomponents
}
</script>
2.4 attrs
attrs
Contains the division in the parent scope
class
And
style
Except non-
props
Attribute collection
// Parent.vue Transmission
<child :msg1="msg1" :msg2="msg2" title="3333"></child>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const msg1 = ref("1111")
const msg2 = ref("2222")
</script>
// Child.vue Receive
<script setup>
import { defineProps, useContext, useAttrs } from "vue"
// 3.2 Version does not need to be introduced defineProps , directly use
const props = defineProps({
msg1: String
})
// Method 1 Not applicable to Vue3.2 Version, which version useContext() Abandoned
const ctx = useContext()
// If it doesn't work props Receive msg1 The words are { msg1: "1111", msg2:"2222", title: "3333" }
console.log(ctx.attrs) // { msg2:"2222", title: "3333" }
// Method 2 Applicable to Vue3.2 Version
const attrs = useAttrs()
console.log(attrs) // { msg2:"2222", title: "3333" }
</script>
2.5 v-model
Multiple data bidirectional bindings can be supported
// Parent.vue
<child v-model:key="key" v-model:value="value"></child>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const key = ref("1111")
const value = ref("2222")
</script>
// Child.vue
<template>
<button @click="handlerClick"> Button </button>
</template>
<script setup>
// Method 1 Not applicable to Vue3.2 Version, which version useContext() Abandoned
import { useContext } from "vue"
const { emit } = useContext()
// Method 2 Applicable to Vue3.2 Version, there is no need to introduce
// import { defineEmits } from "vue"
const emit = defineEmits(["key","value"])
// Usage
const handlerClick = () => {
emit("update:key", " New key")
emit("update:value", " New value")
}
</script>
2.6 provide / inject
provide / inject
Inject for dependency
expose / ref
0
Allows us to specify the data that we want to provide to future generations of components or
expose / ref
1
Receives data from any descendant component that you want to add to the component, no matter how deeply the component is nested
// Parent.vue
<script setup>
import { provide } from "vue"
provide("name", " Mu Hua ")
</script>
// Child.vue
<script setup>
import { inject } from "vue"
const name = inject("name")
console.log(name) // Mu Hua
</script>
2.7 Vuex
// store/index.js
import { createStore } from "vuex"
export default createStore({
state:{ count: 1 },
getters:{
getCount: state => state.count
},
mutations:{
add(state){
state.count++
}
}
})
// main.js
import { createApp } from "vue"
import App from "./App.vue"
import store from "./store"
createApp(App).use(store).mount("#app")
// Page.vue
// Method 1 Direct use
<template>
<div>{{ $store.state.count }}</div>
<button @click="$store.commit('add')"> Button </button>
</template>
// Method 2 Get
<script setup>
import { useStore, computed } from "vuex"
const store = useStore()
console.log(store.state.count) // 1
const count = computed(()=>store.state.count) // The response will follow the vuex The data changes and changes
console.log(count) // 1
</script>