面向对象权限配置组件 (面向对象编程 组件化开发)

1.组件结构

2.页面调用

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>面向对象权限配置组件</title>
	<link rel="stylesheet" type="text/css" href="assets/UserRoleSelector/css/UserRoleSelector.css">
</head>
<body>
	<button id="showSelector">配置用户角色</button>

	<script src="assets/UserRoleSelector/js/UserRoleSelector.js"></script>

	<script>
		window.onload = function(){
			// 通过构造器传入参数,构建UserRoleSelector的实例
			var selector = new UserRoleSelector({ // 传参
				show : false, // 默认不显示
				data : [{"value":"1","text":"系统管理员"},
						{"value":"2","text":"部门经理"},
						{"value":"3","text":"部门主管"},
						{"value":"4","text":"销售经理"},
						{"value":"5","text":"财务会计"},
						{"value":"6","text":"财务出纳"}], // 数据列表 传入json对象
				onSave : function(){ // 保存 传参  参数为组件本身
					alert(this.getValues()); // do code
					// console.log(this); // 问题:改变不了this的引用
					// this.getValues(); // 获得当前被选中的数据
					this.hide(); // 此时this指向UserRoleSelector
				}
			});
			document.getElementById("showSelector").onclick = function(){
				if(selector.status){
					selector.hide();
				}else{
					selector.show(); // 让组件出现
				}
			}
		}
	</script>
</body>
</html>

3.组件封装:

UserRoleSelector.css

html,body{
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
	font-family: Airal,‘microsoft yahei‘;
	background-color: #b1b1b1;
	-moz-user-select: none;/*火狐*/
	-webkit-user-select: none;/*webkit浏览器*/
	-ms-user-select: none;/*IE10*/
	-khtml-user-select: none;/*早期浏览器*/
	user-select: none;
	overflow: hidden;
}
ul,li{
	list-style: none;
	margin: 0;
	padding: 0;
}
.mask{
	position: fixed;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	background-color: rgba(0,0,0,.5);
}
.user-role-selector{
	position: absolute;
	top: 50%;
	left: 50%;
	margin-left: -290px;
	margin-top: -250px;
	background-color: #fff;
	border-radius: 2px;/*边角半径*/
	padding: 50px 20px;
	width: 540px;
	height: 400px;
}
.user-role-selector .data-list{
	width: 40%;
	height: 90%;
	background-color: #fafafa;
	border: 1px solid #e5e5e5;
	float: left;
}
.user-role-selector .data-list li{
	width: 100%;
	height: 36px;
	line-height: 36px;
	text-indent: 10px;
	color: #666;
	font-size: 14px;
	cursor: pointer;
}
.user-role-selector .data-list li:hover{
	background-color: #039ae3;
	color: #fff;
}
.user-role-selector .data-list li.selected{
	background-color: #666;
	color: #fff;
}
.user-role-selector .data-oper{
	width: 18%;
	height: 100%;
	float: left;
	padding-top: 25%;
}
.user-role-selector .data-oper .button{
	margin: 20px auto;
	text-align: center;
}
.user-role-selector .button{
	width: 80px;
	height: 36px;
	display: block;
	border: 1px solid #d9d9d9;
	line-height: 36px;
	text-decoration: none;
	color: #333;
	background: #f3f3f3;
	font-size: 14px;
}
.user-role-selector .button:hover{
	background-color: #039ae3;
	color: #fff;
}
.user-role-selector .data-bar{
	position: absolute;
	bottom: 20px;
	left: 0;
	width: 100%;
	height: 10%;
}
.user-role-selector .data-bar .button{
	float: right;
	text-align: center;
	margin-right: 25px;
}
.user-role-selector .data-bar .button.close{
	background-color: #e84c4c;
	color: #fff;
}

UserRoleSelector.js

