El componente padre-hijo de vue3 pasa valor; el componente hijo de vue3 pasa valor al componente padre; el componente hijo de vue3 escucha la interfaz del componente padre para pasar valor; llamada de evento del componente padre-hijo

代码在文末,均可直接复制使用

Este artículo describe principalmente cuestiones como la transferencia de valores y la llamada de componentes padre-hijo.


Problema 1: el componente secundario no puede recibir el valor pasado por el componente principal

Si el valor del componente principal se asigna durante onMounted, o se asigna de forma asincrónica, como una interfaz , el componente secundario no podrá obtener el valor modificado directamente. Los subcomponentes deben utilizar la supervisión de vigilancia . Busque la vista de vigilancia
del subcomponente son.vue

Pregunta 2: Después de modificar el valor aceptado por el componente secundario, se descubrió que el valor del componente principal también cambió.

Si no desea realizar cambios, debe realizar una asignación de copia profunda cuando el subcomponente la acepte . Se recomienda utilizar copia profunda. Si desea cambiar el valor del componente principal, pase la modificación al evento principal por separado.

Problema 3: el subcomponente acepta un valor, pero la página no se actualiza después de la modificación.

Cuando el subcomponente acepta tipos de datos simples, cámbielo a ref para aceptarlo y generar datos receptivos
. Para obtener más detalles, deje num1VALUE = ref(props.num1) // Generar datos receptivos; de lo contrario, la página de datos modificados no cambiará.

Problema 4: el hijo pasa el evento principal, el componente principal acepta el valor y la asignación no es válida

Esto se debe a que la variable en su componente principal se declara mediante reactivo. reactivo No asignar valor directamente a datos variables =! ! ! Se perderá la capacidad de respuesta. Si usa ref, no necesita asignar valores, o debe usar un solo atributo para asignar valores uno por uno Obj.atributo = valor de atributo, o envuelva una capa adicional de objetos alrededor del objeto original.
由此可见:声明尽量用ref。。。。

5, padre del niño

Vista de búsqueda update:obj.

6. El padre llama al niño

sonRef.value.childMethod()Vista de búsqueda

7. Código

Componente principal far.vue

<template>
  <div>
    <div>父:{
    
    {
    
     state.str1 }}--{
    
    {
    
     state.data1 }}--{
    
    {
    
     obj1 }} -- {
    
    {
    
     num1 }}</div>
    <button style="border: 1px solid cyan;" @click="callChildMethod">父调子事件</button>
    <hr>
    <son ref="sonRef" :str1="state.str1" :data1="state.data1" :obj1="obj1" :num1="num1" @update:obj="getObj" />
  </div>
</template>

<script>
import {
    
     defineComponent, onMounted, reactive ,toRefs,ref} from 'vue'
import Son from './son.vue'

export default defineComponent({
    
    
  components: {
    
    
    Son
  },
  setup() {
    
    

    const state = reactive({
    
    
      str1: '',
      data1: {
    
    }
    })

    let obj1 = reactive({
    
    
      a:1,
    })

    let num1 = ref(1)

    // 父接受子
    function getObj(val){
    
    
      obj1.a = val.a // reactive 不要直接data=赋值!!!会丢失响应式的,如果用ref就不会 非要赋值要不就使用 obj.属性 = 属性值 要不就给原对象多包裹一层对象
      // obj1 = val
      // obj1 = reactive({
    
    ...val})
      console.log('父接受子',val,obj1);
    }

	// 父调用子事件
    const sonRef = ref(null)
    function callChildMethod() {
    
    
      sonRef.value.childMethod()
    }

    onMounted(() => {
    
    
      // 对于在onMounted或异步的数据 传递给子组件 子组件应该使用watch监听接受 否则拿不到数据
      setTimeout(() => {
    
    
        state.str1 = '二次赋值!'
        state.data1 = {
    
    
          name: 'Alice',
          age: 25
        }
      }, 1000);
    })

    return {
    
    
      state,
      obj1,
      num1,
      sonRef,
      getObj,
      callChildMethod
    }
  }
})
</script>

Subcomponente son.vue

<template>
  <div>
    <div>子:{
    
    {
    
     state.str1VALUE }}--{
    
    {
    
     state.data1VALUE }}--{
    
    {
    
     obj1VALUE }} -- {
    
    {
    
     num1VALUE }}</div>
    <button style="border: 1px solid cyan;" @click="setVal">按钮该值</button>
    <button style="border: 1px solid cyan;" @click="setFarVal">子传父</button>
  </div>
</template>

<script>
import {
    
     defineComponent, reactive, watch,toRefs,toRef,ref } from 'vue'

export default defineComponent({
    
    
  props: {
    
    
    str1: String,
    data1: Object,
    obj1: Object,
    num1: Number,
  },
  emits: ['update:obj'],
  setup(props, {
    
     emit }) {
    
    
    const state = reactive({
    
    
      str1VALUE: '',
      data1VALUE: {
    
    }
    })
    let obj1VALUE = JSON.parse(JSON.stringify(props.obj1)) // 复杂数据类型obj如果不用深拷贝赋值 修改对象obj.name单一属性时候(state.data1VALUE.age = 33) 会导致父组件的源值改变 也会导致监听事件再次执行
    let num1VALUE = ref(props.num1) // 生成响应式数据 否则修改数据 页面不变化

    // 同时监听str1和data1   对于在onMounted或异步的数据 传递给子组件 子组件应该使用watch监听接受 否则拿不到数据
    watch([() => props.str1, () => props.data1], ([str1, data1]) => {
    
    
      console.log('监听',str1,data1);
      state.str1VALUE = JSON.parse(JSON.stringify(str1)) // 复杂数据类型obj如果不用深拷贝赋值 修改对象obj.name单一属性时候(state.data1VALUE.age = 33) 会导致父组件的源值改变 也会导致监听事件再次执行
      state.data1VALUE = JSON.parse(JSON.stringify(data1))
    }, {
    
     deep:true, immediate: true })

    // setTimeout(() => {
    
    
    //   state.str1VALUE = 'str1'
    // }, 2000);


    function setVal(){
    
    
      state.str1VALUE = '三次修改赋值'
      // state.data1VALUE = {
    
    
      //   name: '张三',
      //   age: 11
      // }
      state.data1VALUE.age = 33

      obj1VALUE.a = 3

      num1VALUE.value = 3
    }

    // 子传父
    function setFarVal(){
    
    
      let obj = {
    
    
        a: 123456
      }
      emit('update:obj', obj);
      console.log('子传父',obj);
    }

    function childMethod(){
    
    
      console.log('子事件');
    }
    return {
    
    
      state,
      obj1VALUE,
      num1VALUE,
      setVal,
      setFarVal,
      childMethod
    }
  }
})
</script>

Supongo que te gusta

Origin blog.csdn.net/i_am_a_div/article/details/132191998
Recomendado
Clasificación