组件传值
父子:props
/ emits
、v-model
/ [[emits]] (v3) 、v-bind
/ refs
、defineExpose (v3.2)
跨级:provide
& inject
、[[$attrs & $listeners]]
全局:EventBus
(v2) 、[[mitt]] (v3) 、vuex
、pinia
、[[teleport]]
v3.2
[[defineProps & defineEmits]]
父子组件通信
defineExpose
子组件 传值 → 父组件
让父组件直接获取子组件的值或调用方法 v2 是 this.$refs.xx
v3 在 script-setup
模式下,所有数据只是默认隐式 return 给 使用,不会暴露到组件外,所以父组件是无法直接通过挂载 ref
变量获取子组件的数据。
js
// vue3.2 示例
// 子组件 声明
const msg = 'Hello';
// 暴露
defineExpose({
msg,
...
});
// 父组件
<Index ref="son"></Index>
const son = ref(null);
console.log(son.value.msg); // Hello
// ----------------------------------
// vue2 示例
// 子组件有个show方法
show();
// 父组件
<Index ref="son"></Index>
this.$refs['son'].show();
跨级组件通信
$attrs & $listeners
$attrs
负责捡漏props
没有接收的属性
v3 把 `$listeners ` 合并到 `$attrs` 中
js
// v3 引入使用
const attrs = useAttrs();
provide &
inject
ts
#父组件声明
import type {InjectionKey} from 'vue' // vue3为provide提供的标注类型
... // 导入provide
const key = Symbol() as InjectionKey<string>; // 字符串类型
provide(key, name) // 上面设定的传string类型
#某个后代组件使用
... // 导入inject
let name = inject(key);
------------------- v3传响应式: 需要改的地方 -----------------------
const key = Symbol() as InjectionKey<Ref<string>>; // 字符串类型
let name = ref('xxx');
provide(key, name); // 一样, 不需要name.value