// 创建闭包 避免变量污染(全局污染)
var UserRoleSelector = (function(){
	/**
	 * 1.构建 构造器函数
	 * 一般首字母大写
	 */
	// 2.定义UserRoleSelector类型构造器
	function UserRoleSelector(options) { // 3.用户传入的参数
		// this.options = options||{}; // 4.为了避免用户不传入options对象造成的NullPointer(空指针异常)
		this.init(options||{}); // 5.初始化操作
		// this.render(); // 9.生成(渲染)dom结构
		this.bind(); // 绑定插件中dom需要的所有事件
	}
	// 11.将要被渲染的dom结构
	var html =
		‘<div class="user-role-selector">‘ +
			‘<ul class="left-list data-list">‘ +
				// ‘<li>系统管理员</li>‘ +
				// ‘<li>部门经理</li>‘ +
				// ‘<li>部门组管</li>‘ +
				// ‘<li>销售经理</li>‘ +
				// ‘<li>财务会计</li>‘ +
				// ‘<li>财务出纳</li>‘ +
			‘</ul>‘ +
			‘<div class="data-oper">‘ +
				‘<a href="#" class="add button">添加</a>‘ +
				‘<a href="#" class="del button">删除</a>‘ +
			‘</div>‘ +
			‘<ul class="right-list data-list"></ul>‘ +
			‘<div class="data-bar"><a href="#" class="close button">关闭</a>‘ +
			‘<a href="#" class="save button">保存</a></div>‘ +
		‘</div>‘;

	// 6.扩展UserRoleSelector类型实例的功能
	UserRoleSelector.prototype = {
		init:function(options) { // 7.初始化操作
			this.options = options; // 8.初始化参数
			this.dom = document.createElement("div");// 12.创建元素
			this.dom.className = "mask";
			this.dom.style.display = this.options.show?"block":"none"; // 由用户决定元素是否显示
			this.dom.innerHTML = html;
			this.status = this.options.show?1:0; // 0代表隐藏  1代表显示
			document.body.appendChild(this.dom); // 13.将dom插入到新创建的div元素中
			// 27.找到左右列表 便于接受index.html传入数据列表参数
			this.left = this.dom.querySelector(".left-list.data-list");
			this.right = this.dom.querySelector(".right-list.data-list");
			// 32.add、del按钮
			this.add = this.dom.querySelector(".button.add"); // 寻找add按钮
			this.del = this.dom.querySelector(".button.del"); // 寻找del按钮
			// 18.save、close按钮
			this.save = this.dom.querySelector(".button.save"); // 寻找save按钮
			// console.log(this.save);
			this.close = this.dom.querySelector(".button.close"); // 寻找close按钮
			// 28.循环输出列表数据
			var data = this.options.data||[];
			for(var i=0;i<data.length;i++){
				this.left.innerHTML+="<li data-value=‘"+data[i].value+"‘>"+data[i].text+"</li>";
			}
			this.items = this.left.querySelectorAll("li");// 29.找到所有的li
			// console.log(this.items.length);
		},
		// render:function() { // 10.渲染dom
		// 	this.dom.innerHTML = html;
		// },
		bind:function() { // 16.绑定插件中dom需要的所有事件
			var _this = this; // 21.此处this为UserRoleSelector组件本身,将组件的引用保存在局部变量_this中
			if(this.options.onSave){ // 23.保存方法 判断用户是否传参
				// this.save.onclick = function() { // 24.方法一:外层包一个function 便于改变this的引用 及 接收参数
				// 	_this.options.onSave.call(_this); // 25.call方法 起到函数调用过程中改变this的引用,将作用域改为this(此处指向UserRoleSelector组件本身)
				// }
				this.save.onclick = _this.options.onSave.bind(_this); // 26.方法二:调用bind方法,直接参入_this,调用onclick方法,返回的是个函数 起到函数调用过程中,_this对象指向this
			}
			// 17.找到当前dom对象中的按钮 写在init方法中
			this.close.onclick = function() { // 19.定义close按钮的绑定事件
				// this.hide(); // 隐藏组件
				_this.hide(); // 22.隐藏组件 使用局部变量_this替换this,使得指向为UserRoleSelector组件
				// 20.注意:因为函数的作用域问题,当函数被调用过程中,this指向函数本身,此处为close对象,而我们想指向UserRoleSelector组件,所有需要配置this
			};
			// this.add.onclick = function(){
			// 	// 33.拿到left下面所有被选中的item(.selected)
			// 	var selecteds = _this.left.querySelectorAll("li.selected");
			// 	// 34.往right里面append
			// 	for(var i=0;i<selecteds.length;i++){
			// 		_this.right.appendChild(selecteds[i]);
			// 	}
			// };
			// this.del.onclick = function(){
			// 	// 35.拿到right下面所有被选中的item(.selected)
			// 	var selecteds = _this.right.querySelectorAll("li.selected");
			// 	// 36.往left里面append
			// 	for(var i=0;i<selecteds.length;i++){
			// 		_this.left.appendChild(selecteds[i]);
			// 	}
			// };
			/**
			 * bind 和 call 的区别
			 * bind返回的是一个函数,将来时
			 * call返回的是一个对象,现在进行时
			 */
			this.add.onclick = this._operClick.bind(this,this.add); // 39.简化代码
			this.del.onclick = this._operClick.bind(this,this.del); // 39.简化代码
			// 30.给所有的li,绑定事件
			for(var i=0;i<this.items.length;i++){
				// this.items[i].onclick = function() {
				// 	// 31.给被点击的元素添加样式,再次点击清除被选中样式
				// 	if(this.className.indexOf("selected")!=-1){ // 清除被选中样式
				// 		this.className = "";
				// 	}else{ // 添加被选中样式
				// 		this.className = "selected";
				// 	}
				// }

				this.items[i].onclick = this._itemClick; // 38.调用私有方法
			}
		},
		show:function() { // 14.定义show方法
			this.dom.style.display = "block";
			this.status = 1;
		},
		hide:function() { // 15.定义hide方法
			this.dom.style.display = "none";
			this.status = 0;
		},
		_itemClick:function() { // 37.定义私有方法,提高代码效率,节约内存空间
			if(this.className.indexOf("selected")!=-1){ // 清除被选中样式
				this.className = "";
			}else{ // 添加被选中样式
				this.className = "selected";
			}
		},
		_operClick:function(target){ // 40.定义私有方法
			// console.log(target);
			// 41.封装方法
			var one,two;
			if(target.className.indexOf("add")!=-1){
				one = this.left;
				two = this.right;
			}else{
				one = this.right;
				two = this.left;
			}
			// 拿到one下面所有被选中的item(.selected)
			var selecteds = one.querySelectorAll("li.selected");
			// 往two里面append
			for(var i=0;i<selecteds.length;i++){
				two.appendChild(selecteds[i]);
			}
		},
		getValues:function(){ // 43.获得当前被选中的数据
			var values = "";
			var selecteds = this.right.querySelectorAll("li"); // 44.获得右列表所有数据
			// 45.循环输出
			for(var i=0;i<selecteds.length;i++){
				values+=selecteds[i].getAttribute("data-value");
				if(i!=selecteds.length-1){
					values+=",";
				}
			}
			return values;
		}
	}; // 每一个构造器函数都有一个prototype属性

	// 构造器函数 与 普通函数 的区别
	// new UserRoleSelector(); // 调用构造器函数  创建一个被持有句柄的闭包空间,运行函数里面的代码(生命周期比普通函数长),this指向就是当前这块这块空间的引用

	// show(); // 调用普通函数  创建一个临时闭包空间,运行函数里面的代码,this指向是window对象
	return UserRoleSelector; //
})();

