Vue.js快速入门之六:Set和Map的妙用

ES6的Set和Map区别是:Set是“集合”结构,而Map是“字典”结构;Set是以[value, value]的形式存储元素,而Map是以[key, value]的键值对形式存储元素;Map可以用get()键查找到特定值并返回,而Set不行。

一、Set的方法

方法名参数返回值描述
addvalue实例Set新增,相当于Array里的push
deletevalueBoolean集合中存在,则删除其value
hasvalueBoolean判断集合中是否存在value
clear清空集合
keysiterable返回一个包含集合中所有键的迭代器
valuesiterable返回一个包含集合中所有值的迭代器
entriesiterable返回一个包含Set对象中所有元素的键值对迭代器
forEach用于对集合成员执行callback回调函数操作,如果提供了this Arg参数,回调中的this会是这个参数,没有返回值。

注意:

  1. 成员不能重复
  2. 只有值没有键名,类似数组
  3. 可以遍历,方法有add, delete, has等

二、Map的方法

方法参数返回值描述
set(key, value)实例Map向字典中添加新元素
getkeyvalue通过键查找特定的数值并返回
haskeyBoolean判断字典中是否存在键key
delelekeyBoolean通过键key从字典中移除对应的数据
clear将这个字典中的所有元素删除
keysiterable将字典中包含的所有键名以迭代器形式返回
valuesiterable将字典中包含的所有数据以迭代器形式返回
entriesiterable返回所有成员的迭代器
forEach遍历字典的所有成员

注意:

  1. 本质上是键值对的集合
  2. 可以遍历,可以跟各种数据格式转换

三、本地模拟数据 获取栏目表

        最近在研究Vue项目的本地模拟数据时,发现ES6的Set和Map可以很好实现本地数据的增删改查,也解决了Array会存储重复数据问题。对于某些项目特定需求,是有帮助的,这里通过以下小案例,让大家了解如何使用它们。

 注:axios和mockjs上两篇已介绍,不清楚可以翻看下。

3.1 创建data.js,模拟本地数据库

        在mock目录中,创建data.js文件,data.js是本地模拟数据库,里在存储各种数据,代码如下:

import { mock } from 'mockjs'

//实例Map,定义一个存储数据的 数据表
const DBMap = new Map();


export default DBMap;

3.2 定义栏目容器

import { mock } from 'mockjs'

//实例Map,定义一个存储数据的 数据表
const DBMap = new Map();

//实例Map,定义一个存储栏目的 数据集
const category = new Map();

//将栏目数据集 存储到 数据表中
DBMap.set("栏目列表", category);

export default DBMap;

3.3 通过mockjs生成栏目模拟数据

        在data.js中,通过mockjs生成栏目模拟数据,然后循环追加到集合中,代码如下:

let _index = 1;
//使用mock生成栏目模拟数据
mock({
	'data|5': [
		{
			'name|+1': opt => { return '菜单栏目' + _index; }, 
			'id': '@id', 
			'path': opt => { return '/category/column' + (_index++); }
		}
	]
})['data'].forEach(item => {
	category.set(item.id, item);
})

console.log(category);

控制台输出结果如下图:

3.4 创建index.js,定义模拟数据接口

        在mock目录中,创建index.js来定义模拟数据的接口,具体用法上一篇已详细讲解。

import DBMap from './data'

//获取所有栏目
mock("/api/category", "get", (req, res) => {
	let _result = [];
	//获取栏目数据
	let _category = DBMap.get("栏目列表");
	let _isDone = false;
	
	//循环获取数据
	try{
		let _keys = _category.keys();
		do {
			let _next = _keys.next();
			
			_isDone = _next.done;
			if(_next.value){
				_result.push(_category.get(_next.value))
			}
		} while (!_isDone);
	}catch(e){}
	
	return {
		code: 200,
		message: 'success',
		data: _result
	}
});

3.5 创建api目录

        在api目录创建api.js,用来定义接口请求函数,代码如下:

import service from '@/utils/request'

