Data transfer between components

The father the son props

  1. Data is transmitted between the parent and the child. The data of the parent component is transmitted to the child component through props. The syntax of transmission is the same as that of vue2, but the way the child component receives the data from the parent component is changed.
/ / the parent component<template>
    <Menu :arr="arr"></Menu>
</template>
<script setup>
    const arr = [1.2.3.4.5]
</script>
Copy the code
// Subcomponent menu. vue<script setup>
    import { defineProps } from 'vue'
    const props = defineProps({
        arr: {
            type: Array.required: true}})console.log(props.arr) / / [1, 2, 3, 4, 5]
</script>
Copy the code
  1. Way of passing data above, the parent components inside the array is passed to the son, but sometimes will give reference of child components in the parent component plus some classes, or some other values, but not to pass in the form of props, at the time of child components to receive, such as a class, will the quilt the root element of the receiver, If we include a layer of divs, these classes will not be bound to the desired location, so we need to disable the default setting to the root element when receiving them
/ / child component
<script>
    export default {
        inheritAttrs: false
    }
</script>
Copy the code
  1. Place values that are not passed as props on the specified element
<template>
    <div v-bind="$attrs"></div>
</template>
Copy the code
  1. If you don’t want to put them all on one element, you can specify an attribute
<template>
    <div :id="$attrs.id" ></div>
</template>
Copy the code

V – model and components

  1. In some cases, the value in the parent component and the value in the child component are shared, so v-model bi-directional binding is used. In VUe2, v-model is a combination of @input events and V-bind :value. Bi-directional binding is implemented, but it is limited. So it was rewritten in VUE 3 to be more flexible
    • Discard the input receive mode
    • Use update:modelValue instead of value
