目錄
Vue3
父子傳值:props(attrs)/emit
父?jìng)髯?/p>
props
父child :屬性名="變量"
子props=defineProps({屬性名:type...})
attrs父作用域(除 class、 style 、?props?)屬性集合
父child :屬性名="變量",屬性名="常量"
子?attrs = useAttrs()
子傳父emits+@=v-on:
父child @事件名"="parentClick",parentClick(msg)
子emit = defineEmits(["事件名",...]),emit("key",msg)
雙向綁定v-model(支持多個(gè)v-model,所以取消了.sync)
v-model:modelValue簡(jiǎn)寫(xiě)為v-model
父child? v-model:屬性名="變量"
子emit = defineEmits(["事件名",...]),emit("事件名",值)
父調(diào)子事件/屬性:expose / ref
父child ref="childComp",childComp.value.屬性/方法
子defineExpose({屬性: "msg",方法(){??}})
祖?zhèn)鲗Oprovide / inject依賴(lài)注入【不推薦】
耦合性增加->依賴(lài)關(guān)系復(fù)雜化->重用性和可維護(hù)性低
父provide("key",msg)
子inject("key")
跨組件事件觸發(fā)/監(jiān)聽(tīng)器mitt:on/off,emit
代替vue2的eventbus
輕量級(jí):僅有200字節(jié)
支持全部事件的監(jiān)聽(tīng)和批量移除
跨框架:不依賴(lài) Vue 實(shí)例,React / Vue/jQuery
原理:map 保存函數(shù)
直接在組件內(nèi)導(dǎo)入使用:分散式更方便管理和排查問(wèn)題
Vue2
父子傳值:props(attrs)/emit
父?jìng)髯?/p>
props
父child :屬性名="父組件實(shí)例變量"
子
A.數(shù)組:props:['屬性名']
B.對(duì)象:props:{屬性名:{type:,default:}}
attrs父作用域(除 class、 style 、?props?)屬性集合
父child :屬性名="變量",屬性名="常量"
子 this.$attrs
子傳父emits+@=v-on:
父child @事件名"="parentClick",parentClick(msg)
子this.$emit("事件名",msg)
雙向綁定值
.sync(支持多個(gè),update:屬性名)
父child :屬性名.sync="變量"
子?this.$emit("update:屬性名", 屬性值 );?
v-model(支持一個(gè),自定義prop+event名)
語(yǔ)法糖:value 和 @input
model 選項(xiàng)自定義 prop 和 event 的名稱(chēng)
副作用:當(dāng)綁定響應(yīng)式對(duì)象上不存在的屬性,會(huì)讓它響應(yīng)式
父子傳屬性/方法
父?jìng)髯?/p>
this.$parent
this.$root?: App.vue
this.$listeners:父組件.native 除外的監(jiān)聽(tīng)事件集合
調(diào)用:this.$listeners.事件名
子傳父
this.$children[0]
ref
父child ref="childComp",childComp.所有的屬性/方法
祖?zhèn)鲗Oprovide / inject依賴(lài)注入:推薦傳遞常量/方法
父provide(){return obj }
子inject[“name”,“msg”],this.msg
跨組件事件通信EventBus中央事件總線
定義
使用:emit、on、off
slot:父?jìng)髯咏M件,子傳父數(shù)據(jù)
單個(gè)/默認(rèn)/匿名插槽slot
v-slot="name",在2.6后可縮寫(xiě)為#"name"
父v-slot="子slot中的變量"
子slot :屬性名="變量"
具名插槽slot name="":多個(gè)插槽,需要區(qū)分
作用域/帶數(shù)據(jù)的插槽
內(nèi)置指令:數(shù)據(jù)/事件關(guān)聯(lián)DOM
v-bind(簡(jiǎn)寫(xiě):):綁定屬性到 Vue 實(shí)例中的數(shù)據(jù)
v-on (簡(jiǎn)寫(xiě)@): 監(jiān)聽(tīng)DOM事件、觸發(fā)Vue實(shí)例中的方法
Vue3
Vue3 從實(shí)例中完全刪除了?$on
、$off
?和?$once
?方法
父子傳值:props(attrs)/emit
父?jìng)髯?/h4>
props
父child :屬性名="變量"
子props=defineProps({屬性名:type...})
// Parent.vue 傳送
<child :msg2="msg2"></child>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const msg2 = ref("這是傳給子組件的信息2")
// 或者復(fù)雜類(lèi)型
const msg2 = reactive(["這是傳級(jí)子組件的信息2"])
</script>
// Child.vue 接收
<script setup>
// 不需要引入 直接使用
// import { defineProps } from "vue"
const props = defineProps({
// 寫(xiě)法一
msg2: String
// 寫(xiě)法二
msg2:{
type:String,
default:""
}
})
console.log(props) // { msg2:"這是傳級(jí)子組件的信息2" }
</script>
attrs父作用域(除 class、 style 、?props?)屬性集合
父child :屬性名="變量",屬性名="常量"
子?attrs = useAttrs()
// Parent.vue 傳送
<child :msg1="msg1" :msg2="msg2" title="3333"></child>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const msg1 = ref("1111")
const msg2 = ref("2222")
</script>
// Child.vue 接收
<script setup>
// 3.2版本不需要引入,直接用
import { useAttrs } from "vue"
// 如果沒(méi)有用 props 接收 msg1 的話就是 { msg1: "1111", msg2:"2222", title: "3333" }
const props = defineProps({
msg1: String
})
const attrs = useAttrs()
console.log(attrs) // { msg2:"2222", title: "3333" }
</script>
子傳父emits+@=v-on:
父child @事件名"="parentClick",parentClick(msg)
子emit = defineEmits(["事件名",...]),emit("key",msg)
//父組件
<template>
<my-son @childClick="childClick" />
</template>
<script lang="ts" setup>
import MySon from "./MySon.vue";
let childClick = (e: any):void => {
console.log('from son:',e);
};
</script>
//子組件
<template>
<span @click="sonToFather">信息:{{ props.foo }}</span>
</template>
<script lang="ts" setup>
const emit = defineEmits(["childClick"]); // 聲明觸發(fā)事件 childClick
const sonToFather = () =>{
emit('childClick' , props.foo)
}
</script>
雙向綁定v-model(支持多個(gè)v-model,所以取消了.sync
)
v-model:modelValue簡(jiǎn)寫(xiě)為v-model
父child? v-model:屬性名="變量"
子emit = defineEmits(["事件名",...]),emit("事件名",值)
//child.vue
<template>
<span @click="changeInfo">我叫{{ modelValue }},今年{{ age }}歲</span>
</template>
<script setup>
// import { defineEmits, defineProps } from 'vue'
// defineEmits和defineProps在<script setup>中自動(dòng)可用,無(wú)需導(dǎo)入
// 需在.eslintrc.js文件中【globals】下配置【defineEmits: true】、【defineProps: true】
defineProps({
modelValue: String,
age: Number
})
const emit = defineEmits(['update:modelValue', 'update:age'])
const changeInfo = () => {
// 觸發(fā)父組件值更新
emit('update:modelValue', 'Tom')
emit('update:age', 30)
}
</script>
//parent.vue
<template>
// v-model:modelValue簡(jiǎn)寫(xiě)為v-model
// 可綁定多個(gè)v-model
<child
v-model="state.name"
v-model:age="state.age"
/>
</template>
<script setup>
import { reactive } from 'vue'
// 引入子組件
import child from './child.vue'
const state = reactive({
name: 'Jerry',
age: 20
})
</script>
父調(diào)子事件/屬性:expose / ref
父child ref="childComp",childComp.value.屬性/方法
子defineExpose({屬性: "msg",方法(){??}})
// Child.vue
<script setup>
// 方法一 不適用于Vue3.2版本,該版本 useContext()已廢棄
import { useContext } from "vue"
const ctx = useContext()
// 對(duì)外暴露屬性方法等都可以
ctx.expose({
childName: "這是子組件的屬性",
someMethod(){
console.log("這是子組件的方法")
}
})
// 方法二 適用于Vue3.2版本, 不需要引入
// import { defineExpose } from "vue"
defineExpose({
childName: "這是子組件的屬性",
someMethod(){
console.log("這是子組件的方法")
}
})
</script>
// Parent.vue 注意 ref="comp"
<template>
<child ref="comp"></child>
<button @click="handlerClick">按鈕</button>
</template>
<script setup>
import child from "./child.vue"
import { ref } from "vue"
const comp = ref(null)
const handlerClick = () => {
console.log(comp.value.childName) // 獲取子組件對(duì)外暴露的屬性
comp.value.someMethod() // 調(diào)用子組件對(duì)外暴露的方法
}
</script>
祖?zhèn)鲗Oprovide / inject依賴(lài)注入【不推薦】
耦合性增加->依賴(lài)關(guān)系復(fù)雜化->重用性和可維護(hù)性低
耦合性:關(guān)聯(lián)度
父provide("key",msg)
子inject("key")
// Parent.vue
<script setup>
import { provide } from "vue"
provide("name", "沐華")
</script>
// Child.vue
<script setup>
import { inject } from "vue"
const name = inject("name")
console.log(name) // 沐華
</script>
跨組件事件觸發(fā)/監(jiān)聽(tīng)器mitt:on/off,emit
代替vue2的eventbus
輕量級(jí):僅有200字節(jié)
支持全部事件的監(jiān)聽(tīng)和批量移除
跨框架:不依賴(lài) Vue 實(shí)例,React / Vue/jQuery
原理:map 保存函數(shù)
export default function mitt(all) {
all = all || new Map();
//命名為type的事件
return {
all,
//監(jiān)聽(tīng)type事件,綁定handler
on(type, handler) {
const handlers = all.get(type);
const added = handlers && handlers.push(handler);
if (!added) {
all.set(type, [handler]);
}
},
//移除type事件,解綁handler
off(type, handler) {
const handlers = all.get(type);
if (handlers) {
handlers.splice(handlers.indexOf(handler) >>> 0, 1);
}
},
//觸發(fā)type事件,傳遞evt事件參數(shù)給handler(遍歷執(zhí)行與其綁定的所有handler)
emit(type, evt) {
((all.get(type) || [])).slice().map((handler) => { handler(evt); });
((all.get('*') || [])).slice().map((handler) => { handler(type, evt); });
},
clear(){
// 清空所有事件處理程序
all.clear();
},
};
}
直接在組件內(nèi)導(dǎo)入使用:分散式更方便管理和排查問(wèn)題
npm i mitt -save
import mitt from 'mitt'
const emitter = mitt()
// listen to an event
emitter.on('foo', e => console.log('foo', e) )
// listen to all events
emitter.on('*', (type, e) => console.log(type, e) )
// fire an event
emitter.emit('foo', { a: 'b' })
// clearing all events
emitter.all.clear()
// working with handler references:
function onFoo() {}
emitter.on('foo', onFoo) // listen
emitter.off('foo', onFoo) // unlisten
// Parent.vue 傳送
<child :msg2="msg2"></child>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const msg2 = ref("這是傳給子組件的信息2")
// 或者復(fù)雜類(lèi)型
const msg2 = reactive(["這是傳級(jí)子組件的信息2"])
</script>
// Child.vue 接收
<script setup>
// 不需要引入 直接使用
// import { defineProps } from "vue"
const props = defineProps({
// 寫(xiě)法一
msg2: String
// 寫(xiě)法二
msg2:{
type:String,
default:""
}
})
console.log(props) // { msg2:"這是傳級(jí)子組件的信息2" }
</script>
// Parent.vue 傳送
<child :msg1="msg1" :msg2="msg2" title="3333"></child>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const msg1 = ref("1111")
const msg2 = ref("2222")
</script>
// Child.vue 接收
<script setup>
// 3.2版本不需要引入,直接用
import { useAttrs } from "vue"
// 如果沒(méi)有用 props 接收 msg1 的話就是 { msg1: "1111", msg2:"2222", title: "3333" }
const props = defineProps({
msg1: String
})
const attrs = useAttrs()
console.log(attrs) // { msg2:"2222", title: "3333" }
</script>
//父組件
<template>
<my-son @childClick="childClick" />
</template>
<script lang="ts" setup>
import MySon from "./MySon.vue";
let childClick = (e: any):void => {
console.log('from son:',e);
};
</script>
//子組件
<template>
<span @click="sonToFather">信息:{{ props.foo }}</span>
</template>
<script lang="ts" setup>
const emit = defineEmits(["childClick"]); // 聲明觸發(fā)事件 childClick
const sonToFather = () =>{
emit('childClick' , props.foo)
}
</script>
v-model,所以取消了.sync
)
//child.vue
<template>
<span @click="changeInfo">我叫{{ modelValue }},今年{{ age }}歲</span>
</template>
<script setup>
// import { defineEmits, defineProps } from 'vue'
// defineEmits和defineProps在<script setup>中自動(dòng)可用,無(wú)需導(dǎo)入
// 需在.eslintrc.js文件中【globals】下配置【defineEmits: true】、【defineProps: true】
defineProps({
modelValue: String,
age: Number
})
const emit = defineEmits(['update:modelValue', 'update:age'])
const changeInfo = () => {
// 觸發(fā)父組件值更新
emit('update:modelValue', 'Tom')
emit('update:age', 30)
}
</script>
//parent.vue
<template>
// v-model:modelValue簡(jiǎn)寫(xiě)為v-model
// 可綁定多個(gè)v-model
<child
v-model="state.name"
v-model:age="state.age"
/>
</template>
<script setup>
import { reactive } from 'vue'
// 引入子組件
import child from './child.vue'
const state = reactive({
name: 'Jerry',
age: 20
})
</script>
// Child.vue
<script setup>
// 方法一 不適用于Vue3.2版本,該版本 useContext()已廢棄
import { useContext } from "vue"
const ctx = useContext()
// 對(duì)外暴露屬性方法等都可以
ctx.expose({
childName: "這是子組件的屬性",
someMethod(){
console.log("這是子組件的方法")
}
})
// 方法二 適用于Vue3.2版本, 不需要引入
// import { defineExpose } from "vue"
defineExpose({
childName: "這是子組件的屬性",
someMethod(){
console.log("這是子組件的方法")
}
})
</script>
// Parent.vue 注意 ref="comp"
<template>
<child ref="comp"></child>
<button @click="handlerClick">按鈕</button>
</template>
<script setup>
import child from "./child.vue"
import { ref } from "vue"
const comp = ref(null)
const handlerClick = () => {
console.log(comp.value.childName) // 獲取子組件對(duì)外暴露的屬性
comp.value.someMethod() // 調(diào)用子組件對(duì)外暴露的方法
}
</script>
耦合性:關(guān)聯(lián)度
// Parent.vue
<script setup>
import { provide } from "vue"
provide("name", "沐華")
</script>
// Child.vue
<script setup>
import { inject } from "vue"
const name = inject("name")
console.log(name) // 沐華
</script>
export default function mitt(all) {
all = all || new Map();
//命名為type的事件
return {
all,
//監(jiān)聽(tīng)type事件,綁定handler
on(type, handler) {
const handlers = all.get(type);
const added = handlers && handlers.push(handler);
if (!added) {
all.set(type, [handler]);
}
},
//移除type事件,解綁handler
off(type, handler) {
const handlers = all.get(type);
if (handlers) {
handlers.splice(handlers.indexOf(handler) >>> 0, 1);
}
},
//觸發(fā)type事件,傳遞evt事件參數(shù)給handler(遍歷執(zhí)行與其綁定的所有handler)
emit(type, evt) {
((all.get(type) || [])).slice().map((handler) => { handler(evt); });
((all.get('*') || [])).slice().map((handler) => { handler(type, evt); });
},
clear(){
// 清空所有事件處理程序
all.clear();
},
};
}
npm i mitt -save
import mitt from 'mitt'
const emitter = mitt()
// listen to an event
emitter.on('foo', e => console.log('foo', e) )
// listen to all events
emitter.on('*', (type, e) => console.log(type, e) )
// fire an event
emitter.emit('foo', { a: 'b' })
// clearing all events
emitter.all.clear()
// working with handler references:
function onFoo() {}
emitter.on('foo', onFoo) // listen
emitter.off('foo', onFoo) // unlisten
Vue3.x 推薦使用 mitt.js - 掘金
Vue2
父子傳值:props(attrs)/emit
父?jìng)髯?/h4>
props
父child :屬性名="父組件實(shí)例變量"
子
A.數(shù)組:props:['屬性名']
B.對(duì)象:props:{屬性名:{type:,default:}}
// Child.vue 接收
export default {
// 寫(xiě)法一 用數(shù)組接收
props:['msg'],
// 寫(xiě)法二 用對(duì)象接收,可以限定接收的數(shù)據(jù)類(lèi)型、設(shè)置默認(rèn)值、驗(yàn)證等
props:{
msg:{
type:String,
default:'這是默認(rèn)數(shù)據(jù)'
}
},
mounted(){
console.log(this.msg)
},
}
attrs父作用域(除 class、 style 、?props?)屬性集合
父child :屬性名="變量",屬性名="常量"
子 this.$attrs
子傳父emits+@=v-on:
父child @事件名"="parentClick",parentClick(msg)
子this.$emit("事件名",msg)
// Child.vue 派發(fā)
export default {
data(){
return { msg: "這是發(fā)給父組件的信息" }
},
methods: {
handleClick(){
this.$emit("sendMsg",this.msg)
}
},
}
// Parent.vue 響應(yīng)
<template>
<child v-on:sendMsg="getChildMsg"></child>
// 或 簡(jiǎn)寫(xiě)
<child @sendMsg="getChildMsg"></child>
</template>
export default {
methods:{
getChildMsg(msg){
console.log(msg) // 這是父組件接收到的消息
}
}
}
雙向綁定值
.sync(
支持多個(gè),update:屬性名)
// Child.vue 接收
export default {
// 寫(xiě)法一 用數(shù)組接收
props:['msg'],
// 寫(xiě)法二 用對(duì)象接收,可以限定接收的數(shù)據(jù)類(lèi)型、設(shè)置默認(rèn)值、驗(yàn)證等
props:{
msg:{
type:String,
default:'這是默認(rèn)數(shù)據(jù)'
}
},
mounted(){
console.log(this.msg)
},
}
// Child.vue 派發(fā)
export default {
data(){
return { msg: "這是發(fā)給父組件的信息" }
},
methods: {
handleClick(){
this.$emit("sendMsg",this.msg)
}
},
}
// Parent.vue 響應(yīng)
<template>
<child v-on:sendMsg="getChildMsg"></child>
// 或 簡(jiǎn)寫(xiě)
<child @sendMsg="getChildMsg"></child>
</template>
export default {
methods:{
getChildMsg(msg){
console.log(msg) // 這是父組件接收到的消息
}
}
}
.sync(
支持多個(gè),update:屬性名)
?.sync
?修飾符是單向數(shù)據(jù)流的典型范式。?『數(shù)據(jù)向下,事件向上』
父child :屬性名.sync="變量"
子?this.$emit("update:屬性名", 屬性值 );?
//父組件
<template>
<TestCom :num.sync="data"></TestCom>
</template>
<script>
export default({
components: {
TestCom,
},
data() {
return {
data:2
}
},
});
</script>
//子組件
<template>
<div>
<button @click="cahngeNum">按鈕</button>
{{ num }}
</div>
</template>
<script>
export default({
props: {
num: {
default: "",
type: String,
},
},
methods: {
cahngeNum() {
// 事件名稱(chēng)的格式 'update:' + prop名稱(chēng)
this.$emit("update:num", 999);
},
},
});
</script>
v-model(支持一個(gè),自定義prop+event名)
除了傳遞基本的值之外,還可以傳遞其他類(lèi)型,比如對(duì)象或數(shù)組。
語(yǔ)法糖:value
和 @input
語(yǔ)法糖,簡(jiǎn)單來(lái)說(shuō)就是『便捷寫(xiě)法』。
<input v-model="searchText">
語(yǔ)法糖 等價(jià)于:
<input
:value="searchText"
@input="searchText = $event.target.value"
>
當(dāng)用戶(hù)在輸入框中輸入文本時(shí),userMessage
的值會(huì)實(shí)時(shí)更新,
并且當(dāng) userMessage
的值改變時(shí),輸入框中的值也會(huì)自動(dòng)更新。
v-model
在內(nèi)部相當(dāng)于使用 :value
和 @input
來(lái)實(shí)現(xiàn)數(shù)據(jù)的綁定和監(jiān)聽(tīng)。
// Parent.vue
<template>
<child v-model="value"></child>
</template>
<script>
export default {
data(){
return {
value:1
}
}
}
// Child.vue
<template>
<input :value="value" @input="handlerChange">
</template>
export default {
props:["value"],
methods:{
handlerChange(e){
this.$emit("input", e.target.value)
}
}
}
</script>
model 選項(xiàng)自定義 prop 和 event 的名稱(chēng)
默認(rèn)情況下,v-model
會(huì)使用子組件的 value
屬性作為 prop 名,使用 input
事件來(lái)觸發(fā)更新。
-
適應(yīng)不同的數(shù)據(jù)源,與其他組件集成不會(huì)產(chǎn)生命名沖突。
-
提高代碼可讀性: 比起value更具有語(yǔ)義,使其他開(kāi)發(fā)者更容易理解組件的預(yù)期用法和行為。
<!-- CustomInput.vue -->
<template>
<input :value="internalValue" @input="updateParentValue" />
</template>
<script>
export default {
props: {
// 使用自定義的 prop 名 customProp
customProp: String,
},
// 通過(guò) model 選項(xiàng)自定義 v-model 的 prop 和事件名
model: {
prop: 'customProp',
event: 'customEvent'
}
data() {
return {
internalValue: this.customProp
};
},
methods: {
// 使用自定義的事件名 customEvent
updateParentValue(event) {
this.internalValue = event.target.value;
// 觸發(fā)自定義事件,通知父組件更新值
this.$emit('customEvent', this.internalValue);
}
},
};
</script>
副作用:當(dāng)綁定響應(yīng)式對(duì)象上不存在的屬性,會(huì)讓它響應(yīng)式
// template中:
<el-input v-model="user.tel"></el-input>
// script中:
export default {
data() {
return {
user: {
name: '參宿7',
}
}
}
}
父子傳屬性/方法
父?jìng)髯?/h4>
this.$parent
this.$root
?: App.vue
this.$listeners:父組件.native 除外的監(jiān)聽(tīng)事件集合
調(diào)用:this.$listeners.事件名
$root
?: App.vue將父組件傳遞的事件監(jiān)聽(tīng)器綁定到子組件上,以實(shí)現(xiàn)一種“透明傳遞”的效果。這種方式使得子組件不需要顯式聲明和監(jiān)聽(tīng)來(lái)自父組件的事件
在父組件 自定義的所有事件,都被保存在子組件的vm.$listeners屬性里,和$attrs一樣可以層層傳遞
son
組件可以響應(yīng)father
組件的2個(gè)自定義事件speak()、write()
grandson
組件可以響應(yīng)father
組件的2個(gè)自定義事件speak()、write()
,并且還可以響應(yīng)son
組件的1個(gè)自定義事件sonCry()
子傳父
this.$children[0]
ref
父child ref="childComp",childComp.所有的屬性/方法
// Child.vue
export default {
data(){
return {
name:"沐華"
}
},
methods:{
someMethod(msg){
console.log(msg)
}
}
}
// Parent.vue
<template>
<child ref="child"></child>
</template>
<script>
export default {
mounted(){
const child = this.$refs.child
console.log(child.name) // 沐華
child.someMethod("調(diào)用了子組件的方法")
}
}
</script>
祖?zhèn)鲗Oprovide / inject依賴(lài)注入:推薦傳遞常量/方法
要注意的是 provide 和 inject 傳遞的數(shù)據(jù)不是響應(yīng)式的,除非傳入的就是一個(gè)可監(jiān)聽(tīng)的對(duì)象
父provide(){return obj }
obj={name:,msg:}
子inject[“name”,“msg”],this.msg
跨組件事件通信EventBus中央事件總線
定義
// 方法一:獨(dú)立的事件總線文件
// 抽離成一個(gè)單獨(dú)的 js 文件 Bus.js導(dǎo)出 ,然后在需要的地方導(dǎo)入
// 保持了代碼的模塊化和清晰性。事件總線和組件邏輯分離,使得維護(hù)和理解代碼變得更容易。
// Bus.js
import Vue from "vue"
export default new Vue()
// 方法二 全局掛載到Vue原型
// main.js
import Vue from "vue"
Vue.prototype.$bus = new Vue()
// 方法三 注入到 Vue 根對(duì)象上,作為Vue實(shí)例的數(shù)據(jù)屬性
// 組件通過(guò)this.$root.Bus訪問(wèn)
// main.js
import Vue from "vue"
new Vue({
el:"#app",
data:{
Bus: new Vue()
}
})
使用:emit、on、off
// 在需要向外部發(fā)送自定義事件的組件內(nèi)
<template>
<button @click="handlerClick">按鈕</button>
</template>
import Bus from "./Bus.js"
export default{
methods:{
handlerClick(){
// 自定義事件名 sendMsg
Bus.$emit("sendMsg", "這是要向外部發(fā)送的數(shù)據(jù)")
}
}
}
// 在需要接收外部事件的組件內(nèi)
import Bus from "./Bus.js"
export default{
mounted(){
// 監(jiān)聽(tīng)事件的觸發(fā)
Bus.$on("sendMsg", data => {
console.log("這是接收到的數(shù)據(jù):", data)
})
},
beforeDestroy(){
// 取消監(jiān)聽(tīng)
Bus.$off("sendMsg")
}
}
slot:父?jìng)髯咏M件,子傳父數(shù)據(jù)
單個(gè)/默認(rèn)/匿名插槽slot
v-slot="name",在2.6后可縮寫(xiě)為#"name"
父v-slot="子slot中的變量"
子slot :屬性名="變量"
// Child.vue
<template>
<div>
<slot :user="user"></slot>
</div>
</template>
export default{
data(){
return {
user:{ name:"沐華" }
}
}
}
// Parent.vue
<template>
<div>
<child v-slot="slotProps">
{{ slotProps.user.name }}
</child>
</div>
</template>
具名插槽slot name="":多個(gè)插槽,需要區(qū)分
<template>
// 匿名插槽
<slot/>
// 具名插槽
<slot name='title'/>
</template>
<script setup>
import { useSlots, reactive } from 'vue'
const slots = useSlots()
// 匿名插槽使用情況
const defaultSlot = reactive(slots.default && slots.default().length)
console.log(defaultSlot) // slot內(nèi)的標(biāo)簽
// 具名插槽使用情況
const titleSlot = reactive(slots.title && slots.title().length)
console.log(titleSlot) // 1
const state = reactive({
name: '張三',
age: '25歲'
})
</script>
<template>
<child>
// 匿名插槽
<span>我是默認(rèn)插槽</span>
// 具名插槽
<template #title>
<h1>我是具名插槽</h1>
</template>
</child>
</template>
作用域/帶數(shù)據(jù)的插槽
<template>
<slot name="footer" :scope="state" />
</template>
<script setup>
import { reactive } from 'vue'
const state = reactive({
name: '張三',
age: '25歲'
})
</script>
// { scope } 表示從插槽的內(nèi)容中解構(gòu)出一個(gè)名為 scope 的變量
<template #footer="{ scope }">
<footer>作用域插槽——姓名:{{ scope.name }},年齡{{ scope.age }}</footer>
</template>
內(nèi)置指令:數(shù)據(jù)/事件關(guān)聯(lián)DOM
將數(shù)據(jù)和事件處理程序與 DOM 元素關(guān)聯(lián),以實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)渲染、事件處理、條件渲染、循環(huán)渲染等功能。
v-bind(簡(jiǎn)寫(xiě):):綁定屬性到 Vue 實(shí)例中的數(shù)據(jù)
它允許你在模板中動(dòng)態(tài)設(shè)置元素屬性的值
<div v-bind:id="id"></div>
<div :id="id"></div>
v-on (簡(jiǎn)寫(xiě)@): 監(jiān)聽(tīng)DOM事件、觸發(fā)Vue實(shí)例中的方法
<button @click="doSomething">Click me</button>
vue父子組件之間雙向數(shù)據(jù)綁定的(vue2/vue3)_vue3父子組件雙向綁定_前端一枚的博客-CSDN博客文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-586294.html
Vue3的8種和Vue2的12種組件通信,值得收藏 - 掘金文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-586294.html
到了這里,關(guān)于react和vue2/3父子組件的雙向綁定的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!