//获取栏目数据
export const getCategory = () => {
	return service.get('/api/category', {});
}

3.6 在页面中获取栏目数据

import { getCategory } from '@/api/api'
	
export default {
	data(){
		return {
			categoryList: []
		}
	},
	created(){
		this.updateList();
	},
	methods: {
		//获取栏目列表
		updateList(){
			getCategory().then(res => {
				if(res.code == 200){
					this.categoryList = res.data;
				}
				console.log(res);
			}).catch(error => {
				console.error(error);
			})
		}
	}
}

控制台输出结果如下图:

四、实现栏目名称的增删除改查功能

        通过实现下图案例,完成增删改功能演示。

4.1 实现添加功能

         1)mock目录中index.js增加栏目的添加模拟接口

import { mock } from 'mockjs'

//增加栏目
mock("/api/category", "post", (req, res) => {
	let _result = "",
			_code = 0,
			_data = mock({'id': '@id'});
	
	if(req['body']){
		//获取栏目数据
		let _category = DBMap.get("栏目列表");
		
		_category.set(_data.id, mock({
			'name': req.body, 
			'id': _data.id, 
			'path': opt => { return '/category/column' + _category.size; }
		}))
	
		_code = 200;
		_result = "保存成功";
	}else{
		_result = "请输入栏目名称";
	}

	return {
		code: _code,
		message: _result,
		data: null
	}
});

        2)api目录的api.js中添加请求接口函数

//添加栏目
export const addCategory = param => {
	return service.post('/api/category', param);
}

        3)页面中增加“添加事件函数“

import { getCategory, addCategory } from '@/api/api'
	
export default {
	data(){
		return {
			categoryList: []
		}
	},
	created(){
		this.updateList();
	},
	methods: {
		//获取栏目列表
		updateList(){
			getCategory().then(res => {
				if(res.code == 200){
					this.categoryList = res.data;
				}
				console.log(res);
			}).catch(error => {
				console.error(error);
			})
		},
		
		//添加栏目事件
		addCategory(){
			this.$prompt('请输入栏目名称', '提示', {
				confirmButtonText: '保存',
				cancelButtonText: '取消',
			}).then( res => {
				addCategory(res.value).then(res => {
					if(res.code==200){
						this.$message.success(res.message);
						this.updateList();
					}else{
						this.$message.error(res.message);
					}
				});
			}).catch( () => {
				this.$message({
					type: 'info',
					message: '已取消'
				});
			});
		},
		
		//end
	}
}

        以上几步完成后,页面中点击添加事件,会弹出如下图输入框:

        输入完成保存后,重新获取栏目列表,新添加栏目已在列表中了,结果如下图:

 4.2 实现修改功能

        这边在每个栏目上添加了悬浮显示编辑和删除功能按钮,鼠标放到对应栏目项,则显示操作按钮。如下图:

        1)mock目录中index.js增加栏目的修改模拟 接口

//修改栏目名称
mock("/api/category", "put", (req, res) => {
	let _result = "",
			_code = 0;
	if(req['body']){
		//获取栏目数据
		let _data = JSON.parse(req.body),
				_category = DBMap.get("栏目列表"),
				_column = _category.get(_data['id']);
		//修改栏目名称
		_column['name'] = _data['name'];
		_code = 200;
		_result = "修改成功";
	}else{
		_result = "参数格式错误";
	}

	return {
		code: _code,
		message: _result,
		data: null
	}
});

        2)api目录中api.js增加修改请求接口函数

//修改栏目
export const editCategory = param => {
	return service.put('/api/category', param);
}

        3)页面的methods中增加“修改事件函数”

//编辑栏目名称事件
editCategory(_id, _name){
	this.$prompt('请输入栏目名称', '提示', {
		confirmButtonText: '保存',
		cancelButtonText: '取消',
		inputValue: _name
	}).then( res => {
		editCategory({
			id: _id,
			name: res.value
		}).then(res => {
			if(res.code==200){
				this.$message.success(res.message);
				this.updateList();
			}else{
				this.$message.error(res.message);
			}
		})
	}).catch( () => {
		this.$message({
			type: 'info',
			message: '已取消'
		});
	});
}
//end

        以上几步完成后,鼠标放到“菜单栏目3”上,点击编辑图标,弹出修改弹框,将“菜单栏目3”修改成”家电电器“,如下图:

         输入完成点击保存后,重新获取栏目列表,列表中名称已被修改了,结果如下图:

4.3 实现删除功能

         这时,栏目中”新添加的栏目“不需要了,通过删除功能移出掉。

        1)mock目录中index.js增加栏目的删除模拟接口

//修改栏目名称
mock("/api/category", "delete", (req, res) => {
	let _result = "",
			_code = 0;
	if(req['body']){
		//获取栏目数据
		let _category = DBMap.get("栏目列表");
		if(_category.has(req.body)){
			_category.delete(req.body);
			_code = 200;
			_result = "删除成功";
		}else{
			_result = "该栏目不存在~";
		}
	}else{
		_result = "请传入需要删除项的ID";
	}

	return {
		code: _code,
		message: _result,
		data: null
	}
});

        2)api目录中api.js增加删除请求接口函数

//删除栏目
export const deleteCategory = param => {
	return service.delete('/api/category', {
		data: param
	});
}

        3)页面的methods中增加”删除事件函数“

//删除指定栏目
deleteCategory(_id){
	this.$confirm('此操作将永久删除该栏目,是否继续?', "提示", {
		confirmButtonText: "确认删除",
		cancelButtonText: "取消",
		type: "warning"
	}).then(res => {
		deleteCategory(_id).then(res => {
			if(res.code==200){
				this.$message.success(res.message);
				this.updateList();
			}else{
				this.$message.error(res.message);
			}
		});
	}).catch(() => {
		this.$message({
			type: 'info',
			message: '已取消'
		});
	});
},

        点击删除图标后,会出出确认是否删除弹框如下图:

         点击确认后,栏目列表位置”新添加的栏目“就被删除了。

五、栏目的关键词功能 

        

        现在我们来实现添加关键词功能,给每个栏目单独添加关键,这时就用到了Set集合了,它可以存储无重复元素。

5.1 实现栏目切换功能

        Html代码如下:

<div>
	<div class="category-box">
		<div class="left-cont">
			<div class="menu-list">
				<div class="item" 
                    :class="{'active': categoryIndex==index}" 
                    v-for="(item, index) in categoryList" 
                    :key="index">
					//...
					<h3 @click="changeMenuEvent(index)">{{item.name}}</h3>
				</div>
				<div class="item add" @click="addCategory">
					<h3>添加栏目</h3>
				</div>
			</div>
		</div>
		<div class="right-cont">
			//...
		</div>
	</div>
</div>

        JS代码如下:

export default {
	data(){
		return {
			categoryList: [],
            //当前选中栏目索引值
			categoryIndex: 0,    
			//右侧关键词数据集
			tagsList: []
		}
	},
	methods: {
		//选择栏目事件
		changeMenuEvent(index){
			this.categoryIndex = index;
		},

		...
	}
}

        如上代码,将changeMenuEvent函数绑定到菜单栏目元素的Dom的@click事件上即可。

5.2 data.js数据表中定义Set集合

        这里将3.1和3.2 中的代码进行稍微修改,代码如下:

import { mock } from 'mockjs'

//实例Map,定义一个存储数据的 数据表
const DBMap = new Map();
//实例Map,定义一个存储栏目的 数据集
const category = new Map();
//实例Map,定义一个存储关键词的数据集
const tags = new Map();
//数据集 存储到 数据表中
DBMap.set("栏目列表", category);
DBMap.set("关键词列表", tags);


//通过mock随机生成栏目名
let _index = 1;
//使用mock生成栏目模拟数据
mock({
	'data|5': [
		{
			'name|+1': opt => { return '菜单栏目' + _index; }, 
			'id': '@id', 
			'path': opt => { return '/category/column' + (_index++); }
		}
	]
})['data'].forEach(item => {
	tags.set(item.id, new Set());
	category.set(item.id, item);
})