/ / the parent component<template>
    <Menu :bool="bool" @update:bool = "bool = $event"` ></Menu>Methods a<Menu v-model:bool = "bool" />Way 2</template>
<script setup>
    const bool = true
</script>
Copy the code
// Subcomponents (mode 1) receive in the same way as (mode 2)<script setup>
    import { defineProps,defineEmits} from 'vue'
    const emit = defineEmits(['update:bool'])
    const props = defineProps({  
        bool: {
            type: Boolean.required: true}})// Send events
    const boolChange = () = > {
        emit('update:bool', parameter)}</script>

Copy the code

Use watch to listen for changes in the props value

  1. Some of the API writing has changed in Vue3, but the actual content is still the same, so be aware of some of the writing changes
<sctipt>
    import { watch,defineProps } from 'vue';
    const props = defineProps({
        bool: {
            type: Boolean,
            required: true
        }
    })
    
    watch(
        () => props.bool,
        (newValue,oldValue) => {
            console.log(newValue,oldValue)
        }
    )
</script>
Copy the code

Child parent emit

  1. The VUE3 neutron component wants to pass data to the parent component
import { defineEmits } from 'vue'

const emit = defineEmits(['Event name'])

const click = () = > {
    emit('Event name', parameter)}Copy the code
  1. Fires directly on HTML elements
<template>
    <button @click="Emit (' event name ')" >Click the trigger button</button>
</template>
<script setup>
    import { defineEmits } from 'vue'
    const emit = defineEmits(['Event name'])
</script>
Copy the code
  1. The parent component receives the same as before
<template>
    <Menu@ The event name sent by the child component ="Parent component registration event name"></Menu>
</template>
Copy the code

Props of slots

  1. For an example of deleting a list, see how the props of a slot are used
/ / the parent component<template>
    <About v-for="item in arrlist" :key="item.id" :item="item" >// Method 1 (slotProps accepts all values, or can access the corresponding values by structuring)<template v-slot:default="slotProps">Receive all passed data {{slotProps}}</template>2 / / way<template #default="{ id }">Receives the specified value {{id}}</template> 
       
       
       <template #default="{ id }">
           <button @click="removeRow(id)">delete</button>
       </template>
       
    </About>
</template>
<script setup>
    import About from './Home.vue'
    import { ref } from 'vue'
    const arr = [
        { id: 1.name: 'css' },
        { id: 2.name: 'html' },
        { id: 3.name: 'js'},]const arrlist = ref([])
    
    const removeRow =(id) = > {
      const idx = arrlist.value.findIndex(x= > x.id == id)
      arrlist.value.splice(idx, 1)}</script>
Copy the code
/ / child component<template>
  <div>
    <p> {{ props.item.id }} --- {{ props.item.name }} </p>// Pass the value of the ID to the parent, which receives it, passes the button to the child slot, and completes the operation<slot :id="props.item.id"></slot>
  </div>
</template>
<script setup>
    import { defineProps } from 'vue'
    const props = defineProps({
        item: {
            type: Object}})</script>
Copy the code

Properties of $slots

  1. Vue3 can use this attribute directly in template via $slots, official: to programmatically access content distributed through slots
  2. $website position of the slots (instance property | Vue. Js (vuejs.org))
  3. The specific content or the official website is more detailed
// derived from element-plus<template v-if=! "" $slots.title">{{ title }}</template>
Copy the code
  1. If you don’t want to use it on elements, you can use it in a way that’s introduced in script, but it’s rarely used, usually more than on elements
// Source official website<script setup>
    import { useSlots } from 'vue'
    const slots = useSlots()
</script>
Copy the code

Recursive components

  1. Recursive components in VUe2 will have an option of name, which can be set to call the component through name to complete the call of recursive components. When there is a lot of data, if there is such a requirement, to loop data of many levels, you can use the way that the component calls itself, call, Under what conditions does v-IF not invoke a series of operations
// Menu.vue
<template>
    <menu></menu>
</template>
<script>
    export default {
        name: 'menu'
    }
</script>
Copy the code
  1. Recursive components in VUe3
    • Methods a
    <template>
        <el-menu-item-group /> // element-plus
    </template>
    <script>
        import { defineComponent } from 'vue'
        export default defineComponent({
            name: 'ElMenuItemGroup'
        })
    </script>
    Copy the code
    • In the second option, there is no way to set the name option because of the setup syntax sugar, but you can import the component and use it by importing the alias
    // Menu.vue
    <template>
        <menu-child></menu-child>
    </template>
    <script setup>
        import { Menu as MenuChild } from './Menu.vue'
    </script>
    Copy the code

Communication across components

  1. In the actual development, sometimes two components that are not father and son or even brothers need to communicate with each other. The first option is vuex to share the state, and another option is to pass the event through eventBus and then pass the value. However, in VUe3, mitt library is officially recommended. He is a lightweight tool library, or relatively easy to use
2. Import Mitt from 'mitt' const emitter = mitt(Copy the code
/ / component A<template>
    <button @click="tabsChange">button</button>
</template>
<script setup>
    import emitter from '@/event/bus'
    
    const tabsChange = () = > {
        emitter.emit('Event name')}</script>
Copy the code
/ / component B<template>
    
</template>
<script setup>
    import emitter from '@/event/bus'
    
    emitter.on('Event name'.(parameter) = >{event handler})</script>
Copy the code
  1. For more information, see Mitt on NPM or Github for more usage

mitt – npm (npmjs.com)

Dynamic components

  1. Vuejs provides us with a component and uses IS to switch between different components and display different components. In fact, it can be introduced at the same time, and v-IF can control the display and hide of components. Since VUejs provides dynamic components, we can look at the way of dynamic components. V-if is frequently switched and not very good in terms of performance, so dynamic components are still necessary
<component :is="Home"></component>
<script setup>
    import Home from '@/components/Home.vue'
    import About from '@/components/About.vue'
</script>
Copy the code
  1. The syntax used in vue2 to control a variable, but I don’t know why, failed in the setup sugar, so I am still looking for how to use the setup sugar………

Provide or inject data penetration

  1. Vue considers such multi-level data transmission problem of nested components and provides provide and inject to complete data penetration of deeply nested components
  2. Since provide or Inject is put into setup in VUe3, we need to introduce them into VUE
// Top-level component<script setup >
    import { provide,ref } from 'vue'
    const name = ref('provide')
    provide('name',name)
</script>
Copy the code
// The underlying component<template>
    <input type="text" v-model="name" / >
    {{ name }}
</template>
<script setup>
    import { inject } from 'vue'
    const name = inject('name') // name is the first parameter in provide
</script>
Copy the code
  1. Pass the method by providing the method to the child component, which calls the method to change the value in the parent component. The top-level component data can be changed only if it is responsive data
// Top-level component<template> {{ name }} </template>
<script setup >
    import { provide,ref } from 'vue'
    const name = ref('provide')
    provide('clickChange'.(newValue) = >name.value = newValue )
</script>
Copy the code
// The underlying component<template>
    <button @click="ClickChange (' child component fires ')">Click on the change</button>
</template>
<script setup>
    import { inject } from 'vue'
    const clickChange = inject('clickChange') // name is the first parameter in provide
</script>
Copy the code