.

时间: 2024-10-25 19:58:26

面向对象权限配置组件 (面向对象编程 组件化开发)的相关文章

面向对象、面向服务、面向组件三种编程模式有什么区别?分别适用于哪些领域的开发?

http://blog.sina.com.cn/s/blog_6d2890600101cwih.html 三个数据后面都缺了一个词,分别是:“编程”.“架构”和“开发”(或“软件工程”). 同时,不是“面向”组件而是“基于”组件. 面向对象编程(Object-Oreinted Programming) 是一种编程范式.指在设计程序时大量运用类实例对象的方式.OOP一旦在项目中被运用,就成了时刻要考虑的东西. 面向服务架构(Service-Oreinted Architecture) 是将软件设计

原生JS面向对象思想封装轮播图组件

原生JS面向对象思想封装轮播图组件 在前端页面开发过程中,页面中的轮播图特效很常见,因此我就想封装一个自己的原生JS的轮播图组件.有了这个需求就开始着手准备了,代码当然是以简洁为目标,轮播图的各个功能实现都分别分为不同的模块.目前我封装的这个版本还不适配移动端,只适配PC端. 主要的功能有:自动轮播,点击某一张图片对应的小圆点就跳转到指定图片,有前后切换按钮.使用的时候只需要传入图片的路径以及每张图片分别所对应的跳转路径还有目标盒子ID就可以了,还可以自定义每张图轮播的延时,不过延时参数不是必须

