一、 組件化編程
組件化開發(fā)是在ES6中提出來的,可以提高頁(yè)面的復(fù)用率,提高開發(fā)效率。它是一套模板化的代碼,要有<template>、<script>、<style>三個(gè)標(biāo)簽,分別用來定義布局、腳本、樣式。而且<template>下必須有一個(gè)根節(jié)點(diǎn)。
1.1 編寫App.vue和HelloWorld.vue
HelloWorld.vue
<template>
<div> <!-- template的根節(jié)點(diǎn),是必須的 -->
<h1 class="title">{{msg}}</h1>
</div>
</template>
<script>
export default { <!-- 向外暴露成員,表示向外暴露該組件 -->
data() {
return {
msg: 'Hello World'
}
}
}
</script>
<style>
.title {
color: red;
}
</style>
App.vue
<template>
<div>
<p>{{article}}</p>
<Helloworld></Helloworld> <!-- 自定義的組件Helloworld.vue -->
</div>
</template>
<script>
<!-- 引入HelloWorld.vue組件 -->
import Helloworld from './components/HelloWorld.vue'
export default {
<!-- 需要在當(dāng)前組件中來定義引入的組件 -->
components: {Helloworld},
data() { //組件化編程必須使用定義data方法
return {
article: 'Vue組件間通信'
}
}
}
</script>
<style>
</style>
1.2 定義入口JS文件
import Vue from 'vue' //引入vue
import App from './App.vue' //引入自己定義的App.vue,使用變量App來接收
new Vue({
render: h => h(App), //將App組件渲染到index.html中
}).$mount("#app")
render是Vue中的一個(gè)方法,方法的定義形式如下:
// render最原始的,而傳入的參數(shù)createElement又是一個(gè)函數(shù),用來生成dom結(jié)構(gòu)
render: function(createElement){
return createElement(模板);
}
// 按照ES6的箭頭函數(shù)的寫法,進(jìn)行第一次演變
render: createElement => createElement(模板)
// 將上面的createElement變?yōu)閔,那么就得到最終的形式
render: h => h(App)
$mount("#id")該方法的作用是先實(shí)例化Vue對(duì)象,接著在掛載到指定Id的節(jié)點(diǎn)上
二、 組件通信
2.1 props
父組件向子組件傳值
父組件 App.vue
<template>
<div>
<h1>Hello World</h1>
<!-- 前面一個(gè)msg標(biāo)識(shí)子組件用于接收的變量名, 引號(hào)中的msg是當(dāng)前組件的值 -->
<child :msg="msg"/>
</div>
</template>
<script>
import child from './Child.vue'
export default {
components: {
child
},
data() {
return {
msg: '這個(gè)信息來源于父組件'
}
}
}
</script>
<style></style>
子組件 Child.vue
<template>
<div>
<p>{{msg}}</p>
</div>
</template>
<script>
export default {
// 使用props接收父組件傳遞過來的值
props: {
msg: String
}
}
</script>
<style></style>
2.2 事件綁定、監(jiān)聽、取值
2.2.1 子組件操作父組件
通過事件綁定,子組件向父組件傳值
父組件 App.vue
<template>
<div>
<input type="text" v-model="value">
<hr>
<Child @dosomething="changeValue"/>
</div>
</template>
<script>
import Child from './components/Child.vue'
export default {
components: {
Child
},
data() {
return {
value: ''
}
},
methods: {
changeValue(value) {
this.value = value;
}
}
}
</script>
<style>
</style>
子組件 Child.vue
<template>
<div>
<button @click="dosomething">子組件按鈕</button>
</div>
</template>
<script>
export default {
methods: {
dosomething() {
// 調(diào)用父組件綁定的事件 dosomething,然后調(diào)用changeValue方法,并傳值
this.$emit('dosomething', '張某人');
}
}
}
</script>
<style>
</style>
2.2.2 父組件監(jiān)聽子組件
ref用于組件間引用
父組件 App.vue
<template>
<div>
<input type="text" v-model="value">
<hr>
<Child ref="child"/>
</div>
</template>
<script>
import Child from './components/Child.vue'
export default {
components: {
Child
},
mounted() {
// 將當(dāng)前組件中的changeValue方法,綁定到名為changeValue中監(jiān)聽事件中,
// 子組件通過 this.$emit('changeValue', '張某人') 變會(huì)調(diào)用父組件的changeValue方法
this.$refs.child.$on('changeValue', this.changeValue);
},
data() {
return {
value: ''
}
},
methods: {
changeValue(value) {
this.value = value;
}
}
}
</script>
<style>
</style>
2.2.3 父組件取子組件中的值
父組件 App.vue
<template>
<div>
<input type="text" v-model="value">
<button @click="changeValue">取子組件的值</button>
<hr>
<Child ref="child"/>
</div>
</template>
<script>
import Child from './components/Child.vue'
export default {
components: {
Child
},
data() {
return {
value: ''
}
},
methods: {
changeValue() {
this.value = this.$refs.child.value;
}
}
}
</script>
<style>
</style>
子組件 Child.vue
<template>
<div>
<p>我是子組件,我中間定義了一個(gè)value='張某人'的數(shù)據(jù)</p>
</div>
</template>
<script>
export default {
data() {
return {
value: '張某人'
}
}
}
</script>
<style>
</style>
2.3 訂閱與發(fā)布
??訂閱與發(fā)布(Publish發(fā)布、subscribe訂閱)可以應(yīng)用到各種場(chǎng)景之下,不僅僅是父子組件之間,也可以應(yīng)用于兄弟組件之間。
安裝pubsub-js這個(gè)類庫(kù):
npm install pubsub-js --save
父組件 App.vue
<template>
<div>
<input type="text" v-model="value"/>
<hr>
<Child ref="child"/>
</div>
</template>
<script>
import Child from './components/Child.vue'
import PubSub from 'pubsub-js'
export default {
components: {
Child
},
data() {
return {
value: ''
}
},
mounted() {
PubSub.subscribe('channel1', (msg, value) => {
this.changeValue(value);
});
},
methods: {
changeValue(value) {
this.value = value;
}
}
}
</script>
<style>
</style>
子組件 Child.vue
<template>
<div>
<button @click="pub">子組件發(fā)布消息</button>
</div>
</template>
<script>
import PubSub from 'pubsub-js'
export default {
methods: {
pub() {
PubSub.publish('channel1', '張某人');
}
}
}
</script>
<style>
</style>
2.4 插槽
??插槽的作用說白了就是一個(gè)占位的作用。
父組件 App.vue
<template>
<List>
<!--
可以簡(jiǎn)寫為這種形式
<template #title>
-->
<template v-slot:title>
<h2>插槽案例</h2>
<button class="btn btn-danger btn-sm">點(diǎn)擊</button>
</template>
<!--
可以簡(jiǎn)寫為這種形式
<template #title="props">
-->
<template v-slot:item="props">
<h3>插槽屬性</h3>
<p>屬性值:{{props}}</p>
</template>
</List>
</template>
<script>
import List from './components/List.vue'
export default {
components: {
List
}
}
</script>
<style>
.site-header {
text-align: center;
}
</style>
子組件 Child.vue
<template>
<div>
<slot name="title"></slot>
<slot name="item" v-bind="person"></slot> <!-- 組件屬性 -->
</div>
</template>
<script>
export default {
data() {
return {
person: {age: 10, name: 'zhangsan'}
}
}
}
</script>
<style>
</style>