VUE有自己组件扩展功能,可以实例组件引用,也可以在页面直接以组件标签名来引用。
基于VUE扩展组件,正如MVVM模式一样,让数据与DOM之间事件或者渲染操作,我们只关心数据模型层就好。能节省很多代码。
前期要做的准备.VUE 一些基本知识
组件化
data 和props 之间的区别.props通常是用于在标签作为一个传递属性也可以在实例中通过propsData传递.data 可以实例中传递,但不能在标签属性中传递;
v-for:针对集合处理
$Index:当前索引,如果有多重嵌套,可以这样
<div class="dx-selectpanel-content">
<div v-for="(parentindex,item) in tabs" :style="{'display':selectedIndex==parentindex?'':'none'}">
<a v-for="m in item.data" :class="{'sp-selected':item.selectedIndex==$index}" @click="onChange(parentindex,$index)">{{m.text}}</a>
</div>
</div>
<div v-for="(parentindex,item) in tabs" :style="{'display':selectedIndex==parentindex?'':'none'}">
<a v-for="m in item.data" :class="{'sp-selected':item.selectedIndex==$index}" @click="onChange(parentindex,$index)">{{m.text}}</a>
</div>
</div>
页面中使用:
<listmenu v-for="item in listMenu" :item="item" :index="$index" :selected-index="selectedIndex" @click="showChart($index)"> </listmenu>
var vueModel = new Vue({
el:"bdoy",
data: {
listMenu: [],
},
methods: {
showChart: function (index) {
}
}
});
el:"bdoy",
data: {
listMenu: [],
},
methods: {
showChart: function (index) {
}
}
});
下面有两个组件
1.带有搜索的下拉列表选择框
2.带有动画效果,具有联动选择的,多级选择面板
下拉列表效果如下:
<script src="../../scripts/mvvm/vue/vue.js"></script>
href="../../styles/css/bootstarp/css/bootstrap.min.css" rel="stylesheet" />
<script src="../../scripts/lib/jquery/jquery-3.1.min.js"></script>
<script src="../../scripts/ui/bootstrap/bootstrap.js"></script>
<script type="text/template" id="tempSelect">
{{selectedText}}
- {{item[textFieldName]}}
</script>
<script>
var select = Vue.extend({
data:function()
{
return { list: [], textFieldName: "text",search:"", valueFieldName: 'value',isShow:false ,selectedValue:"",selectedText:""};
},
methods: {
onSelect: function (item)
{
this.selectedValue = item[this.valueFieldName];
this.selectedText = item[this.textFieldName];
this.isShow = false;
this.$emit('onSelect', this.selectedValue);
}
},
created: function ()
{
this.selectedText = this.defaultLabel;
},
watch: {
isShow:function(val)
{
if(val)
{
this.search = '';
}
},
list: function (val) {
if (val.length==0)
{
this.selectedText = this.defaultLabel;
this.selectedValue = '';
}
}
},
props:['defaultLabel'],
replace:true,
template: '
{{selectedText}}
- {{item[textFieldName]}}
'
});
var n = new select({ el: "#sltlist", propsData: { defaultLabel: "请选择" } })
n.list = [{ text: "aaaaaa", value: "1" }, { text: "bbbbbbbb", value: "2" }, { text: "aaaaaa", value: "1" }, { text: "bbbbbbbb", value: "2" }, { text: "aaaaaa", value: "1" }, { text: "bbbbbbbb", value: "2" }, { text: "aaaaaa", value: "1" }, { text: "bbbbbbbb", value: "2" }, { text: "aaaaaa", value: "1" }, { text: "bbbbbbbb", value: "2" }];
</script>
联动多级选择面板效果如下:
<script src="../../scripts/mvvm/vue/vue.js"></script>
href="../../styles/css/bootstarp/css/bootstrap.min.css" rel="stylesheet" />
<script src="../../scripts/lib/jquery/jquery-3.1.min.js"></script>
<script src="../../scripts/ui/bootstrap/bootstrap.js"></script>
<script type="text/template" id="tempList">
{{item.name}}
{{m.text}}
</script>
<script>
var selectPanel = Vue.extend({
data: function () {
return { isShow: false, tabs: [], selectedIndex: 0 ,selectalltext:"",showBtn:false,currentIndex:-1};
},
watch: {
'isShow':function(val)
{
if(val)
{
this.currentIndex = -1;
this.selectalltext = '';
this.selectedIndex = 0;
this.clearSelected();
}
}
},
methods: {
onComfirm:function()
{
this.close();
this.$emit('onComfirm', this.tabs[this.tabs.length - 1].data[this.currentIndex]);
},
close: function () {
this.isShow = false;
},
onChangeTab: function (index) {
this.selectedIndex = index;
},
bindData: function (index, data) {
this.tabs[index].data = data;
},
clearSelected: function () {
var tabCount = this.tabs.length;
for (var i = 1; i < tabCount; i++) {
this.tabs[i].selectedIndex = -1;
this.tabs[i].data = [];
}
if (tabCount > 0)
{
this.tabs[0].selectedIndex = -1;
}
this.showBtn = false;
},
onChange: function (panretindex, itemindex) {
var index = panretindex + 1, tabCount = this.tabs.length, tabItem = this.tabs[panretindex];
if (index < tabCount) {
this.selectedIndex = index;
}
if (index >= tabCount) {
this.showBtn = true;
} else {
this.showBtn = false;
}
tabItem.selectedIndex = itemindex;
for (var i = index; i < tabCount; i++) {
this.tabs[i].selectedIndex = -1;
this.tabs[i].data = [];
}
var text = "";
for (var i = 0; i < tabCount; i++) {
if(this.tabs[i].selectedIndex!=-1)
{
text +='—'+this.tabs[i].data[this.tabs[i].selectedIndex].text;
}
}
this.currentIndex = index;
this.selectalltext = text.substr(1);
this.$emit('onChange', panretindex, tabItem.data[itemindex]);
},
open: function (selector, soffset) {
soffset = soffset || { left: 0, top: 0 };
var that = this;
this.isShow = true;
this.$nextTick(function () {
var element = $(selector), offset = element.offset(), container = $(that.$el), w = container.outerWidth(), styles;
styles = {
top: offset.top + element.outerHeight() + soffset.top,
left: offset.left - ((w - element.outerWidth()) / 2) + soffset.left
};
if (styles.left < 0) {
styles.left = 10;
}
container.css(styles);
});
}
},
template: '
{{item.name}}
{{m.text}}
'
});
var _panel = new selectPanel({ el: "#selectpanel", data: { tabs: [{ name: "区域", data: [{ text: "fda", value: "fd" }, { text: "fda", value: "fd" }], selectedIndex: -1 }, { name: "案场", data: [], selectedIndex: -1 }, { name: "区域", data: [{ text: "fda", value: "fd" }], selectedIndex: -1 }] } });
_panel.$on("onChange", function (panretindex,item) {
if(panretindex==0)
{
this.bindData(1, [{ text: "aaaaaaaaaa", value: "bbbbbbbbbbbbb" }, { text: "fdaf", value: "ddddddd" }])
} if (panretindex == 1) {
this.bindData(2, [{ text: "cccccc", value: "bbbbbbbbbbbbb" }, { text: "tttttt", value: "ddddddd" }])
}
});
$("#btnOpen").on("click",function(){
_panel.open(this);
})
</script>