vue3.0学习笔记4---父子组件通讯以及子组件双向数据绑定

1.子组件双向数据绑定

创建一个子组件,里面包含一个input输入框。目标实现input输入框的值和父组件之间双向绑定。

  • 首先要在子组件的props上创建一个modelValue变量。注意名字要写对modelValue
props: {
    rules: Array as PropType<RuleType[]>,
    title: String,
    modelValue: String,
  },
  • 将该值绑定到input属性中
<template>
  <div class="form-group">
    <label for="inputValue">{
   
   { title }}</label>
    <input class="form-control" :class="{'is-invalid': inputRef.error}" id="inputValue" :value="inputRef.value" @blur="validateInput" @input="updateValue">
    <small id="emailHelp" class="form-text text-danger" v-if="inputRef.error">{
   
   { inputRef.message }}</small>
  </div>
</template>
  • 通过input方法更新值,注意事件名不能写错,update:modelValue
const updateValue = (e: KeyboardEvent) => {
  const targetValue = (e.target as HTMLInputElement).value
  inputRef.value = targetValue
  context.emit("update:modelValue", targetValue)
}
  • 父组件调用,通过v-model就可以获取子组件实时输入的值
<validate-input class="mb-3" :rules="emailRules" title="电子邮箱" v-model="emailRef"></validate-input>
2. 把子组件设置的属性传递给子组件内部的input($attr)属性
  • 首先子组件要加入inheritAttrs: false,
name: "ValidateInput",
  props: {
    rules: Array as PropType<RuleType[]>,
    title: String,
    modelValue: String,
  },
  inheritAttrs: false,
  • input绑定属性v-bind="$attrs",这样你在外部设置的input属性都会作用到input组件上了。
<validate-input class="mb-3" :rules="emailRules" title="电子邮箱" v-model="emailRef"  placeholder="请输入电子邮箱"></validate-input>
3.子组件向父组件传递通讯
  • 外部创建一个ValidateForm来包裹validate-input,定义两个插槽,一个用于存放
    validate-input,一个用于存放提交按钮。(注意用name来区分)
<template>
  <form class="validate-form-container">
    <slot name="default"></slot>
    <div class="submit-area" @click.prevent="submitForm">
      <slot name="submit">
        <button type="submit" class="btn btn-primary mt-3">提交</button>
      </slot>
    </div>
  </form>
</template>
  • 定义需要传递到父组件的方法,写在emits字段里面,因为有多个,用数组
export default defineComponent({
  name: "ValidateForm",
  emits: ['form-submit']
})
  • 绑定点击事件
<div class="submit-area" @click.prevent="submitForm">
  • 编写点击事件方法,注意方法名为form-submit
setup(props, context) {
    const submitForm = () => {
      context.emit('form-submit', '123')
    }
    return {
      submitForm
    }
  }
  • 父页面接收方法
<validate-form @form-submit="onFormSubmit">
const onFormSubmit = (value: string) => {
  console.log(value)
}
4. 父组件向slot的子组件通讯(mitt)
  • 安装mitt
    npm install mitt --save

  • 父组件定义

import mitt, {Handler, Emitter} from "mitt";
export const emitter: Emitter = mitt();
type ValidateFunc = () => boolean;


const callback = (func: ValidateFunc) => {
  validateArr.push(func)
}
emitter.on('foo', callback as Handler<ValidateFunc>)
onUnmounted(() => {
  emitter.off('foo', callback as Handler<ValidateFunc>)
  validateArr = []
})

知识点: 数组eveny只要有一个false就直接退出返回false,如果需要全部返回,先map再every

猜你喜欢

转载自blog.csdn.net/czl0325/article/details/113646479