Communication details of 7 components of Vue3

  • 2021-11-24 00:46:39
  • OfStack

Directory 1, Vue3 component communication mode 2, Vue3 communication usage writing 2.1 props2.2 $emit2.3 expose/ref2.4 attrs2.5 v-model2.6 provide/inject2.7 Vuex

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>


Related articles: