父子元件通訊
prop
event
style和class
natvie修飾符
$listeners
v-model
sync修飾符
$parent和$children
$slots和$scopedSlots
ref
跨元件通訊
Provide和Inject
router
vuex
store模式
eventbus
父子元件通訊
prop
最常見的元件通訊方式,由父元件向子元件傳遞。prop可接收一個陣列或物件
//子元件
<script>
export default {
name: "Comp",
//陣列方式 props:[....]
// ↓ 物件方式
props: {
datas: {
type: Object,
default: () => {
return {};
}
},
}
</script>
event
子元件向父元件傳送通知,並傳遞引數
子元件
methods:{
// 通過 $emit向父元件傳送一個通知
handleEvent(){
this.$emit('eventMsg', option)
}
}
父元件
methods:{
// 監聽子元件定義的方法
eventMsg(option){
console.log(option);
}
}
style 和 class
父元件可以向子元件傳遞style 和 class ,style 和 class將合併到子元件根元素上
父元件
<template>
<div id="app">
<HelloWorld
style="color:red"
class="hello"
msg="Welcome to Your Vue.js App"
/>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
components: {
HelloWorld,
},
};
</script>
子元件
<template>
<div class="world" style="text-align:center">
<h1>{{msg}}</h1>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
};
</script>
最終渲染結果
<div id="app">
<div class="hello world" style="color:red; text-aling:center">
<h1>Welcome to Your Vue.js App</h1>
</div>
</div>
attribute
父元件在使用子元件時,在子元件上定義一些屬性,這些屬性將作用於子元件的根元素上,但是不包括style和class
父元件
<HelloWorld data-a="1" data-b="2" msg="Welcome to Your Vue.js App" />
子元件
<template>
<div>
<h1>{{msg}}</h1>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String,
},
created() {
// 通過$attrs獲取父元件定義的 attribute
console.log(this.$attrs); // {"data-a":"1","data-b":"2"}
},
};
</script>
最終渲染結果
<div id="app">
<div data-a="1" data-b="2">
<h1>Welcome to Your Vue.js App</h1>
</div>
</div>
Tip:子元件可以通過定義 inheritAttrs:false 來緊張 attribute 附著在子元件根元素上 但不影響通過 $attrs 獲取資料
natvie修飾符
在註冊事件時,父元件可以通過 navite 修飾符,將事件註冊到子元件根元素上
父元件
<template>
<div id="app">
<HelloWorld @click.native="handleClick" />
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
components: {
HelloWorld,
},
methods: {
handleClick() {
console.log(1);
},
},
};
</script>
子元件
<template>
<div>
<h1>Hello World</h1>
</div>
</template>
最終渲染結果
<template>
<div id="app">
<h1>Hello World</h1>
</div>
</template>
// 當點選app時。會觸發父元件定義的 handleClick 方法
$listeners
子元件可以通過 $listeners 獲取父元件傳遞過來的所有處理函式
v-model
父元件在使用子元件時,可以在子元件上繫結v-model,子元件通過定義model的prop和event還獲取父元件定義的值
父元件
`
<Compn v-model="datas" />
`
子元件
<script>
export default {
//分類篩選元件
name: "sortFilter",
//定義實現v-modal的屬性與事件
model: {
prop: "value",
event: "change"
},
props: {
//繫結的值
value: {
type: [String, Number],
default: ""
}
},
created() {
console.log(this.value)
},
</script>
sync 修飾符
和 v-model類似,用於雙向資料繫結,不同點在於 v-model只能針對一個資料進行繫結,而 sync 修飾符沒有限制
子元件
<template>
<div>
<p>
<button @click="$emit(`update:num1`, num1 - 1)">-</button>
{{ num1 }}
<button @click="$emit(`update:num1`, num1 + 1)">+</button>
</p>
<p>
<button @click="$emit(`update:num2`, num2 - 1)">-</button>
{{ num2 }}
<button @click="$emit(`update:num2`, num2 + 1)">+</button>
</p>
</div>
</template>
<script>
export default {
props: ["num1", "num2"],
};
</script>
父元件
<template>
<div id="app">
<Numbers :num1.sync="n1" :num2.sync="n2" />
<!-- 等同於 -->
<Numbers
:num1="n1"
@update:num1="n1 = $event"
:num2="n2"
@update:num2="n2 = $event"
/>
</div>
</template>
<script>
import Numbers from "./components/Numbers.vue";
export default {
components: {
Numbers,
},
data() {
return {
n1: 0,
n2: 0,
};
},
};
</script>
$parent 和 $children
在元件內部,可以通過$parent 和$children屬性,分別獲取當前元件的父元件和子元件例項
<template>
<div class="hello">
<button @click="handelParent">獲取父元件例項</button>
<button @click="handelChild">獲取子元件例項</button>
<Child />
</div>
</template>
<script>
import Child from "./Children.vue";
export default {
name: "HelloWorld",
props: {
msg: String,
},
components: {
Child,
},
methods: {
handelParent() {
console.log("父元件例項:", this.$parent);
},
handelChild() {
console.log("子元件例項", this.$children);
},
},
};
</script>
ref
在使用元件時,可以通過在元件上定義ref來獲取元件例項
<template>
<div class="hello">
<button @click="handelChild">獲取子元件例項</button>
<Child ref="child" />
</div>
</template>
<script>
import Child from "./Children.vue";
export default {
name: "HelloWorld",
props: {
msg: String,
},
components: {
Child,
},
methods: {
handelChild() {
console.log("子元件例項", this.$refs.child);
},
},
};
</script>
跨元件通訊
provide 和 Inject
provide和inject 可以實現深層元件通訊,頂層元件只需定義provide,底層元件通過inject接受資料
頂層元件
// 父元件
provide(){
msg:'hello Children'
},
// 子元件
inject: ['msg']
created () {
console.log(this.msg) // hello Children
}
router
如果一個組將改變了位址列,所有監聽位址列的組將都會做出相應的改變,
//監聽路由變化
watch:{
$route(to,from) {
console.log(to,from);
}
}
vuex
vuex 過於笨重,通常不建議在小型專案中使用,小型專案可以使用store 或 eventbus代替vuex,vuex本質上就是一個資料倉儲。在此不做過多贅述,先挖一個坑,下回再敘。
store 模式
store模式其實就是一個普通的js模組,各元件可以匯入該模組,將資料放到data裡面,此時store就具有響應式了。
// 匯出一個 store.js模組
export default {
userInfo:{...},
loginInfo:{...}
}
// A子元件匯入 store模組
import store from './store.js'
export default {
name:'Acompon',
data(){
userInfo: store.userInfo
}
}
// B子元件匯入 store模組
import store from './store.js'
export default {
name:'Bcompon',
data(){
loginInfo: store.loginInfo
}
}
tip: store模式的缺點是無法跟蹤資料的改變,因為所有元件都可以更改資料
eventbus
eventbus事件匯流排相當於一個橋樑,作為所有組將的一個事件中心,所有元件皆可往eventbus裡面註冊事件,也可以監聽事件。
// 定義一個eventbus模組
import Vue from 'vue'
export const EventBus = new Vue()
// 在main.js裡匯入該模組並掛載到全域性
// main.js
import eventbus from './eventbus.js'
Vue.prototype.$eventBus = eventbus
所有子元件向eventbus裡組 註冊 或者 監聽 事件
// 元件A 通過 $emit()註冊事件
sendMsg() {
this.$eventBus.$emit("aMsg", 'from A');
}
// 元件B 通過 $on 監聽事件
this.$eventBus.$on("aMsg", (msg) => {
// A傳送來的訊息
console.log(msg) // from A
})
// 通過 $off() 可以關閉事件