Vue 元件練習 - Checkbox 清單
5 |
不管用哪種前端框架,一定少不了遇到 Checkbox 清單需求,之前寫過 KO 版,寫過 NG 版,如今改學 Vue,不寫個 Vue 版成何體統?
廢話少說,放碼過來!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Checkbox List Vue Component</title>
<style>
html,
body {
font-size: 9pt;
}
[v-cloak] {
display: none;
}
fieldset {
width: 320px;
padding: 12px;
}
fieldset div { background-color: #eee; }
</style>
</head>
<body>
<div id="app" v-cloak>
<fieldset>
<legend>Checkbox List (string array options & multi-select)</legend>
<v-chkbox-list v-model="SelValues1" v-bind:items="StrArrayOptions"></v-chkbox-list>
<div class="value-view">{{SelValues1}}</div>
</fieldset>
<fieldset>
<legend>Checkbox List (value/text options & exclusive choice)</legend>
<v-chkbox-list v-model="SelValue2" v-bind:items="ValueTextArrayOptions" exclusive="true"></v-chkbox-list>
<div class="value-view">{{SelValue2}}</div>
</fieldset>
</div>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
<script>
//實際應用時,元件會另存成 vue-components-filename.js 方便重複利用
Vue.component('v-chkbox-list', {
props: {
value: Array,
items: Array,
exclusive: Boolean
},
template: '<span><label v-for="item in items">' +
'<input type="checkbox" v-bind:value="item.value || item" />' +
'<span>{{item.text || item}}</span>  </label></span>',
mounted: function () {
var self = this;
var el = $(self.$el);
el.find("input").each(function () {
if (self.exclusive) {
this.checked = this.value == self.value;
}
else {
this.checked = $.inArray(this.value, self.value) > -1;
}
});
el.on("change", "input[type=checkbox]", function () {
if (self.exclusive) {
$(this).closest("span").find("input").not(this).prop("checked", false);
self.$emit('input', this.value);
}
else {
var selValues = $.map(el.find(":checked"), function (cbx) {
return cbx.value;
});
self.$emit('input', selValues);
}
});
}
});
</script>
<script>
var vm = new Vue({
el: "#app",
data: {
StrArrayOptions: ["Value1", "Value2", "Value3"],
SelValues1: ["Value2"],
ValueTextArrayOptions: [
{ value: "Value1", text: "Text1" },
{ value: "Value2", text: "Text2" },
{ value: "Value3", text: "Text3" }
],
SelValue2: "Value2"
}
});
</script>
</body>
</html>
我選擇寫成 Vue Component,重點跟上一篇 Kendo UI 日期選擇器封裝元件講的大同小異,這裡不多贅述。選項來源支援兩種型別,一種直接給字串陣列,顯示文字等於選擇值;若二者不同,則可提供具有 value 及 text 屬性的物件陣列。選取方式則分為單選或多選,選取結果支援 v-model 繫結,單選時型別為字串、多選時則為字串陣列,用講的有點抽象,看示範比較快: 線上展示
[2020/9/21 補充:讀者 milkmidi 留言分享了更能發揮 Vue 特色的簡潔寫法,我的版本相較之下像是莽夫揮著 jQuery 斧頭硬幹(掩面),稍晚再補上我的學習心得]
Vue 3.0 正式版昨天發佈了,這篇用的還是 2.x 寫法(我計劃明年再升級現有專案,原因請參考昨天的文章),V3 寫法改天再來研究。
Writing a checkbox list as Vue component.
Comments
# by milkmidi
黑暗大大你好,我把你的exmaple小改一下,主要就是拿掉 jQuery, 讓 Code 更簡單一些 https://jsbin.com/vowuwek/15/edit?html,console,output
# by Jeffrey
to milkmidi, 謝謝分享,用 Vue v-model 取代 click 事件很酷,學習了。另外實測 IE11 不支援 template: `...`,但改回 '...' 就 OK 了。
# by milkmidi
忘了 ie11不支援template vue真的很好用
# by plastic
建議一下,目前Vue 2版應該到2.6,上面還是用2.0,然後是如果沒有用到Jquery UI或其他必須要Jquery的,裡面的內容應該是可以全換成 Vue 的
# by Jeffrey
to plastic,jquery 與 vue.js 我是用 JSBin 內建功能加上的,感謝提醒。milkmidi 有給了一個純 Vue 版範例,本案例的確可以完全不用 jQuery,之後再寫心得文。