当前位置 : 主页 > 网络编程 > JavaScript >

Vue父子组件通信全面详细介绍

来源:互联网 收集:自由互联 发布时间:2023-02-01
目录 1.Vue父子组件通信方式 2.不同文件间的通信方式 1 .父组件vue文件和子组件vue文件 2 .父组件jsx文件和子组件vue文件 3 .父组件vue文件和子组件jsx文件 4 .父组件jsx文件和子组件jsx文件
目录
  • 1.Vue父子组件通信方式
  • 2.不同文件间的通信方式
    • 1 .父组件vue文件和子组件vue文件
    • 2 .父组件jsx文件和子组件vue文件
    • 3 .父组件vue文件和子组件jsx文件
    • 4 .父组件jsx文件和子组件jsx文件
  • 3.如何实现

    1.Vue父子组件通信方式

    父子组件通信方式一般为props和emit组合使用,那么在不同的文件中应该如何使用呢?

    |.vue文件和.jsx文件中有什么不同吗?

    2.不同文件间的通信方式

    1 .父组件vue文件和子组件vue文件

    // 父组件 App.vue
    <HelloWorld :value="count" @update:value="handleAppValue" />
    
    // 子组件 HelloWorld.vue
    // script
    const props = defineProps<{ value: number }>();
    const emit = defineEmits<{
      (e: "update:value", value: number): void;
    }>();
    const handleUpdate = () => {
      emit("update:value", props.value + 1);
    };
    </script>
    <template>
      <div @click="handleUpdate">{{ value }}</div>
    </template>
    

    2 .父组件jsx文件和子组件vue文件

    // 父组件 TsxTest.tsx
    // setup内
    const handleUpdateValue = (count: number) => {
      value.value = count;
      emit("update:value", value.value);
    };
    // 注意这里是onUpdate:value
    return () => (
      <HelloWorld value={value.value} onUpdate:value={handleUpdateValue} />
    );
    
    // 子组件 HelloWorld.vue
    // script
    const props = defineProps<{ value: number }>();
    const emit = defineEmits<{
      (e: "update:value", value: number): void;
    }>();
    const handleUpdate = () => {
      emit("update:value", props.value + 1);
    };
    </script>
    <template>
      <div @click="handleUpdate">{{ value }}</div>
    </template>
    

    3 .父组件vue文件和子组件jsx文件

    // 父组件 App.vue
    const count = ref(2);
    const handleAppValue = (value: number) => {
      count.value = value;
    };
    <TsxTest :value="count" @update:value="handleAppValue" />
    
    // 子组件 TsxTest.tsx
    // script
    props: {
      value: {
        type: Number,
        default: 1,
      },
    },
    emits: ["update:value"],
    setup(props, { emit }) {
      const handleUpdateValue = () => {
        emit("update:value", props.value + 1);
      };
      return () => (
        <div onClick={handleUpdateValue}>{props.value}</div>
      );
    },
    

    4 .父组件jsx文件和子组件jsx文件

    // 父组件 TsxParent
    const value = ref(1);
    const handleUpdateValue = (count: number) => {
      value.value = count;
    };
    <TsxTest value={value.value} onUpdate:value={handleUpdateValue} />
    
    // 子组件 TsxTest.tsx
    // script
    props: {
      value: {
        type: Number,
        default: 1,
      },
    },
    emits: ["update:value"],
    setup(props, { emit }) {
      const handleUpdateValue = () => {
        emit("update:value", props.value + 1);
      };
      return () => (
        <div onClick={handleUpdateValue}>{props.value}</div>
      );
    },
    

    3.如何实现

    在componentEmits文件里面可以看到

    // componentEmits.ts
    // rawArgs就是emit('update:value', count)的count值
    let args = rawArgs
    const isModelListener = event.startsWith('update:')
    // 双向绑定的name比如update:value那么就是后面的value值
    const modelArg = isModelListener && event.slice(7)
    if (modelArg && modelArg in props) {
      const modifiersKey = `${
        modelArg === 'modelValue' ? 'model' : modelArg
      }Modifiers`
      // 是否有modifiersKey比如trim/number
      const { number, trim } = props[modifiersKey] || EMPTY_OBJ
      if (trim) {
        args = rawArgs.map(a => a.trim())
      }
      if (number) {
        args = rawArgs.map(toNumber)
      }
    }
    

    为啥modifiersKey会拼接Modifiers字符串呢?

    因为在vModel处理时会获取父组件传过来的modifiers并进行处理拼接

    // vModel.ts
    // 对eventName进行处理,arg不存在则认为是onUpdate:modelValue
    const eventName = arg
      ? isStaticExp(arg)
        ? `onUpdate:${arg.content}`
        : createCompoundExpression(['"onUpdate:" + ', arg])
      : `onUpdate:modelValue`
    const modifiersKey = arg
      ? isStaticExp(arg)
        ? `${arg.content}Modifiers`
        : createCompoundExpression([arg, ' + "Modifiers"'])
      : `modelModifiers`

    然后在进行handler处理

    // componentEmits.ts 接上
    let handlerName
    let handler =
      // toHandlerKey就行处理evnet变成on${capitalize(str)}
      props[(handlerName = toHandlerKey(event))] ||
      // also try camelCase event handler (#2249)
      props[(handlerName = toHandlerKey(camelize(event)))]
    // for v-model update:xxx events, also trigger kebab-case equivalent
    // for props passed via kebab-case
    if (!handler && isModelListener) {
      handler = props[(handlerName = toHandlerKey(hyphenate(event)))]
    }
    if (handler) {
      // callWithAsyncErrorHandling就是函数执行,然后进行了错误处理
      callWithAsyncErrorHandling(
        handler,
        instance,
        ErrorCodes.COMPONENT_EVENT_HANDLER,
        args
      )
    }

    简单来说emit函数就是语法糖

    <TsxTest value={value.value} onUpdate:value={handleUpdateValue} />
    <TsxTest :value="count" @update:value="handleAppValue" />
    

    上面两种方式的处理函数[onUpdate:value/@update:value]都会在emit里面变成这样

    emit('update:value', count)
    // 执行emit其实就行下面的执行
    props.['onUpdate:value'](count)

    到此这篇关于Vue父子组件通信全面详细介绍的文章就介绍到这了,更多相关Vue父子组件通信内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

    上一篇:vuex中能直接修改state吗
    下一篇:没有了
    网友评论