Communication details of 7 components of Vue3


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>