- 情境1:要選取多個 ckeckbox 對應到資料庫的欄位,欄位值是一串YN代表某個選項是否有被選去,例如: YNNYYNNYYN
- 情境2:要選取多個 ckeckbox 對應到資料庫的欄位,欄位值只有一個,可能是任何字元,例如: 1
可以打造兩個元件,分別對應至單選、多選
單選元件
程式碼 (Code)
Vue.component('x-ck-single', {
props: {
disabled: { type: Boolean, default: () => false },
// checkbox 的標記 [string] || [{text:string, value:any}]
labels: { type: Array, default: () => ['Yes', 'No'] },
value: { default: () => null },
trueValue: { default: () => 'Y' },
falseValue: { default: () => 'N' },
inline: { type: Boolean, default: () => false },
},
data() {
return {
innervalue_: this.value,
}
},
watch: {
value(v) {
this.innervalue_ = v
},
},
computed: {
innervalue: {
get() {
return this.innervalue_
},
set(v) {
this.innervalue_ = v
this.$emit('input', v)
},
},
},
render: function (h) {
const self = this
let len = self.labels.length // labels 的長度
let allStr = self.labels.every((label) => typeof label == 'string') // 是否為 string
let allOkObj = self.labels.every((l) => !!l.text && !!l.value) // 是否為合法的物件(如果不是 string)
let siblingConf = null
if (allOkObj) {
siblingConf = self.labels.map((l) => _.pick(l, ['text', 'value']))
} else if (allStr && len <= 2) {
siblingConf = self.labels.map((text, idx) => {
let value = idx === 0 ? self.trueValue : self.falseValue
return { text, value }
})
}
if (!siblingConf) {
let errStr = '無法正確設定元件,len,allStr,allOkObj'
return h('div', errStr, len, allStr, allOkObj)
}
// 設定 CheckBox
let { disabled } = self
let hideDetails = true
let dense = true
const baseProps = { hideDetails, dense, disabled }
const baseClass = self.inline ? ['d-inline-block'] : []
let siblings = siblingConf.map((c) => {
let props = {
label: c.text,
inputValue: self.innervalue === c.value,
...baseProps,
}
// 如果只有一個選項,取消勾選時就顯示 falseValue
let valueOnNull = len === 1 ? self.falseValue : null
let on = {
change: (e) => (self.innervalue = e ? c.value : valueOnNull),
}
return h("v-checkbox", { props, class: baseClass, on })
})
// 傳回整個元件
return h('div', {}, siblings)
}
})
{{value === null ? 'null' : value}}
多選元件
程式碼 (Code)