1.父向子传值
props传值方式
<!-- 根据一个变量的值动态传入 -->
<BlogPost :title="post.title" />
props是单向数据流,即父传给子,但子不能修改父。
2.子向父传值
2.1 emit触发
子组件中触发事件
<button @click="$emit('increaseBy', 1)"> Increase by 1 </button>
父组件中定义事件
<MyButton @increase-by="increaseCount" />
2.2 ref
父组件可以通过 ref 主动获取子组件的属性或者调用子组件的方法
父组件
//template中定义ref
<ResourceAllocation ref="childFormRef" :errors.sync="state.errors" />
// js中
const childFormRef = ref(null);
(childFormRef as any).value.setFormErr(err);
子组件
//定义了一个错误处理的事件
const setFormErr = async (err: IFetchResponse) => {
formErrHandle(state, err);
};
//定义了一个表单提交事件
const submit = async () => {
const {hasError, errors} = await (form.value as any).submit();
return {
hasError,
errors,
formData: {...state.formData}
};
};
2.3.sync 和 v-model(.sync在vue3中好像被废弃了)
2.3.1 v-model 用于在表单输入元素或组件上创建双向绑定 cn.vuejs.org/guide/compo…
子组件:方式1
<!-- CustomInput.vue -->
<script>
export default {
props: ['modelValue'], emits: ['update:modelValue']
}
</script>
<template>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</template>
<CustomInput v-model="searchText" />
另一种在组件内实现 v-model 的方式是使用一个可写的,同时具有 getter 和 setter 的计算属性。get 方法需返回 modelValue prop,而 set 方法需触发相应的事件:
子组件:方式2(工作中常用)
<!-- CustomInput.vue -->
<script>
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
computed: {
value:
{
get() {
return this.modelValue
},
set(value) {
this.$emit('update:modelValue', value)
}
}
}
}
</script>
<template>
<input v-model="value" />
</template>
3.兄弟组件传值(todo 下面内容待补充)
eventbus
vuex
自定义事件 CustomEvent ,清除副作用?
1.在子应用中注册事件
import {computed, watch} from '@vue/composition-api';
export const notifyRootApp = (key: string, payload: any) => {
const event = new CustomEvent('afe:notifyRootApp', {
detail: {
key,
payload
}
});
window.dispatchEvent(event);
};
2.点击确定需要把表单数据传给后端发送ajax请求
确定和取消的事件应该放在子应用里面,
那点击主应用通知子应用触发事件
(点击了确定,告诉子应用当前我在创建报告页我点了哈,你该去执行确定事件了,点击了取消,告诉子应用我点了哈,你该去执行取消事件了)
export const useRootAppNotify = (
handleCreatReportConfirmCallBack,
handleCreatReportCancelCallBack,
handleAddVersionConfirmCallBack,
handleAddVersionCancelCallBack
) => {
console.log('useOceanAppNotify');
const NOTIFY_EVENT = "afe:notifyChildApp"
const listenerFn = (e: any) => {
console.log('addEventListener');
try {
const {key, payload}: TAfeNotify = e.detail;
if (key === 'btnIsClicked') {
if (payload.isConfirmBtnClicked) {
if (payload.pageName === 'CreateReport') {
handleCreatReportConfirmCallBack?.();
} else {
handleAddVersionConfirmCallBack?.();
}
} else {
if (payload.pageName === 'CreateReport') {
handleCreatReportCancelCallBack?.();
} else {
handleAddVersionCancelCallBack?.();
}
}
}
} finally {
//
}
};
onMounted(() => {
window.addEventListener(NOTIFY_EVENT, listenerFn);
});
onBeforeUnmount(() => {
window.removeEventListener(NOTIFY_EVENT, listenerFn);
});
};
4.多层嵌套组件传值
provide / inject
注意provide提供的数据并不是响应式的,为保证注入方和供给方之间的响应性链接,我们需要使用 computed() 函数提供一个计算属性
使用 Symbol 作注入名,我们通常推荐在一个单独的文件中导出这些注入名 Symbol