Appearance
vue3 组件传参
1. 父 -> 子 defineProps
- 父组件
vue
<template>
<div>
<Child :msg="msg" />
</div>
</template>- 子组件
vue
<script setup>
defineProps({
msg: {
type: String,
default: 'hello'
}
})
</script>2. 子 -> 父 defineEmits
- 父组件
vue
<template>
<div>
<Child @change="handleClick" />
</div>
</template>
<script setup>
import Child from './Child.vue'
const handleClick = (val) => {
console.log('val')
}
</script>- 子组件
vue
<script setup>
const emits = defineEmits(['change']) // 定义事件
emits('change', 'hello')
</script>3. 父 -> 子 useAttrs()
Vue3中,$attrs包含父组件中除props和自定义事件外的所有属性集合。(父组件传递的参数,defineProps()没接收的参数,都由useAttrs()接收)
- 父组件
vue
<template>
<div>
<Child :msg="msg" data="123" name="王小二" />
</div>
</template>- 子组件
vue
<script setup>
import { useAttrs } from 'vue'
// 接收父组件传递数据
const props = defineProps(['name'])
// 用VueUse方法获得,除props之外的参数
const attrs = useAttrs()
console.log(attrs)
</script>4. 父 <-> 子 <-> 子 provide 、inject 多层,可双向
一个父组件相对于其所有的后代组件,会作为依赖提供者, 任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。
- 父组件
vue
<script setup>
import { ref, provide } from 'vue'
const count = ref(0)
provide('key', count)
</script>- 子组件 接收
vue
<script setup>
import { inject } from 'vue'
const count = inject('key')
</script>4.1. 应用层提供, 可以作为全局状态管理, 替代Pinia 或者 Vuex
- useStore.js 状态管理
js
/**
* 状态管理
*/
import { reactive } from "vue";
class useStore {
state = reactive({
loader: true,
})
/**
* 设置loader
* @param {*} state 状态
*/
setLoader = state => {
this.state.loader = state ? true : false;
}
}
export default new useStore()- main.js 全局注入
js
import { createApp, provide } from 'vue'
import useStore from '@/hooks/useStore'
const app = createApp({
setup() {
provide('store', useStore)
return () => h(App);
}
})- 组件使用
vue
<script setup>
import { inject } from 'vue'
const store = inject('store')
store.setLoader(true); // 设置loader
let loading = computed(() => store.state.loader) // 获取loader
</script>5. 父 -> 子 ref
- 父组件
vue
<template>
<div>
<Child ref="child" />
</div>
</template>
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const child = ref(null) // 子组件实例
child.value.show() // 调用子组件方法
console.log(child.value.name) // 打印子组件实例
</script>- 子组件
vue
<script setup>
// 可以通过 defineExpose 编译器宏来显式指定在 <script setup> 组件中要暴露出去的属
defineExpose({
name,
show
})
const name = '王小二'
const show = () => {
console.log('show')
}
</script>6. 父 <-> 子 v-model
- 父
vue
<template>
<div>
<Child v-model="msg" />
<!-- 等同于 -->
<Child :modelValue="msg" @update:modelValue="msg = $event" />
</div>
</template>- 子
vue
<script setup>
// 输入
const prop = defineProps({
modelValue: String
})
console.log(prop.modelValue)
// 输出
const emit = defineEmits(['update:modelValue'])
const change = () => {
emit('update:modelValue', 'hello')
}
</script>defineModel 语法糖
- 子 简化版
vue
<script setup>
const { modelValue, update: emit } = defineModel()
// 输入
console.log(modelValue) // 等同于 prop.modelValue
// 输出
const change = () => {
emit('hello')
}
</script>7. 其它
- window 对象 绑定监听数据
- 自定义事件 触发
- 浏览器缓存