一、前言
【又在重複造輪子!!!】vue有很多現成的UI框架,博主的手機端用的是mintUI,但是mintUI樣式不能整改爲想要的樣子,因此純手工封裝了一個checkBox組件(純css實現效果,需要不一樣的可自制樣式)
先來一個效果圖:
二、正文
1、說明
- 使用checkBox綁定數據,選中的數據使用數組存儲(vue分組的寫法)
- 爲了保證是數組類型,需要指定組件參數使用的變量,使用$emit回傳數據到父組件,checkbox實現v-model雙向綁定
- 通過參數確定,是否顯示多選框,用樣式控制
2、實例調用
<!-- html -->
<multi-check-list label="多選測試1" :options="multiCheckOptions" v-model="checkedVal1"></multi-check-list>
<multi-check-list label="多選測試2" :options="multiCheckOptions" v-model="checkedVal2" :showbox="false"></multi-check-list>
<multi-check-list label="多選測試3(全部禁用)" :options="multiCheckOptions" :checked="checkedVal3" :disabled="true"></multi-check-list>
// js數據
data: function () {
return {
multiCheckOptions: [
{'value': '1', 'name': '選項1'},
{'value': '2','name': '選項2(禁用)','disabled': true},
{'value': '3', 'name': '選項3'}],
checkedVal1: [1],
checkedVal2: [1, 2],
checkedVal3: [1, 2],
}
}
3、代碼解析
3.1、參數說明(參數命名最好不要使用大寫,有可能會解析不到):
- label:組件的標籤名稱
- options:需要生成的checkBox選項 數據格式:[{value:'1',name:'選項1',disabled:false}]
- checked:選中的數據 ['1'],通常與disabled:true合併使用,若使用v-model,則無需綁定該參數‘’
- disabled:是否全部禁用, 默認false可用
- showbox:是否顯示勾選框, 默認顯示 ( false:不顯示,則樣式會改變)
3.2、核心代碼:
- 修改v-model對應的變量和事件,保證數據格式,
model: { // v-model 對應的變量和事件,默認是value和change
prop: 'checked',
event: 'change'
},
- 保證單向數據流的統一性,且回傳數據到父組件所使用的v-model
tips:可能會有小夥伴覺得,我不用checkedVal:this.checked都可以,只需要直接在checkBox
checkedVal: this.checked, // data中定義一個新的變量,用來存儲選中的數據,保證單向數據流的統一性
this.$emit('change', newValue) // 監聽數據變化,回傳數據到父組件
有這三句話,組件就已經成功了一半,接下來只需要把他們放到合適的位置,就可以初見成效。
3.3 、準備js代碼
export default {
name: "multi-check-list",
model: { // v-model 對應的變量和事件,默認是value和change
prop: 'checked',
event: 'change'
},
props: { // 組件參數
label: String,
options: Array,
checked: Array,
disabled: false,
showbox: {
type: Boolean,
default: true
},
},
watch: { // 監聽數據變化,回傳數據到父組件
checkedVal(newValue, oldValue) {
if (newValue != oldValue) {
this.$emit('change', newValue)
}
}
},
data() {
return {
checkedVal: this.checked, // 用來存儲選中的數據
curTime: new Date().getTime(), // 獲取當前時間,生成唯一id,保證一個頁面可使用多個組件
}
},
}
可能會有小夥伴不明白,爲什麼要checkedVal:this.checked?!?
答:
- 確實不需要這句話,直接把checkedVal使用到的地方替換成checked也可以達到目的
- 但是我們寫代碼,是不是除了寫代碼之外,還可以做點別的事情,比如寫出優雅的代碼((๑⁼̴̀д⁼̴́๑)ドヤッ‼ What are you 弄啥嘞!)
- 首先,vue是單向數據流,自上而下,普通的數據類型,是不會與父組件數據保持一致,因爲object(我們用的checked數組,也屬於object)用的是同一塊內存,也就是上下的checked會同步變化
- 其次,我們封裝組件爲了保證調用者的數據不被破壞,我們應該遵循vue的規則,另外定義一個變量用來存儲會變化的數據
3.4 、編寫html代碼
遍歷傳入的options,動態生成CheckBox列表
<div class="multi-checklist">
<label class="multi-checklist-title">{{label}}</label>
<div :class="showbox? 'multi-checklist-contentc':'multi-checklist-content'">
<div class="option-item" v-for="(item,index) in options">
<input type="checkbox" :id="'mchecklist'+index+curTime" :value="item.value" v-model="checkedVal"
class="checkbox" :disabled="item.disabled || disabled">
<label :for="'mchecklist'+index+curTime" class="check-label">{{item.name}}</label>
</div>
</div>
</div>
到這裏,組件封裝就基本成型了,沒有貼出css,如果需要完整代碼,可直接在本人github上clone代碼,或者在本人資源裏面下載
感謝觀看,歡迎留言交流!