Element作为一个Vue的组件库,除了有一些bug之外还是挺好用的。
比如实现一个下拉框
<div id="app">
<el-select v-model="selected" placeholder="选择课程">
<el-option :value="null" label="全部"></el-option>
<el-option v-for="item in items" :key="item" :label="item" :value="item"></el-option>
</el-select>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
selected: null,
items: ["语文", "数学", "地理", "历史", "英语", "物理"]
}
});
</script>
但如果一个系统中很多页面需要用到这个东西,每次都要重写,也是挺麻烦的,所以可以考虑封装一下
建一个my-element.js
Vue.component('my-select-ke', {
data: function () {
return {
selected: null,
items: ["语文", "数学", "地理", "历史", "英语", "物理"]
};
},
template: `
<el-select v-model="selected" placeholder="选择课程">
<el-option :value="null" label="全部"></el-option>
<el-option v-for="item in items" :key="item" :label="item" :value="item"></el-option>
</el-select>`,
});
现在只要引用js 就可以直接生效了
<script src="my-element.js"></script>
<div id="app">
<my-select-ke></my-select-ke>
</div>
<script>
var vm = new Vue({
el: "#app
});
</script>
效果和之前是一样的
不过这个时候值是无法回传的
所以需要再实现一个 v-model 回传选中的值
Vue.component('my-select-ke', {
data: function () {
return {
selected: null,
items: ["语文", "数学", "地理", "历史", "英语", "物理"]
};
},
model: {
event: 'change'
},
watch: {
selected: function (val) {
this.$emit("change", val);
}
},
template: `
<el-select v-model="selected" placeholder="选择课程">
<el-option :value="null" label="全部"></el-option>
<el-option v-for="item in items" :key="item" :label="item" :value="item"></el-option>
</el-select>`,
});
使用 model
设置绑定事件,用watch
观察selected
属性,并触发change
事件发送值
<div id="app">
<my-select-ke v-model="ke"></my-select-ke>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
ke: null
}
});
</script>
现在就可以设置v-model
属性了
Element
的select本身是支持多选的,如果我们自己的组件也需要多选,需要把multiple
属性传递到el-select
中去
Vue.component('my-select-ke', {
data: function () {
return {
selected: "",
items: ["语文", "数学", "地理", "历史", "英语", "物理"]
};
},
props:["multiple"], //声明props
model: {
event: 'change'
},
watch: {
selected: function (val) {
this.$emit("change", val);
}
},
template: `
<el-select v-model="selected" placeholder="选择课程" :multiple="multiple"> <!-- 传递属性 -->
<el-option v-for="item in items" :key="item" :label="item" :value="item"></el-option>
</el-select>`,
});
最后,如果列表的数据并不是写死的,而且通过接口获取的,可以继续改造
Vue.component('my-select-ke', {
data: function () {
return {
selected: "",
items: ["语文", "数学", "地理", "历史", "英语", "物理"]
};
},
props: ["query", "placeholder", "clearable", "size", "multiple"],
model: { event: 'change' },
watch: {
selected: function (val) {
this.$emit("change", val);
}
},
methods: {
ajax: function (key) {
this.loading = true;
var query = this.query || {};
fetchival('/api/ke/list', { credentials: 'include' })
.get({ keyWord: key, size: query.size })
.then(function (data) {
this.loading = false;
this.items = data.Items;
}.bind(this));
},
label: function (item) {
return item.name + "(" + item.teacher + ")";
}
},
mounted: function () {
this.ajax();
},
template: `
<el-select v-model="selected" :multiple="multiple" :clearable="clearable" :size="size" :placeholder="placeholder" filterable remote :loading="loading" :remote-method="ajax" value-key="id">
<el-option v-for="item in items" :key="item.id" :label="label(item)" :value="item"></el-option>
</el-select>`
});
<div id="app">
<my-select-ke v-model="ke" :query="{size:5}"></my-select-ke>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
ke: null,
}
});
</script>