8. Vue可複用解決方案
Vue可複用方案是指在Vue.js專案中,透過建立可複用的元件、指令、外掛等,來提高程式碼的複用性和可維護性常見的Vue可複用方案有:元件(Components)、指令(Directives)、外掛(Plugins)、混入(Mixins)、高階元件(Higher-Order Components, HOC)等。透過這些可複用方案,可以有效地減少程式碼重複,提高開發效率和程式碼質量。
8.1 自定義指令
自定義指令是Vue.js中一種強大的功能,允許你在DOM元素上繫結特定的行為。透過自定義指令,你可以封裝複雜的DOM操作邏輯,並在多個元件中複用。
以下是如何建立自定義指令的詳細步驟:
自定義指令可以包含幾個鉤子函式,例如 bind
、inserted
、update
、componentUpdated
和 unbind
。每個鉤子函式都有其特定的用途。
鉤子函式
- bind:只呼叫一次,指令第一次繫結到元素時呼叫。在這裡可以進行一次性的初始化設定。
- inserted:被繫結元素插入父節點時呼叫(僅保證父節點存在,但不一定已被插入文件中)。
- update:所在元件的VNode更新時呼叫,但是可能發生在其子VNode更新之前。
- componentUpdated:指令所在元件的VNode及其子VNode全部更新後呼叫。
- unbind:只呼叫一次,指令與元素解綁時呼叫。
8.1.1 全域性指令
<body>
<div id="app">
<div v-date></div>
<p v-date></p>
</div>
<script src="../js/vue3.js"></script>
<script>
let app = Vue.createApp({})
// 自定義指令,directive('指令名', {指令的內容})
app.directive('date', {
// 指令的定義,mounted會返回一個dom物件,el是指令所在的元素
mounted(el) {
el.innerHTML = new Date()
}
})
app.mount('#app')
</script>
</body>
8.1.2 區域性指令
<body>
<div id="app">
<div v-date></div>
<p v-date></p>
</div>
<script src="../js/vue3.js"></script>
<script>
let app = Vue.createApp({
directives: {
date: {
mounted(el) {
el.innerHTML = new Date()
}
}
}
}).mount('#app')
</script>
</body>
也可以這麼寫:
<body>
<div id="app">
<div v-date></div>
<p v-date></p>
</div>
<script src="../js/vue3.js"></script>
<script>
const mydirective = {
date: {
mounted(el) {
el.innerHTML = new Date()
}
}
}
let app = Vue.createApp({
directives: mydirective
}).mount('#app')
</script>
</body>
8.1.3 指令引數
<body>
<div id="app">
<img src="../img/jy.jpg" v-imgcir="300">
</div>
<script src="../js/vue3.js"></script>
<script>
const mydirective = {
imgcir: {
mounted(el,binding) {
el.style.width = binding.value + 'px'
el.style.height = binding.value + 'px'
el.style.borderRadius = (binding.value/2) + 'px'
}
}
}
let app = Vue.createApp({
directives:mydirective
}).mount('#app')
</script>
</body>
8.2 Mixin混入
Mixin混入(Mixin Mixins)是一種程式設計模式,主要用於在物件導向程式設計中,透過將一個或多個類的功能“混入”到另一個類中,從而實現程式碼的複用和功能的擴充套件。Mixin類通常不單獨例項化,而是作為其他類的組成部分,為其提供特定的行為或屬性。
Mixin混入的主要特點包括:
- 程式碼複用:Mixin類可以包含一些通用的方法或屬性,這些方法或屬性可以被多個類共享,從而減少程式碼重複。
- 靈活性:透過Mixin混入,可以在不修改原有類結構的情況下,為類新增新的功能。
- 多重繼承:在支援多重繼承的語言中,Mixin類可以被多個類繼承,從而實現複雜的功能組合。
8.2.1 基本用法
<body>
<div id="app">
{{ num }}
{{ name }}
{{ date }}
</div>
<script src="../js/vue3.js"></script>
<script>
const common = {
data() {
return {
name: '張三'
}
}
}
const date = {
data() {
return {
date: new Date()
}
}
}
let app = Vue.createApp({
data() {
return {
num: 100
}
},
mixins: [common, date]
}).mount('#app')
</script>
</body>
8.2.2 混入優先順序
Vue中Mixin混入的優先順序規則如下:
- 資料物件(data):元件自身的資料優先順序更高。
- 生命週期鉤子函式:Mixin中的鉤子函式會在元件自身的鉤子函式之前呼叫。
- 方法(methods)、計算屬性(computed)和其他選項:元件自身的定義會覆蓋Mixin中的定義。
<body>
<div id="app">
{{ num }}
{{ name }}<br>
<button @click="add">點選</button>
</div>
<script src="../js/vue3.js"></script>
<script>
const common = {
data() {
return {
name: '張三',
num: 200
}
},
methods: {
add() {
console.log('這是Mixin混入中的方法');
}
},
created() {
console.log('vue例項建立後生命週期函式--Mixin');
}
}
let app = Vue.createApp({
data() {
return {
num: 100
}
},
mixins: [common],
methods: {
add() {
console.log('這是元件中的一個方法');
}
},
created() {
console.log('vue例項建立後生命週期函式--元件');
}
}).mount('#app')
</script>
</body>
8.2.3 全域性Mixin
<body>
<div id="app">
{{ num }}
<button @click="add">點選</button>
</div>
<script src="../js/vue3.js"></script>
<script>
let app = Vue.createApp({})
app.mixin({
data() {
return {
num: 100
}
},
methods: {
add() {
console.log('這是Mixin混入中的方法');
}
},
created() {
console.log('vue例項建立後生命週期函式--Mixin');
}
})
app.mount('#app')
</script>
</body>
8.3 外掛
外掛(Plugin)是一種擴充套件Vue功能的方式。外掛可以全域性地為Vue應用新增一些功能,如新增全域性方法或屬性、新增全域性資源(指令、過濾器、過渡等)、透過全域性混入(Mixin)新增一些元件選項,或者向Vue例項新增例項方法。
8.3.1 基本用法
<body>
<div id="app">
</div>
<script src="../js/vue3.js"></script>
<script>
// 外掛宣告有兩種方式
// 1、物件形式
/*
const MyPlugin = {
// app:將使用外掛的Vue例項透過app引數傳入;options:引數
install(app, options) {
console.log('hello world');
console.log(app);
console.log(options);
}
}
*/
// 2、函式形式
const MyPlugin = (app, options) => {
console.log('hello world');
console.log(app);
console.log(options);
}
let app = Vue.createApp({})
app.use(MyPlugin, { name:'張三' })
app.mount('#app')
</script>
</body>
8.3.2 給Vue擴充套件功能
<body>
<div id="app">
<img src="../img/jy.jpg" v-imgcir="300">
{{ date }}
</div>
<script src="../js/vue3.js"></script>
<script>
const MyPlugin = {
install(app, options) {
app.directive('imgcir', {
mounted(el, binding) {
el.style.width = binding.value + 'px'
el.style.height = binding.value + 'px'
el.style.borderRadius = (binding.value / 2) + 'px'
}
})
app.mixin({
data() {
return {
date: new Date()
}
}
})
}
}
let app = Vue.createApp({})
app.use(MyPlugin)
app.mount('#app')
</script>
</body>