一、props
<template>
<h3>父组件</h3>
<span v-if='toy'>儿子给的玩具{{toy}}</span>
<Child :car='car' :getToy='getToy'></Child>
</template>
<script setup>
import Child from './Child.vue'
import {ref} from 'vue'
let car=ref('宝马')
let toy=ref('')
const getToy=(value)=>{
toy.value=value
}
</script>
<template>
<h4>子组件父亲给的车{{props.car}}</h4>
<button @click='getToy(toy)'> 把玩具给父亲</button>
</template>
<script setup>
import{ref,defineProps} from 'vue'
const props=defineProps(['car','getToy'])
let toy=ref('奥特曼')
</script>
二、自定义事件CustomEvent
<template>
<h3>父组件</h3>
<span v-if='toy'>儿子给的玩具{{toy}}</span>
<hr>
<Child @getToy='getToy'></Child>
</template>
<script setup>
import Child from './Child.vue'
import {ref} from 'vue'
let toy=ref('')
const getToy=(value)=>{
toy.value=value
}
</script>
<template>
<h4>子组件玩具{{toy}}</h4>
<button @click='getToy'> 把玩具给父亲</button>
</template>
<script setup>
import{ref,defineEmits} from 'vue'
const emit = defineEmits(['getToy'])
let toy=ref('奥特曼')
const getToy=()=>{
emit('getToy',toy.value)
}
</script>
三、mitt
npm i mitt
utils/emitter.js
//引入mitt
import mitt from 'mitt';
//调用mitt得到emitter,emitter能绑定事件,触发事件
const emitter=mitt();
// //绑定事件
// emitter.on('test1',()=>{
// console.log('test1事件被调用');
// })
// emitter.on('test2',()=>{
// console.log('test2事件被调用');
// })
// setInterval(()=>{
// emitter.emit('test1')
// emitter.emit('test2')
// },1000)
// setTimeout(()=>{
// // emitter.off('test1')
// // emitter.off('test2')
// emitter.all.clear()
// },5000)
export default emitter;
<template>
<h4>子组件1玩具{{toy}}</h4>
<p v-if='eat'>老二给的零食{{eat}}</p>
<button @click='getToy'> 把玩具给老二</button>
</template>
<script setup>
import{ref,onUnmounted} from 'vue'
import emitter from '../../utils/emitter'
let toy=ref('奥特曼')
let eat=ref('')
const getToy = ()=>{
emitter.emit('send-toy',toy.value)
}
emitter.on('send-eat',(value)=>{
eat.value=value
})
onUnmounted(()=>{
emitter.off('send-eat')
})
</script>
<template>
<h4>子组件2零食{{eat}}</h4>
<p v-if='toy'>老大给的玩具{{toy}}</p>
<button @click='sendEat'> 把零食给老大</button>
</template>
<script setup>
import{ref,onUnmounted} from 'vue'
import emitter from '../../utils/emitter'
let eat=ref('奥利奥')
let toy=ref('')
emitter.on('send-toy',(value)=>{
toy.value=value
})
const sendEat=()=>{
emitter.emit('send-eat',eat.value)
}
onUnmounted(()=>{
emitter.off('send-toy')
})
</script>
四、v-model
UI组件库,组件封装会用
1.v-model用在html标签上
<template>
<h3>父组件</h3>
<!-- v-model用在html标签上 -->
<input type="text" :value="username" @input="$event.target.value">
<input type="text" v-model="username">
</template>
<script setup>
import {ref} from 'vue'
let username=ref('张三')
</script>
2. v-model用在组件标签上
<template>
<h3>父组件</h3>
<!-- v-model用在组件标签上 -->
<CustomInput v-model="username" />
<!-- <CustomInput :modelValue="username" @update:modelValue="username=$event" /> -->
</template>
<script setup>
import CustomInput from './CustomInput.vue'
import {ref} from 'vue'
let username=ref('张三')
</script>
<template>
<input type="text" :value="props.modelValue" @input="emit('update:modelValue',$event.target.value)"><br>
</template>
<script setup>
import{ref,defineProps} from 'vue'
const props=defineProps(['modelValue'])
const emit=defineEmits(['update:modelValue'])
</script>
对于原生事件,$event就是事件对象
对于自定义事件,$event就是触发事件时,所传递的数据
<template>
<h3>父组件</h3>
<!-- v-model用在组件标签上 -->
<CustomInput v-model:name="username" v-model:pass="password" />
</template>
<script setup>
import CustomInput from './CustomInput.vue'
import {ref} from 'vue'
let username=ref('张三')
let password=ref('123456')
</script>
<template>
<input type="text" :value="props.name" @input="emit('update:name',$event.target.value)">
<br>
<input type="text" :value="props.pass" @input="emit('update:pass',$event.target.value)">
<br>
</template>
<script setup>
import{ref,defineProps} from 'vue'
const props=defineProps(['name','pass'])
const emit=defineEmits(['update:name','update:pass'])
</script>
五、$attrs
$attrs会自动排除props中声明的属性
<template>
<h3>父组件</h3>
a:{{a}}b:{{b}}c:{{c}}d:{{d}}
<Child :a='a' :b='b' :c='c' :d='d' v-bind='{x:100,y:200}' :updateA='updateA'/>
</template>
<script setup>
import Child from './Child.vue'
import {ref} from 'vue'
let a=ref('1')
let b=ref('2')
let c=ref('3')
let d=ref('4')
const updateA=(val)=>{
a.value+=val
}
</script>
<template>
<h4>子组件</h4>
<ul>
<li> a:{{props.a}}</li>
<li>
其他{{$attrs}}
</li>
</ul>
<GrandChild v-bind='$attrs'/>
</template>
<script setup>
import GrandChild from './GrandChild.vue'
import{ref,defineProps} from 'vue'
const props=defineProps(['a'])
</script>
<template>
<h4>孙组件</h4>
<ul>
<li>a:{{props.a}}</li>
<li>b:{{props.b}}</li>
<li>c:{{props.c}}</li>
<li>d:{{props.d}}</li>
<li>x:{{props.x}}</li>
<li>y:{{props.y}}</li>
</ul>
<button @click='updateA(6)'>更新A</button>
</template>
<script setup>
import{ref,defineProps} from 'vue'
const props=defineProps(['a','b','c','d','x','y','updateA'])
</script>
六、$refs,$parent
1.$refs
<template>
<h3>父组件</h3>
<button @click='changeChild1'>修改child1的玩具</button>
<button @click='changeChild2'>修改child2的零食</button>
<Child1 ref='child1'/>
<Child2 ref='child2'/>
<button @click='getAllChild($refs)'>获取所有子组件实例对象</button>
</template>
<script setup>
import Child1 from './Child1.vue'
import Child2 from './Child2.vue'
import {ref} from 'vue'
let child1=ref('')
let child2=ref('')
const changeChild1=()=>{
child1.value.toy='小猪佩奇'
}
const changeChild2=()=>{
child2.value.eat='汉堡'
}
const getAllChild=(refs)=>{
console.log('refs',refs);
for(let key in refs){
refs[key].number+=3
}
}
</script>
<template>
<h4>子组件1玩具{{toy}}个数{{number}}</h4>
</template>
<script setup>
import{ref,defineExpose} from 'vue'
let toy=ref('奥特曼')
let number=ref(5)
defineExpose({toy,number})
</script>
<template>
<h4>子组件2零食{{eat}} 个数{{number}}</h4>
</template>
<script setup>
import{ref,defineExpose} from 'vue'
let eat=ref('奥利奥')
let number=ref(3)
defineExpose({eat,number})
</script>
2.$parent
<template>
<h3>父组件{{number}}</h3>
<Child1 ref='child1'/
</template>
<script setup>
import Child1 from './Child1.vue
import {ref} from 'vue'
let child1=ref('')
let number=ref(10)
defineExpose({number})
</script>
<template>
<h4>子组件1玩具{{toy}}个数{{number}}</h4>
<button @click=minusFather($parent)>修改父组件</button>
</template>
<script setup>
import{ref,defineExpose} from 'vue'
let toy=ref('奥特曼')
let number=ref(5)
const minusFather=(parent)=>{
parent.number+=1
}
</script>
七、provide,inject
<template>
<h3>父组件</h3>
{{money}}
品牌{{car.brand}}价格{{car.price}}数量{{car.count}}
<Child />
</template>
<script setup>
import Child from './Child.vue'
import {ref,reactive,provide} from 'vue'
let money=ref(100)
let car=reactive({
brand:'宝马',
price:'22w',
count:3
})
const updateMoney=(val)=>{
money.value-=val
}
provide('moneyContext',{money,updateMoney})
provide('car', car)
</script>
<template>
<h4>子组件</h4>
<GrandChild />
</template>
<script setup>
import GrandChild from './GrandChild.vue'
</script>
<template>
<h4>孙组件</h4>
<p>{{money}} <button @click="updateMoney(5)">花钱</button> </p>
{{car.brand}}{{car.price}}{{car.count}}
</template>
<script setup>
import{ref,inject} from 'vue'
let {money,updateMoney}=inject('moneyContext',{money:0,updateMoney:()=>{}})
let car=inject('car',{brand:'xx',price:'xxx',count:'xxx'})
</script>