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