1.porps
// defineProps 无需引入
let props = defineProps(['info', 'age'])
// props 为proxy代理对象,在模板可以省略props. 直接使用info
<div>{{ info }}</div>
// 但是在script 中不能省略
let age = props.age
2.自定义事件(子>父)
// 父组件
<child @事件A='lb1'></child>
lb1 = ('回传参数1', '回传参数2') => {}
// 子组件
// defineEmit 无需引入
let $emit = defineEmit(['事件A']) // 创建emit实例
const fn2 = () = { $emit('事件A', '参数1', '参数...')}
注意:
vue2中 @click在html标签上或组件上时,可以是自定义事件,也可以是原生DOM事件
vue3中,@click这种原生DOM事件不管在标签还是组件上,都是原生事件。
3.v-model 实现父子组件数据同步 !!
不仅可以收集表单,还能实现父子数据同步,任意一方改变,另一方也会同步
- v-model其实是语法糖,原理还是利用了 props,emit 来实现双向同步
父组件
<Child v-model="age1"></Child>
const age1 = ref(123)
v-model="age1"
原理为:
- 给子一个props ,属性名必须叫
modelValue
, - 给子一个自定义事件必须叫
update:modelValue
age1 只是modelValue的数据来源,叫啥都可以
子组件
<div>age:{{modelValue}}</div>
-------------------------------------------
<script setup>
let $emit = defineEmits(['update:modelValue'])
let props = defineProps(['modelValue'])
const handelClick = () =>{
$emit('update:modelValue', props.modelValue+1)
}
父组件
<Child v-model:age="ageNumber" v-model:name="nameStr"></Child>
const ageNumber = ref (1)
const nameStr = ref ('tom')
v-model:age="ageNumber"
原理为:
- 给子一个props ,属性名叫
age
,取父的ageNumber属性为值 - 给子一个自定义事件必须叫
update:age
update:age :update + 属性名
子组件
<div>age:{{modelValue}}</div>
-------------------------------------------
<script setup>
let $emit = defineEmits(['update:age', 'update:name'])
let props = defineProps(['age', 'name'])
const handelClick = () =>{
$emit('update:age', props.age+1)
$emit('update:name', props.name = 'tony')
}
4.useAttrs
类似于props,可以拿到父传给子的属性与事件,但props优先级更高,props接受的属性,useAttrs就接收不到了
父组件
<Child :age="age" @xxxFn="Fn"></Child>
子组件
<div :="$attrs"></div> // : 为v-bind,把$attrs对象里的属性和事件绑定给这个元素
import {useAttrs} from 'vue
let $attrs = useAttrs() // 返回一个proxy对象,包含了父传过来的没有被props接收的属性和事件
5.ref & $parent
vue3中, 组件内部数据方法默认对来访问者关闭,想要访问的话,需要需要通过defineExpose方法暴露
子组件
const money = ref(100)
const fly = () => {}
defineExpose([
money,
fly
])
// 通过$parent拿到父组件
console.log($parent.car) // $parent无需定义,可以直接使用
父组件
<Child ref="son"></Child>
const son = ref() // 获取子组件实例
console.log(son.value.money)
son.value.fly()
// 暴露给子组件用
const car = ref(1)
defineExpose([
car
])
6. provide & inject
隔辈组件数据通信,父子也行
并且传递的数据指向同一个对象
,所以子孙组件内部修改了,父组件也能同步
爷组件
import {provide} from 'vue'
provide('TOKEN_CODE', 123) // 参数1.标识key 参数2.数据
后代组件
import {inject} from 'vue'
let token = inject('TOKEN_CODE')
7.pinia
兄弟组件通信
- 选择式API写法 state,action,mutation…
- 组合式API写法 ref
细节查看文档
8. slot
- 作用域插槽
- 子组件通过slot,能够将数据传给父组件,父组件通过templete接收
- 作用域插槽的意义: 儿子提供数据,由父组件来控制子组件内容格式
子组件
<slot :arr=[1,2,3]></slot> // 任意位置注入槽 并提供数据
父组件
<Child>
<temptele v-slot="arr"> // 定义内容插进去
.......
</temptele>
</Child>