5.3 获取对应栏目的关键词列表

        1)mock目录中index.js增加获取关键词列表模拟接口

//获取关键词列表
mock("/api/tags", "get", (req, res) => {
	let _result = [],
			_code = 0,
			_msg = "";
	//获取关键词数据
	let _tags = DBMap.get("关键词列表");
	if(req['body']){
		try{
			let _setData = _tags.get(req.body),
				_values = _setData.values(),
				_isDone = false;
			if(_setData.size!=0){
                //循环获取数据
				do{
					let _next = _values.next();
					_isDone = _next.done;
					if(_next.value){
						_result.push(_next.value);
					}
				} while(!_isDone);
			}
			_code = 200;
			_msg = "success";
		}catch(e){
			_code = 0;
			_msg = JSON.stringify(e);
		}
	}else{
		_code = 0;
		_msg = "请传入栏目ID";
	}
	
	return {
		code: _code,
		message: _msg,
		data: _result
	}
});

        2)api目录中api.js增加获取关键词请求接口函数

//获取关键词列表
export const getTagsList = param => {
	return service.get('/api/tags', {
		data: param
	});
}

        3)页面的methods中增加“获取关键词列表”事件函数

//获取关键词列表
updateTags(){
	let _id = this.categoryList[this.categoryIndex]['id'];
	getTagsList(_id).then(res => {
		if(res.code==200){
			this.tagsList = res.data;
		}
	})
}

        这时,每个栏目中还有没有关键词,所有获取是空数组。还需要注意一件事,就是获取关键词列表事件函数已定义,需要在栏目切换时,重新获取关键词列表数据,changeMenuEvent事件函数修改如下:

//选择栏目事件
changeMenuEvent(index){
	this.categoryIndex = index;
	this.updateTags();
},

六、实现关键词增删改功能

6.1 添加关键词

        1)mock目录中index.js增加 添加关键词模拟接口

//栏目中添加关键词信息
mock("/api/tags", "post", (req, res) => {
	let _result = [],
			_code = 0,
			_msg = "";
	//获取关键词数据
	let _tags = DBMap.get("关键词列表");
	if(req['body']){
		try{
			let _data = JSON.parse(req.body), 
				_setData = _tags.get(_data.id);
			_setData.add(_data['name']);			
			_code = 200;
			_msg = "success";
		}catch(e){
			_code = 0;
			_msg = JSON.stringify(e);
		}
	}else{
		_code = 0;
		_msg = "请传入栏目ID";
	}
	
	return {
		code: _code,
		message: _msg,
		data: _result
	}
});

        2)api目录中api.js增加 添加关键词请求接口函数

//添加关键词信息
export const addTags = param => {
	return service.post('/api/tags', param);
}

        3)页面的methods中增加“添加关键词”事件函数

//添加关键词
addTagsEvent(){
	let _id = this.categoryList[this.categoryIndex]['id'];
	this.$prompt('请输入关键词名称', '提示', {
		confirmButtonText: '保存',
		cancelButtonText: '取消',
	}).then( res => {
		addTags({
			id: _id,
			name: res.value
		}).then(res => {
			if(res.code==200){
				this.$message.success(res.message);
				this.updateTags();
			}else{
				this.$message.error(res.message);
			}
		});
	}).catch( () => {
		this.$message({
			type: 'info',
			message: '已取消'
		});
	});
},

         点击“添加关键词”按钮后,会弹出如下弹框,然后点击“保存”。

 

        保存后,页面中就已显示新添加的关键词信息了,如下图:

 

6.2 修改关键词

        如下图,这里菜单栏目1中,有个“test3”关键事,现在要把它修改成“test2”。

         1)mock目录中index.js增加 修改关键词模拟接口

