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>
页面中使用:

  <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) {

}
                }
        });

下面有两个组件
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>

.dx-selectbox {
/* border: solid 1px blue; */
position: relative;
font-family: "Arial","Microsoft YaHei","黑体","宋体",sans-serif;
display:inline-block;
}
.dx-select-input {
border: solid 1px rgb(231, 231, 231);
width:100%;
height:28px;
line-height:28px;
position:relative;
}
.dx-select {
position: absolute;
border: solid 1px rgb(231, 231, 231);
border-top:0px!important;
top: 100%;
left: 0px;
width: 100%;
display:none;
padding:5px;
z-index: 99;
background-color: #fff;
}
.dx-selectbox.dx-open .dx-select{
display:block;
}
.dx-selectbox.dx-open .dx-select-input{
border-bottom:0px!important;
}
.dx-select-text
{
display:block;
width:100%;
text-align:center;
}
.dx-select-arrow
{
position: absolute;
right: 4px;
top: 50%;
margin-top: -5px;
}
.dx-select-arrow::after
{
position: absolute;
content:'';
border:solid 5px #000;
border-bottom-color:transparent;
border-left-color:transparent;
border-right-color:transparent;
top: 5px;
right: 0px;
}
.dx-selectbox.dx-open .dx-select-arrow::after{
position: absolute;
content: '';
border: solid 5px #000;
border-top-color: transparent;
border-left-color: transparent;
border-right-color: transparent;
top: 0px;
right: 0px;
}
.dx-select-ul
{
list-style:none;
margin:0px;
padding:0px;
height:280px;
overflow:hidden;
overflow-y:auto;
}
.dx-select-ul li{
height:30px;
line-height:30px;
border-bottom:solid 1px #dfdfdf;
}
.dx-select-ul li:last-child{
border-bottom:0px!important;
}
.dx-select-search
{
padding-bottom:5px;
}
.dx-select-search input{
border:solid 1px solid 1px rgb(143, 191, 200);
width:100%;
height:30px;
line-height:30px;
outline:none;
}

<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>

.dx-selectpanel
{
font-family: verdana,Microsoft YaHei,Tahoma,sans-serif;
padding:5px;
border:2px solid #eee;
background-color:#f5f5f5;
width:500px;
position:absolute;
z-index:80;
}
.dx-sp-tab
{
}
.sp-selected
{
background-color:#56b4f8;
color:#fff;
}
.dx-selectpanel-tab
{
border-bottom:solid 3px #56b4f8;
position:relative;
height:35px;
}
.dx-selectpanel-tab a {
display:inline-block;
text-align:center;
height:35px;
line-height:35px;
padding:0px 25px;
text-decoration:none;
font-size:16px;
cursor:default;
}
.dx-selectpanel-content{
margin-top:10px;
}
.dx-selectpanel-content a
{
display:inline-block;
text-align:center;
text-decoration:none;
padding:10px 25px;
color: #666;
font-size:13px;
cursor:pointer;
}
.dx-selectpanel-close{
position:absolute;
right:10px;
cursor:default;
top:10px;
}
.dx-selectpanel-close:hover::after, .dx-selectpanel-close:hover::before{
background-color:#94cef8;
}
.dx-selectpanel-close::before, .dx-selectpanel-close::after{
position:absolute;
top:0px;
left:0px;
content:'';
display:block;
border:0px!important;
width:2px;
height:15px;
background-color:#56b4f8;
}
.dx-selectpanel-close::before
{
transform:rotate(35deg);
}
.dx-selectpanel-close::after
{
transform:rotate(-35deg);
}
/* 必需 */
.amselectpanel-transition {
transform-origin:50% 0;
-webkit-transform-origin:50% 0;
}
.amselectpanel-enter {
animation:amselectpanelover 1s ease;
-webkit-animation:amselectpanelover 1s ease;
}
@keyframes amselectpanelover{
from
{
transform:scale(0);
-webkit-transform:scale(0);
}
to
{
transform:scale(1);
-webkit-transform:scale(1);
}
}
@keyframes amselectpanelout {
from {
transform: scale(1);
-webkit-transform:scale(1);
}
to {
transform: scale(0);
-webkit-transform:scale(0);
}
}
.amselectpanel-leave {
animation:amselectpanelout 1s ease;
-webkit-animation:amselectpanelout 1s ease;
}
.dx-selectpanel-btn
{
border:0px!important;
background-color:#56b4f8;
color:#fff;
width:80px;
float:right;
text-align:center;
}
.dx-selectpanel-footer
{
margin-top: 10px;
padding: 10px 0px 0px;
border-top: solid 1px #e7eaed;
}
.dx-selectpanel-footer>span{
font-size:12px;
}
.dx-selectpanel-footer .dx-selectpanel-t2{
color:#56b4f8;
}
.dx-selectpanel-footer .dx-selectpanel-t2>span{
background-color:#ff6a00;
}

点击
<script type="text/template" id="tempList">
{{item.name}}
{{m.text}}
当前选择:{{selectalltext}} 确认

</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}}
当前选择:{{selectalltext}}确认

'
});
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>


