随着对前端框架Vue的深入了解和学习,提升了工作效率的同时也开拓了自己的思路。但有些功能仍需要使用jquery,bootstrap来实现,在工作中两种模式来回切换,很不雅观。(vue:使用mvvm实现数据双向绑定,以数据为驱动,jquery:通过操作Document元素)。那有没有方法封装jquery相关插件呢?达到vue原生功能的效果,经过了解可以通过component组件来封装。网上关于vue封装jquery插件的例子比较少,自己写了个例子。希望大家一起学习交流哈。
一、component语法
组件使用方法:父组件通过props给组件赋值,子组件通过$emit自定认事件给父组件传值。
Vue.component("v-select", {
model: {
prop: "SelectValue" //通过父组件v-model传值给子组件,prop需要和props中的属性名称一致
},
props: ["source", "SelectValue"], //父组件传递数据
data: () => {
return { x: "-1" } //组件内的属性,需要通过函数返回json对象,防止同一页面应用多个相同组件时,组件的属性值会相互干扰
},
template: " <div><input type='text'/></div>", //组件的模板
methods: {
//组件使用的方法
edit: function (v) {
this.$emit("v-change", v); //将组件内控件的值通过自定义事件传递给父组件
}
},
mounted: function () {
//编译好的html挂载到页面完成后执行的事件
//1、在此初始化jquery插件
//2、通过jquery对控件进行事件监控,处理业务逻辑
//3、给vue属性赋值
}
});
<v-select v-model="ddlValue" v-on:v-change="edit" v-bind:source="list"></v-select>
二、使用案例
1、使用原生事件给父组件传值(v-model:原理是vlue属性+input事件,子组件通过$emit触发vue原生input事件并赋值给v-model)
<html xmlns="http://www.w3.org/1999/xhtml">
<head >
<title></title>
<link href="../BootStrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="../BootStrap/js/plugins/bootstrap-multiselect/bootstrap-multiselect.css" rel="stylesheet" />
</head>
<body>
<div id="MyVue">
选中值:{{ddlValue}}
<v-select v-model="ddlValue" v-bind:source="list"></v-select>
</div>
</body>
</html>
<script src="../js/jquery-1.8.0.min.js"></script>
<script src="../BootStrap/js/bootstrap.min.js"></script>
<script src="../BootStrap/js/plugins/bootstrap-multiselect/bootstrap-multiselect.min.js"></script>
<script src="js/vue.min.js"></script>
<script type="text/javascript">
Vue.component("v-select", {
model: {
prop: "SelectValue" //通过父组件v-model传值给子组件
},
props: ["source", "SelectValue"],
data: () => { //组件内的属性需要通过函数返回json对象,防止同一页面应用多个组件时,组件的属性值会相互干扰
return { Id: "Date_" + Math.ceil(Math.random() * 100000) } //id保证多个相同组件在一个页面时,避免对象冲突
},
template: "<div > <select v-bind:class='Id' class=\" form-control \" multiple><option v-for='item in source' v-bind:value='item.value'>{{item.text}}</option></select></div>",
methods: {
edit: function (v) {
this.$emit("input", v); //触发Vue原生事件(使用v-model来进行数据双向绑定时,接受一个 value 属性,在有新的 value 时触发 input 事件)
}
},
mounted: function () {
var Self = this;
//初始化select下拉列表特效
$("." + this.Id).multiselect({
selectAllText: '全部',
includeSelectAllOption: true
});
//兼容在inArray中查询子元素时,类型不同会查找不到
var CurrSource = Self.SelectValue.join(',').split(',');
//将父组件的值赋值给下拉列表
$("." + this.Id + ' option').each(function (i, content) {
if ($.inArray($.trim(content.value), CurrSource) >= 0) {
this.selected = true;
}
});
//设置选中值后,需要刷新select控件
$("." + this.Id).multiselect('refresh');
//下拉列表值更改后,将值传给父组件的事件
$("." + this.Id).change(function () {
Self.edit($(this).val());
});
console.log(this.SelectValue);
}
});
var MyVue = new Vue({
el: "#MyVue",
data: {
list: [{ "text": "请选择", "value": -1 }, { "text": "请选择1", "value": 1 }, { "text": "请选择2", "value": 2 }],
ddlValue: [1, 2]
},
methods: {
}
});
</script>
2、使用自定义事件给父组件传值
<html xmlns="http://www.w3.org/1999/xhtml">
<head >
<title></title>
<link href="../BootStrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="../BootStrap/js/plugins/bootstrap-multiselect/bootstrap-multiselect.css" rel="stylesheet" />
</head>
<body>
<div id="MyVue">
选中值:{{ddlValue}}
<v-select v-model="ddlValue" v-on:v-change="edit" v-bind:source="list"></v-select>
</div>
</body>
</html>
<script src="../js/jquery-1.8.0.min.js"></script>
<script src="../BootStrap/js/bootstrap.min.js"></script>
<script src="../BootStrap/js/plugins/bootstrap-multiselect/bootstrap-multiselect.min.js"></script>
<script src="js/vue.min.js"></script>
<script type="text/javascript">
Vue.component("v-select", {
model: {
prop: "SelectValue" //通过父组件v-model传值给子组件
},
props: ["source", "SelectValue"],
data: () => { //组件内的属性需要通过函数返回json对象,防止同一页面应用多个组件时,组件的属性值会相互干扰
return { Id: "Date_" + Math.ceil(Math.random() * 100000) } //id保证多个相同组件在一个页面时,避免对象冲突
},
template: "<div > <select v-bind:class='Id' class=\" form-control ng-pristine ng-untouched ng-valid\" multiple><option v-for='item in source' v-bind:value='item.value'>{{item.text}}</option></select></div>",
methods: {
edit: function (v) {
this.$emit("v-change", v); //将组件内控件的值通过自定义事件传递给父组件
}
},
mounted: function () {
var Self = this;
//初始化select下拉列表特效
$("." + this.Id).multiselect({
selectAllText: '全部',
includeSelectAllOption: true
});
//兼容在inArray中查询子元素时,类型不同会查找不到
var CurrSource = Self.SelectValue.join(',').split(',');
//将父组件的值赋值给下拉列表
$("." + this.Id + ' option').each(function (i, content) {
if ($.inArray($.trim(content.value), CurrSource) >= 0) {
this.selected = true;
}
});
//设置选中值后,需要刷新select控件
$("." + this.Id).multiselect('refresh');
//下拉列表值更改后,将值传给父组件的事件
$("." + this.Id).change(function () {
Self.edit($(this).val());
});
console.log(this.SelectValue);
}
});
var MyVue = new Vue({
el: "#MyVue",
data: {
list: [{ "text": "请选择", "value": -1 }, { "text": "请选择1", "value": 1 }, { "text": "请选择2", "value": 2 }],
ddlValue: [1, 2]
},
methods: {
edit: function (v) {
this.ddlValue = v;
}
}
});
</script>
三、效果图