//栏目中修改关键词信息
mock("/api/tags", "put", (req, res) => {
	let _result = [],
			_code = 0,
			_msg = "";
	//获取关键词数据
	let _tags = DBMap.get("关键词列表");

	if(req['body']){
		try{
			let _data = JSON.parse(req.body), 
				_setData = _tags.get(_data.id);
			if(_setData.has(_data.oldVal)){
				_setData.delete(_data.oldVal);
				_setData.add(_data.newVal);			
				_code = 200;
				_msg = "success";
			}else{
				_code = 0;
				_msg = "修改的信息不存在";
			}
		}catch(e){
			_code = 0;
			_msg = JSON.stringify(e);
		}
	}else{
		_code = 0;
		_msg = "请传入栏目ID";
	}
	
	return {
		code: _code,
		message: _msg,
		data: _result
	}
});

        2)api目录中api.js增加 修改关键词请求接口函数

//修改关键词信息
export const editTags = param => {
	return service.put('/api/tags', param);
}

        3)页面的methods中增加“修改关键词”事件函数

//修改关键词
editTagsEvent(_name){
	let _id = this.categoryList[this.categoryIndex]['id'];
	this.$prompt('请输入栏目名称', '提示', {
		confirmButtonText: '保存',
		cancelButtonText: '取消',
		inputValue: _name
	}).then( res => {
		editTags({
			id: _id,
			oldVal: _name,			//原内容
			newVal: res.value		//新内容
		}).then(res => {
			if(res.code==200){
				this.$message.success(res.message);
				this.updateTags();
			}else{
				this.$message.error(res.message);
			}
		})
	}).catch( () => {
		this.$message({
			type: 'info',
			message: '已取消'
		});
	});
},

        鼠标放到要修改关键词上,点击悬浮图标“修改按钮”,会弹出修改弹框,如下图:

         把“test3”修改成“test2”后,点击保存,这里页面上就显示为“test2”了,如下图:

6.3 删除关键词

         1)mock目录中index.js增加 删除关键词模拟接口

//栏目中修改关键词信息
mock("/api/tags", "delete", (req, res) => {
	let _result = [],
			_code = 0,
			_msg = "";
	//获取关键词数据
	let _tags = DBMap.get("关键词列表");
	if(req['body']){
		try{
			let _data = JSON.parse(req.body), 
				_setData = _tags.get(_data.id);
			if(_setData.has(_data.name)){
				_setData.delete(_data.name);	
				_code = 200;
				_msg = "success";
			}else{
				_code = 0;
				_msg = "删除的信息不存在";
			}
		}catch(e){
			_code = 0;
			_msg = JSON.stringify(e);
		}
	}else{
		_code = 0;
		_msg = "请传入栏目ID";
	}
	
	return {
		code: _code,
		message: _msg,
		data: _result
	}
});

        2)api目录中api.js增加 删除关键词请求接口函数

//删除关键词信息
export const deleteTags = param => {
	return service.delete('/api/tags', {
		data: param
	});
}

        3)页面的methods中增加“删除关键词”事件函数

//删除关键词
deleteTagsEvent(_name){
	let _id = this.categoryList[this.categoryIndex]['id'];
	this.$confirm('此操作将永久删除关键词('+_name+'),是否继续?', "提示", {
		confirmButtonText: "确认删除",
		cancelButtonText: "取消",
		type: "warning"
	}).then(res => {
		deleteTags({
			id: _id,
			name: _name
		}).then(res => {
			if(res.code==200){
				this.$message.success(res.message);
				this.updateTags();
			}else{
				this.$message.error(res.message);
			}
		});
	}).catch(() => {
		this.$message({
			type: 'info',
			message: '已取消'
		});
	});
},

        将刚修改过的“test2”删除掉,点击“删除图标按钮”,弹出删除确认码,如下图:

         点击确认删除后,页面中“test2”就消失了,如下图:

         这一波操作下来,是不是觉得很有意思。在后台接口未完成之前,前端就可以模拟数据库表,进行数据的增删除改查操作。在此同时,前端也可以完善接口文档,与后台同步接口中的入参数据和响应数据,使得真实接口中的数据和模拟接口中的数据完善衔接。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值