【组件化开发】前端进阶篇之如何编写可维护可升级的代码

前言 我还在携程的做业务的时候,每个看似简单的移动页面背后往往会隐藏5个以上的数据请求,其中最过复杂的当属机票与酒店的订单填写业务代码 这里先看看比较“简单”的机票代码: 然后看看稍微复杂的酒店业务逻辑: 机票一个页面的代码量达到了5000行代码,而酒店的代码竟然超过了8000行,这里还不包括模板(html)文件!!! 然后初略看了机票的代码,就该页面可能发生的接口请求有19个之多!!!而酒店的的交互DOM事件基本多到了令人发指的地步: 当然,机票团队的交互DOM事件已经多到了我笔记本不能截图了

关于前端组件化开发的一点思考

前端开发与其他程序开发的共性在于,同样要求“高内聚,低耦合,易读写,可复用”. “高内聚”是指将在逻辑上可以归类为一个单元的代码封装在一起,尽量保障一块代码集合主要解决一个需求,在前端开发中,最常见的便是将一个逻辑单元的代码使用IIFE函数进行封装. 可以说,保障代码高内聚即在一定程度上满足了代码“低耦合”的要求,因为低耦合即是要求一个逻辑单元的代码块在改动时,不会造成其他逻辑单元代码块的变动,在前端开发中,即是要求各代码块不要过多共享某变量或对象,在不得以的情况下,一定要清晰注释. “易读写”

Vue组件化开发

一. 通过axios实现数据请求 1. json简介 json是 JavaScript Object Notation 的首字母缩写,单词的意思是javascript对象表示法,这里说的json指的是类似于javascript对象的一种数据格式. json的作用:在不同的系统平台,或不同编程语言之间传递数据. 1.1 json数据的语法 json数据对象类似于JavaScript中的对象,但是它的键对应的值里面是没有函数方法的,值可以是普通变量,不支持undefined,值还可以是数组或者jso

Webpack+Vue+ES6 前端组件化开发mobile-multi-page应用实战总结

本文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws 一.写在前面 项目上线有一段时间了,一个基于webpack+vue+ES6的手机端多页面应用.其实说是多页面应用,实际上在webpack中属于四个app,  如果真是做纯单页面,那应该有二三十个页面吧.所以我这里的多页面应用,是分为四个SPA.比如微信最下面,有四个导航,微信,通讯录,发现,我. 那么这四个导航,就是我的四个SPA,配置多个入口即可. 在这里就不说太多代码了,项目结构将会放

Android适合组件化开发的路由框架:Launch

1.概述 最近越来越不想写代码了,特别是一些重复性的代码,比如由于每次启动一个 Activity,我们都会很习惯的在 Activity 中写下: public static void launch(Activity activity) { Intent intent = new Intent(); intent.setClass(activity, xxxActivity.class); activity.startActivity(); } 已经有两年Android开发经验的我掐指一算,好像有

Android 业务组件化开发实践

组件化并不是新话题,其实很早很早以前我们开始为项目解耦的时候就讨论过的.但那时候我们说的是功能组件化.比如很多公司都常见的,网络请求模块.登录注册模块单独拿出来,交给一个团队开发,而在用的时候只需要接入对应模块的功能就可以了. 百牛信息技术bainiu.ltd整理发布于博客园 今天我们来讨论一下业务组件化,拿出手机,打开淘宝或者大众点评来看看,里面的美食电影酒店外卖就是一个一个的业务.如果我们在一个项目里面去写的时候,总会出现或多或少的代码耦合,最典型的有时为了赶上线时间而先复制粘贴一段类似的代

Android组件化开发的简单应用

组件化开发的主要步骤: 一.新建Modules 1.新建Project,作为应用的主Module. 2.新建Module:"Common",类型选择"Android Library",作为所有其它Module的基础依赖库. 3.新建Module:"Home",类型选择"Android Library",依赖"Common". 4.新建Module:"Project",类型选择"