前端架构组件化开发系列二 (基于VUE 扩展组件)相关推荐

  1. 我的react组件化开发道路(二) 分页 组件开发

    2019独角兽企业重金招聘Python工程师标准>>> 上一篇文章主要写了关于react组件化开发的一些基本配置,慢慢的深入到每个组件的详细介绍中,今天我们就来分享react的分页组 ...

  2. Vue3组件化开发(二)

    一.非父子组件的通信 在开发中,我们构建了组件树之后,除了父子组件之间的通信之外,还会有非父子组件之间的通信. 这里我们主要讲两种方式: Provide/Inject: pMitt全局事件总线: 1. ...

  3. android 组件生命周期,Android组件化开发实践(五):组件生命周期管理

    每个Android应用启动时,都会先创建一个Application.通常在Application里我们会做一些应用初始化的操作,常见的有第三方SDK初始化.在应用组件化之后,组件与壳工程是隔离开来的, ...

  4. android组件化数据生命周期,Android组件化开发实践(五):组件生命周期管理

    每个Android应用启动时,都会先创建一个Application.通常在Application里我们会做一些应用初始化的操作,常见的有第三方SDK初始化.在应用组件化之后,组件与壳工程是隔离开来的, ...

  5. [微信小程序]组件化开发,以一个自定义模块框组件当做示例(附完整示例代码和效果图)

    微信小程序开发交流qq群   173683895    承接微信小程序开发.扫码加微信. 正文: 自定义组件我把它分为简单的三个步骤, 1.创建组件 --- 2.编写组件  ---   3.调用,使用 ...

  6. modal组件 vue_开发一个简单的 Vue 弹窗组件

    https://github.com/woai3c/Front-end-articles​github.com 一个弹窗组件通常包含两个部分,分别是遮罩层和内容层. 遮罩层是背景层,一般是半透明或不透 ...

  7. 【Vue】Vite 组件化开发

    文章目录 组件化开发 一.组件化开发思想 二.Vue 组件的构成 2.1 组件组成结构 2.2 组件 template 节点 2.2.1 在 template 中使用指令 2.2.2 在 templa ...

  8. VUE 前端中如何进行组件化开发?

    1.前端里面常说的视图层是什么? 我们把HTML中的DOM就可以与其他的部分独立开来划分出一个层次,这个层次就叫做视图层. Vue 的核心库只关注视图层 图1: dom对象树结构 图2:DOM和CSS ...

  9. Vue第二天学习总结—— Vue全家桶之组件化开发(组件化开发思想、组件注册、Vue调试工具用法、组件间数据交互传递、组件插槽、基于组件的案例——购物车)

    (一) 组件化开发思想 1. 现实中的组件化思想体现 组件化即是对某些可以进行复用的功能进行封装的标准化工作 标准:要想组件能够成功组合在一起,每个组件必须要有标准 分治:将不同的功能封装到不同的组件 ...

  10. 架构:Android 组件化开发

    前言 强烈推荐先阅读这篇文章 Android 组件化最佳实践 本文是阅读实践后的思考总结,更倾向实践步骤. 组件化开发架构 组件化开发大体就是这样的架构,最关键的是base 和 base_custom ...

最新文章

  1. javascript中最最最常用的方法封装
  2. Django框架详细介绍---cookie、session、自定义分页
  3. c语言switch设计计算器,求助。。关于用switch编写简易计算器
  4. Python中变量的作用域?(变量查找顺序)
  5. 【CSS】font样式简写(转)- 不是很建议简写
  6. HttpContext.Current.Cache和HttpRuntime.Cache的区别,以及System.Runtime.Caching
  7. 联系服务器安装系统教程,服务器安装系统教程
  8. ASP.NET 实践:在非层次化控件中显示网站地图的数据
  9. 在哪里学python-深圳学python人工智能培训去哪里
  10. 1136 A Delayed Palindrome(20 分)
  11. 通力法评 | 简评中国证监会关于MOM产品的征求意见稿
  12. 将中文版pycharm改成英文版
  13. java开源cad_.Net开源项目(包含CAD支持)
  14. Linux查看当前时间
  15. 23个无本空手套白狼的赚钱方法!颠…
  16. adb命令操作安卓hosts文件
  17. top在linux的命令,Linux命令详解之–top命令 | Linux大学
  18. css中img间有空隙
  19. 打破“中规中矩”,手机QQ何以萌翻众人?
  20. UCML页面生成后突然不能访问 参数化查询 '(@ActivityID nvarchar(4000))SELECT ActivityInfoEx.ActivityInfoEx' 需要参数 '@Acti

热门文章

  1. win10子系统安装php,win10 ubuntu 子系统安装php
  2. Shadow Defender 安装后启动蓝屏、无法启动、不兼容 Win10 解决方案
  3. D92-02-ASEMI低压降快恢复二极管TO247封装
  4. 10个比较不错的 JavaScript 库
  5. 能制作引导系统型U盘的几个软件工具
  6. MIF/MID格式简介
  7. 微信小程序列表渲染(循环渲染)
  8. pgadmin3连接mysql_postgresql – pgAdmin III:拒绝访问数据库
  9. linux火狐浏览器50版本,firefox 52 下载-Firefox(火狐浏览器)52版下载 v52.0.2官方版--pc6下载站...
  10. Latex入门——使用vscode实时编辑latex文档