建網(wǎng)站 外貿(mào)微信推廣平臺哪里找
一、Vue 組件化開發(fā)概述
組件化是 Vue.js 的核心概念之一,它允許將界面拆分成獨立、可復(fù)用的組件,使得開發(fā)大型應(yīng)用變得更加簡單和高效。
組件的定義是實現(xiàn)應(yīng)用中局部功能代碼和資源的集合。Vue.js 的組件化用于將 UI 頁面分割為若干組件進行組合和嵌套。它是一種高效的處理復(fù)雜應(yīng)用系統(tǒng)的方式,能夠更好地明確功能模塊的作用。目的是為了解耦,把復(fù)雜系統(tǒng)拆分成多個組件,分離組件邊界和責(zé)任,便于獨立升級和維護。
Vue 的組件化將 UI 頁面分割為若干組件進行組合和嵌套。組件化是一種強大的開發(fā)模式,具有諸多好處。比如,它能提高開發(fā)效率,方便重復(fù)使用,簡化調(diào)試步驟,提升項目可維護性,便于多人協(xié)同開發(fā)。組件是 Vue.js 最強大的功能之一,讓我們用獨立可復(fù)用的小組件來構(gòu)建大型應(yīng)用,開發(fā)效率更快更敏捷。
在 Vue 中,組件可以分為頁面組件、業(yè)務(wù)組件和通用組件。Vue 的組件是基于配置的,我們通常編寫的組件是組件配置而非組件,框架后續(xù)會生成其構(gòu)造函數(shù),它們基于 VueComponent,擴展于 Vue。Vue 中常見組件化技術(shù)有屬性 prop,自定義事件,插槽等,它們主要用于組件通信、擴展等。合理的劃分組件,有助于提高應(yīng)用性能。組件應(yīng)該是高內(nèi)聚、低耦合的,遵循單向數(shù)據(jù)流的原則。
二、組件復(fù)用的方法
(一)引入組件并注冊
- 可以全局注冊組件,如 Vue.component('my-component', {...})。全局注冊組件有多種方式,一種是在 main.js 中直接注冊,例如:
// 引入
import PageTools from '@/components/PageTools';
// 注冊為全局組件
Vue.component('PageTools', PageTools);
這種方式的缺點是如果需要注冊的全局組件非常多,我們需要一個一個引入,然后分別調(diào)用 Vue.component 方法,main.js 文件會變的很大,不好維護。另一種是使用插件的形式注冊,在統(tǒng)一注冊的入口文件中:
// 引入
import PageTools from './PageTools';
export default {
install(Vue) {
// 注冊全局組件
Vue.component('PageTools', PageTools);
}
};
入口文件注冊插件(main.js):
import Components from './components';
Vue.use(Components);
此外,還可以在 main.js 中引入組件,然后通過 Vue.component 方法全局注冊組件,例如:
// 全局注冊組件
import MyCounter from "./components/MyCounter.vue";
Vue.component('MyCounter', MyCounter);
全局注冊后,在項目的任意位置均可使用組件。
- 也可在特定實例中局部注冊組件,如 new Vue({components: {'my-component': {...}}})。局部注冊插件,是指在某個 Vue 頁面中局部使用。代碼如下:
import MyCounter from '@/components/MyCounter.vue';
export default {
name: 'Home',
components: {
MyCounter
}
};
此處需要注意,首先得在 components 屬性中注冊組件,然后才能在頁面代碼部分引用組件。
- 單文件組件(.vue 文件)的使用。模塊化就是把一個很大的東西,拆分成一些小的東西,vue 組件就是把一個大的 html 文件,拆成了一些小的 vue 文件,這個 vue 文件里面,包括了 html,js,css。當(dāng)要去使用組件的時候,就需要暴露這些組件【export】,然后引入【import】。
vue-cil 腳手架使用全局安裝(僅第一次執(zhí)行):npm install -g @vue/cli。此后命令行就有了 vue 這個命令。切換到要創(chuàng)建的目錄,然后使用命令創(chuàng)建項目vue create xxx。啟動項目npm run serve。
由于瀏覽器不認(rèn)識.vue 文件,就需要我們搭建 vue 腳手架,vue 腳手架給我們配置好了基本上所有東西,我們直接在里面寫項目就可以了。單文件組件格式由三部分組成:\u003ctemplate\u003e、\u003cstyle\u003e、\u003cscript\u003e。\u003ctemplate\u003e 里面寫 html,必須有一個根標(biāo)簽;\u003cstyle\u003e 里面寫 css,scoped 樣式作用是讓樣式局部生效,防止和其他組件樣式?jīng)_突被覆蓋;\u003cscript\u003e 里面寫 js,export default 暴露組件。組件使用時,首先要在我們使用的地方去引入組件,然后配置一項 components: {組件名,組件名},最后直接當(dāng)做標(biāo)簽中使用\u003c組件名\u003e\u003c/組件名\u003e。
(二)在模板中使用組件
- 直接在 template 里面使用引入的 component 的文件,如。在普通的標(biāo)簽?zāi)0逯?#xff0c;必須使用短橫線的方式使用組件。如果使用駝峰式命名組件,那么在使用組件的時候,只能在模板字符串中使用駝峰命名法。注意事項:組件參數(shù)的 data 值必須是函數(shù);組件模板必須是單個跟元素。全局組件和局部組件都可以通過這種方式在模板中使用。例如:
<div id="app">
<hello-world>
</hello-world>
<peng-ke>
</peng-ke>
</div>
Vue.component('HelloWorld', {
data: function() {
return {
msg: 'helloworld'
};
},
template: `<p>{{msg}}</p>`
});
var pengke = {
data: function() {
return {
msg: '你好,pengke'
};
},
template: `<h3>{{msg}}</h3>`
};
var vm = new Vue({
el: '#app',
data: {},
components: {
'peng-ke': pengke
}
});
三、組件的注冊方式
(一)在實例中注冊
在 Vue 中,可以在特定的實例中局部注冊組件。局部注冊插件是指在某個 Vue 頁面中局部使用。首先需要引入組件,然后在組件的配置對象中通過components屬性進行注冊。例如:
import MyCounter from '@/components/MyCounter.vue';
export default {
name: 'Home',
components: {
MyCounter
}
};
此處需要注意,首先得在components屬性中注冊組件,然后才能在頁面代碼部分引用組件。
(二)在 Vue 中注冊
全局注冊后可以在任何實例中使用,如在main.js中引入組件,然后通過Vue.component方法全局注冊組件:
// 全局注冊組件
import MyCounter from "./components/MyCounter.vue";
Vue.component('MyCounter', MyCounter);
全局注冊后,在項目的任意位置均可使用組件。這種方式適用于一些通用的組件,方便在整個項目中復(fù)用。但如果需要注冊的全局組件非常多,一個個引入并注冊會使main.js文件變得很大,不好維護。此時可以使用插件的形式注冊,在統(tǒng)一注冊的入口文件中:
// 引入
import PageTools from './PageTools';
export default {
install(Vue) {
// 注冊全局組件
Vue.component('PageTools', PageTools);
}
};
入口文件注冊插件(main.js):
import Components from './components';
Vue.use(Components);
四、組件的 props
(一)定義 props
在 Vue.js 中,組件的 props 是子組件聲明的屬性,它們允許子組件從父組件接收數(shù)據(jù)。子組件通過聲明 props 來定義它期望從父組件接收哪些數(shù)據(jù)。例如,子組件可以這樣定義 props:
import { defineProps } from 'vue';
const props = defineProps({
name: String,
age: Number
});
export default {
props
};
(二)傳遞 props
在父組件中,可以通過普通的 HTML 屬性的方式將數(shù)據(jù)傳遞給子組件。例如:
<template>
<div>
<ChildComponent :name="userName" :age="userAge" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const userName = ref('張三');
const userAge = ref(30);
</script>
五、組件事件
(一)自定義事件的創(chuàng)建和觸發(fā)
在 Vue 中,自定義事件可以讓子組件向父組件傳遞特定的信息或觸發(fā)特定的操作。自定義事件有三個關(guān)鍵要素:事件源(通常是子組件)、事件類型和監(jiān)聽器(通常是父組件中的方法)。
例如,我們可以創(chuàng)建一個名為myComponent的子組件,并在其中定義一個自定義事件。當(dāng)特定條件滿足時,觸發(fā)這個自定義事件:
export default {
data() {
return {
someCondition: false
};
},
methods: {
triggerEvent() {
if (this.someCondition) {
this.$emit('myCustomEvent', 'some data');
}
}
}
};
(二)父組件監(jiān)聽子組件事件
父組件可以通過v-on指令監(jiān)聽子組件觸發(fā)的自定義事件。例如:
<template>
<div>
<my-component @myCustomEvent="parentMethod"></my-component>
</div>
</template>
<script>
import myComponent from './myComponent.vue';
export default {
components: {
myComponent
},
methods: {
parentMethod(data) {
console.log('子組件觸發(fā)了自定義事件,傳遞的數(shù)據(jù)是:', data);
}
}
};
</script>
(三)父組件處理事件
當(dāng)父組件監(jiān)聽到子組件觸發(fā)的事件后,可以在對應(yīng)的處理方法中進行各種操作。比如,可以更新父組件的數(shù)據(jù)、調(diào)用其他方法或者執(zhí)行一些特定的邏輯。
例如,在接收到子組件傳遞的數(shù)據(jù)后,父組件可以根據(jù)這個數(shù)據(jù)進行一些計算或狀態(tài)更新:
parentMethod(data) {
this.someParentData = data * 2;
// 或者調(diào)用其他方法進行進一步處理
this.someOtherMethod(data);
}
六、Vue 實現(xiàn)邏輯復(fù)用的方式
(一)插件(Plugins)
插件可以全局或局部地添加功能,例如可以通過創(chuàng)建一個插件對象,在其中定義一些方法或?qū)傩?#xff0c;然后使用Vue.use()方法全局注冊插件,或者在特定的 Vue 實例中局部使用插件。這樣可以在多個組件中共享一些通用的功能,提高代碼的復(fù)用性。
(二)混入(Mixins)
混入包含可復(fù)用的組件邏輯,如定義一個混入對象,可以包含數(shù)據(jù)、方法、生命周期鉤子等組件選項。例如:
const myMixin = {
data() {
return {
sharedData: 'This is shared data'
};
},
methods: {
sharedMethod() {
console.log('This is a shared method.');
}
},
created() {
console.log('Mixing in created hook.');
}
};
然后在組件中使用混入,可以通過在組件的選項中添加mixins屬性,并將混入對象作為數(shù)組元素傳入。例如:
import { defineComponent } from 'vue';
const MyComponent = defineComponent({
mixins: [myMixin],
data() {
return {
componentData: 'Component specific data'
};
},
template: `<div>{{sharedData}} - {{componentData}}</div>`
});
這樣,組件就可以繼承混入對象中的邏輯,實現(xiàn)代碼的復(fù)用?;烊朐?Vue 中提供了一種靈活的方式來共享通用的功能,減少重復(fù)代碼,提高開發(fā)效率。
七、內(nèi)容分發(fā)——插槽(Slots)
(一)默認(rèn)插槽
默認(rèn)插槽也叫匿名插槽,可以在子組件中使用一個<slot>標(biāo)簽來作為占位符,父組件可以通過這個標(biāo)簽向子組件中傳遞內(nèi)容。在父組件中使用子組件時,可以在標(biāo)簽中直接寫入要插入的內(nèi)容,也可以使用v-bind指令綁定父組件中的數(shù)據(jù)。子組件的模板中可以使用this.$slots.default來渲染插入的內(nèi)容。
例如,子組件MyComponent的代碼如下:
<template>
<div>
<slot>默認(rèn)內(nèi)容...</slot>
</div>
</template>
<script>
export default {
name: 'MyComponent'
};
</script>
父組件中使用MyComponent:
<template>
<div>
<MyComponent>
<p>這是插入的內(nèi)容</p>
</MyComponent>
</div>
</template>
<script>
import MyComponent from './MyComponent.vue';
export default {
components: {
MyComponent
}
};
</script>
(二)具名插槽
具名插槽就是給每一個插槽增加了一個name屬性讓每一個插槽都有自己的名字,這樣方便,父組件中的配置按照相應(yīng)的地方插入。
父組件中:
<Category title="美食">
<img slot="center" src="D:\\gr信息\\圖集\\2.jpg" alt="1"/>
<a slot="footer" href="http://www.baidu.com/">牛肉飯</a>
</Category>
<Category title="游戲":listData="games">
<ul slot="center">
<!-- 這時候因為變量直接在app.vue中所以可以直接去遍歷game遍歷完了再利用插槽的功能傳遞給Category.vue -->
<li v-for="(g, index) in games" :key="index">{{ g }}</li>
<div class="foot" slot="footer">
<a href="http://www.baidu.com/">網(wǎng)絡(luò)游戲</a>
<a href="http://www.baidu.com/">單機游戲</a>
</div>
</ul>
</Category>
<Category title="電影":listData="films">
<!-- controls 可以讓video可以播放 -->
<videoslot="center" controlssrc="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"/>
<template v-slot:footer>
<div class="dianyin" slot="footer">
<a href="http://www.baidu.com/">經(jīng)典</a>
<a href="http://www.baidu.com/">熱門</a>
<a href="http://www.baidu.com/">推薦</a>
</div>
<h4>歡迎觀影</h4>
</template>
</Category>
子組件中:
<template>
<div class="category">
<h3>{{ title }}分類</h3>
<!-- 定義一個默認(rèn)插槽,那么App.vue中相應(yīng)的組件標(biāo)簽里標(biāo)簽體的內(nèi)容會往這個插槽中放置 -->
<slot name="center"></slot>
<slot name="footer"></slot>
</div>
</template>
<script>
export default {
name: 'Category',
props: ['title']
};
</script>
<style>
.category {
background-color: skyblue;
width: 200px;
height: 300px;
}
h3 {
text-align: center;
background-color: orange;
}
</style>
要點:具名插槽:即具有名字的插槽,在默認(rèn)插槽基礎(chǔ)上指定插槽的名字(name = " ")。父組件指明放入子組件的哪個插槽slot = "footer",如果是template可以寫成v-slot : footer。
父組件中:
<Category>
<template slot="center">
<div>html結(jié)構(gòu)1</div>
</template>
<template v-slot:footer>
<div>html結(jié)構(gòu)2</div>
</template>
</Category>
子組件中:
<template>
<div>
<!-- 定義插槽 -->
<slot name="center">插槽默認(rèn)內(nèi)容...</slot>
<slot name="footer">插槽默認(rèn)內(nèi)容...</slot>
</div>
</template>
<script>
export default {
name: 'Category'
};
</script>
(三)作用域插槽
作用域插槽是一種特殊的插槽,它能夠接收來自父組件的數(shù)據(jù),并在子組件中使用。在 Vue2 中,作用域插槽是通過slot-scope實現(xiàn)的,而在 Vue3 中,作用域插槽是通過v-slot實現(xiàn)的。
例如,子組件代碼如下:
<template>
<div>
<!-- 這是一個具名插槽,name=sun是這個插槽的名字 -->
<slot name="sun":data="data"></slot>
</div>
</template>
<script>
// import Vue from 'vue';
export default {
data() {
return {
data: '我是子組件的數(shù)據(jù)'
};
}
};
</script>
如果想要用到子組件的數(shù)據(jù)并展示的話,就可以使用作用域插槽了。首先得在子組件的slot中如同使用prop傳值一樣,綁定需要傳遞的數(shù)據(jù),然后在父組件中使用v-slot去獲取傳過來的數(shù)據(jù)并結(jié)構(gòu)。
父組件代碼如下:
<template>
<!-- sun就是插槽的名字 -->
<!-- {data}是用結(jié)構(gòu)的方式來獲取的 -->
<Sun v-slot:sun="{data}">{{data}}</Sun>
</template>
<script>
import Sun from './Sun.vue';
export default {
name: 'Father',
components: {
Sun
}
};
</script>
(四)使用插槽
插槽是 Vue 中一個非常有用的工具,可以幫助我們創(chuàng)建可重用的組件,實現(xiàn)動態(tài)內(nèi)容展示,以及提高代碼的可維護性和可擴展性。
在使用插槽時,可以根據(jù)實際需求選擇默認(rèn)插槽、具名插槽或作用域插槽。
默認(rèn)插槽適用于只有一個插槽位置的情況,父組件可以直接在子組件標(biāo)簽中插入內(nèi)容或使用v-bind指令綁定數(shù)據(jù)。
具名插槽可以定義多個插槽,每個插槽都有一個名字,父組件可以通過slot屬性或v-slot指令將內(nèi)容插入到特定的插槽位置。
作用域插槽允許子組件將數(shù)據(jù)傳遞給父組件,父組件可以在插槽中使用這些數(shù)據(jù)來渲染內(nèi)容。
(五)作用域插槽的使用
作用域插槽可以用于父組件向子組件傳遞數(shù)據(jù),同時子組件可以自定義顯示方式。比如,我們可以在父組件中傳遞一組數(shù)據(jù)給子組件,然后在子組件中使用作用域插槽來自定義顯示方式,這樣就能夠?qū)崿F(xiàn)復(fù)雜的 UI 效果。
實際應(yīng)用如下:
父組件代碼如下:
<template>
<div>
<child-component:list="list">
<template v-slot:item="{ item }">
<div class="item":class="{ active: item.active }">{{ item.name }}</div>
</template>
</child-component>
</div>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue';
const list = ref([
{ name: 'item1', active: true },
{ name: 'item2', active: false },
{ name: 'item3', active: true }
]);
</script>
子組件代碼如下:
<template>
<div>
<ul>
<li v-for="item in list":key="item.name">
<slot name="item":item="item"></slot>
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import { withDefaults, defineProps } from 'vue';
interface props {
list: Array;
}
const props = withDefaults(defineProps<props>(), {
list: () => []
});
</script>
在父組件中,我們通過v-slot來定義作用域插槽,然后在子組件中使用slot來引用這個插槽。在子組件中,我們可以使用item來訪問從父組件傳遞過來的數(shù)據(jù),并自定義顯示方式。
八、組件通信方式
(一)父子組件通信
- Props 和 Events:父組件通過 props 向子組件傳遞數(shù)據(jù),子組件通過$emit向父組件發(fā)送事件。這種方式簡單直接,在 Vue 開發(fā)中被廣泛應(yīng)用。例如,子組件可以定義為<button @click=\"increment\">Increment</button>,父組件則使用<child-component :initial-count=\"count\" @increment=\"count++\"></child-component>的方式進行通信。在子組件中,通過 props 接收父組件傳遞的initial-count屬性,然后在按鈕被點擊時,觸發(fā)increment方法,通過$emit向父組件發(fā)送事件,父組件接收到事件后執(zhí)行count++操作,實現(xiàn)數(shù)據(jù)的雙向傳遞。
(二)Event Bus(非官方,但常用)
通過一個事件總線(通常是一個 Vue 實例)來通信。在 Vue 中,當(dāng)需要在非父子組件之間進行通信時,Event Bus 是一種常用的方法。例如,可以創(chuàng)建一個全局的事件總線對象:
const eventBus = new Vue();
在組件中,可以使用$emit和$on方法來觸發(fā)和監(jiān)聽事件。例如,在發(fā)送事件的組件中:
eventBus.$emit('customEvent', 'some data');
在接收事件的組件中:
eventBus.$on('customEvent', (data) => {
console.log(data);
});
(三) listeners
listeners 包含了父作用域中的(不含.native 修飾器的)v-on 事件監(jiān)聽器。在 Vue 中, listeners 可以幫助我們更好地處理組件之間的通信和屬性傳遞。例如,子組件可以通過$attrs獲得父組件在子組件上添加的屬性(除了子組件 prop 聲明的以外的屬性),并且可以通過v-bind="$attrs"的方式,將屬性自動綁定到子組件的某標(biāo)簽上。同時,子組件可以通過$listeners獲取父組件綁定在子組件上的所有事件監(jiān)聽器,并通過類似this.$listeners.click的方式將事件傳遞給父組件處理。
(四)provide/inject
provide:祖父組件可以使用 provide 來提供數(shù)據(jù)。inject:后代組件可以使用 inject 來注入數(shù)據(jù)。在 Vue 中,provide/inject 是一種處理層級嵌套的數(shù)據(jù)通信方式。父組件通過 provide 來提供變量,然后在子組件中通過 inject 來注入變量。無論組件嵌套多深,provide 是個函數(shù),返回值一個對象;inject 是一個數(shù)組,用來接收 provide 傳遞過來的對象。例如:
const App = {
data() {
return {
title: "老爹"
};
},
// provide 提供變量
provide() {
return {
msg: "老爹的數(shù)據(jù)"
};
},
template: `<div><A></A></div>`,
};
Vue.component('B', {
data() {
return {
count: 0
};
},
// 通過 inject 去接收
inject: ['msg'],
created() {
console.log(this.msg);
},
template: `<div>{{msg}}</div>`,
});
Vue.component('A', {
data() {
return {};
},
created() {
// 通過 this.$parent 獲取父組件的數(shù)據(jù),支持連續(xù)鏈?zhǔn)讲僮?/code>
console.log(this.$parent.$parent);
console.log(this.$children);
console.log(this);
},
template: `<div><B></B></div>`,
});
new Vue({
el: '#app',
data: {},
components: {
// 2.掛載子組件 App
App
}
});
(五)狀態(tài)管理庫(Vuex)
對于復(fù)雜應(yīng)用,可以使用 Vuex 來集中管理狀態(tài)。Vuex 是 Vue.js 的狀態(tài)管理模式和庫。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。例如,在一個計數(shù)器應(yīng)用中,可以使用 Vuex 來管理計數(shù)器的狀態(tài):
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
}
},
actions: {
incrementAction({ commit }) {
commit('increment');
},
decrementAction({ commit }) {
commit('decrement');
}
},
getters: {
countGetter(state) {
return state.count;
}
}
});
在組件中,可以使用mapState、mapMutations和mapActions輔助函數(shù)來自動將 Vuex store 的狀態(tài)和 actions 映射為組件的屬性和方法:
<!-- Counter.vue -->
<template>
<div>
<h1>{{ count }}</h1>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
computed: {
...mapState(['count'])
},
methods: {
...mapActions(['incrementAction', 'decrementAction'])
}
};
</script>
(六)ref
...
(七) children
使用 children 可能會導(dǎo)致組件之間的耦合度增加,這可能會使組件更難以重用和測試。在 Vue 中,子組件可以通過$parent訪問父實例,父組件可以通過$children訪問子組件實例。但是這種方式只是作為訪問組件的應(yīng)急方法,更推薦用 props 和 events 實現(xiàn)父子組件通信。例如:
Vue.component('A', {
data() {
return {};
},
created() {
// 通過 this.$parent 獲取父組件的數(shù)據(jù),支持連續(xù)鏈?zhǔn)讲僮?/code>
console.log(this.$parent.$parent);
console.log(this.$children);
console.log(this);
},
template: `<div></div>`,
});
九、構(gòu)建可復(fù)用模塊的技巧
(一)函數(shù)封裝
在 Vue 組件化開發(fā)中,函數(shù)封裝是構(gòu)建可復(fù)用模塊的重要技巧之一。例如,可以將截取輸入框中第二個字符開始到最后的值并把它們轉(zhuǎn)化成大寫字母的功能封裝成函數(shù)。這樣,在多個組件中需要進行類似操作時,只需調(diào)用這個封裝好的函數(shù)即可,無需重復(fù)編寫相同的代碼邏輯。
(二)組件封裝
- 整體封裝,用戶通過改變數(shù)據(jù)源來呈現(xiàn)不同的頁面狀態(tài),代碼結(jié)構(gòu)不可定制化。整體封裝的組件在使用時相對簡單,只需提供相應(yīng)的數(shù)據(jù)源即可實現(xiàn)特定的功能。然而,由于其代碼結(jié)構(gòu)不可定制化,可能在某些復(fù)雜的應(yīng)用場景下靈活性不足。
- 自定義封裝(插槽),開放一部分槽位給父組件,使其能夠進行一定程度的定制化。具名插槽可以定義多個插槽,每個插槽都有一個名字,父組件可以通過slot屬性或v-slot指令將內(nèi)容插入到特定的插槽位置。作用域插槽是一種特殊的插槽,它能夠接收來自父組件的數(shù)據(jù),并在子組件中使用。在 Vue2 中,作用域插槽是通過slot-scope實現(xiàn)的,而在 Vue3 中,作用域插槽是通過v-slot實現(xiàn)的。
(三)插件封裝
在某些情況下,將公用部分邏輯封裝成插件,為項目添加全局功能,如常見的 loading 功能、彈框功能等。vue 中的組件可以以插件的方式封裝,例如封裝一個 toast 插件:創(chuàng)建 toast 組件,在 main.js 中導(dǎo)入并安裝,在組件中通過this.$toast訪問 toast 組件中的方法。插件的核心是 install 函數(shù),第一個參數(shù)是 Vue 對象,第二個參數(shù)是 options 配置參數(shù)。當(dāng)通過vue.use()調(diào)用插件時,即執(zhí)行 install 方法。通過 mixins 創(chuàng)建全局插件,以下封裝了一個數(shù)據(jù)驗證的插件 rules。通過在 vue 實例的$options中添加 rules,實現(xiàn)對實例中 data 的監(jiān)聽。封裝控件先與創(chuàng)建其他 vue 實例相同,構(gòu)建控件需要實現(xiàn)的效果,再在 js 文件中,實現(xiàn) install 方法,并暴露為全局對象。以下為封裝消息彈框控件 toast 的示例,假定 toast.vue 實現(xiàn)了效果。在 toast.js 文件中:引入 toast 組件,定義 toastObj 對象,實現(xiàn) install 方法,將 toast 組件對象掛載到 Vue 實例上,最后導(dǎo)出 toastObj 對象。在 main.js 文件中,通過vue.use(toast)全局使用 toast 控件;也可以在任何 vue 實例中進行局部使用。
十、Vue 組件化開發(fā)的優(yōu)勢
(一)模塊化開發(fā)
Vue 的組件化開發(fā)實現(xiàn)了模塊化開發(fā),具有多方面的優(yōu)勢。首先,它具有獨立性,每個組件可以獨立開發(fā)、測試和部署,減少了開發(fā)中的耦合度。就像管理書籍時,根據(jù)類別將書放在不同的格子里,隨著業(yè)務(wù)的發(fā)展,Vue 組件化將應(yīng)用程序按照業(yè)務(wù)拆分成不同的模塊,每個模塊對應(yīng) Vue 項目下 component 下的文件目錄,模塊中的組件組成了完整的模塊頁面。這種獨立性使得不同的開發(fā)人員可以專注于特定的組件,提高開發(fā)效率。
其次,模塊化開發(fā)有利于團隊協(xié)作。不同的開發(fā)人員可以同時開發(fā)不同的組件,提升團隊協(xié)作效率。例如在開發(fā)電商網(wǎng)站時,可以將產(chǎn)品展示、購物車、用戶評論等功能分別開發(fā)成獨立的組件,開發(fā)人員可以并行工作,互不干擾。
最后,模塊化的結(jié)構(gòu)使得調(diào)試更加簡單。問題可以被隔離在特定的組件中,更容易定位和修復(fù)。當(dāng)出現(xiàn)問題時,可以快速確定是哪個組件出現(xiàn)了問題,針對性地進行調(diào)試。
(二)代碼復(fù)用性高
Vue 組件化開發(fā)極大地提高了代碼的復(fù)用性。一方面,它減少了重復(fù)代碼。相同的功能只需開發(fā)一次,然后在不同的地方復(fù)用。比如在開發(fā)多頁面應(yīng)用時,可以創(chuàng)建一個導(dǎo)航欄組件,在所有頁面中復(fù)用該組件,避免了在每個頁面中重復(fù)編寫導(dǎo)航欄的代碼。
另一方面,通過復(fù)用組件可以確保應(yīng)用中相同功能的一致性,減少了不一致的問題。同時,只需在一個地方進行修改,就可以更新所有使用該組件的地方,維護起來非常方便。
(三)易于維護
Vue 組件化開發(fā)使得應(yīng)用程序的維護變得更加容易。首先,組件化的代碼結(jié)構(gòu)清晰,便于理解和管理。每個組件都有明確的功能和職責(zé),就像一個個獨立的模塊,使得整個應(yīng)用程序的結(jié)構(gòu)一目了然。
其次,組件可以單獨更新,不會影響其他部分的功能。例如,如果需要修改某個組件的功能,只需要對該組件進行修改,而不會對其他組件產(chǎn)生影響。
此外,不同的組件可以由不同的開發(fā)人員負(fù)責(zé),職責(zé)分明,降低了維護成本。根據(jù)業(yè)界調(diào)查,使用組件化開發(fā)的項目,其維護成本比傳統(tǒng)開發(fā)方式降低了 30%以上。
(四)提高開發(fā)效率
Vue 組件化開發(fā)能夠快速提高開發(fā)效率。其一,通過復(fù)用現(xiàn)有的組件,可以快速搭建應(yīng)用的基礎(chǔ)結(jié)構(gòu)。在新項目啟動時,可以直接復(fù)用之前項目中的通用組件,如按鈕、輸入框、表單等,從而大大縮短開發(fā)時間。
其二,組件化結(jié)構(gòu)便于隔離和定位問題,縮短調(diào)試時間。當(dāng)出現(xiàn)問題時,可以快速確定問題所在的組件,針對性地進行調(diào)試,提高了調(diào)試效率。
最后,高效協(xié)作也是提高開發(fā)效率的重要因素。團隊成員可以并行開發(fā)不同的組件,避免資源沖突,提高團隊的協(xié)作效率。