[vue] 实现多条件筛选

大体效果图是这样的:
​​[vue] 实现多条件筛选_第1张图片
[vue] 实现多条件筛选_第2张图片
一、涉及的知识点:

  1. vue 组件化开发,不懂的可以参考vue 组件基础 ==》https://cn.vuejs.org/v2/guide/components.html
  2. es6 promise 模拟数据,参考 ==》http://es6.ruanyifeng.com/#docs/promise

其他:
1.可把组件单独放一个js文件里,通过script 引入即可。
2.全部写在一个页面是为了更加直观的理解,开发代码时,个人不建议用此方法
3.第一次写文章,有什么不对的,希望大家别见怪!谢谢

<script src="js/demo-filter.js"></script>

二、实现:

  1. 主逻辑部分
const vm = new Vue({
	el: '#view',
	data() {
		return {
			viewList: [],
			viewTime: {
				time: true,
				msg: '数据拼命加载中...'
			},
			param: {},
			filterList: [],
			filterSelData: [] // 过滤选中的数据
		}
	},
	created() {
		// 请求数据
		this.setRequest('json/demo2.json', this.param, 'get').then(res => {
			this.viewList = [...res.list]
			return this.setRequest('json/demo3.json', this.param, 'get')
		}).then(res => {
			this.filterList = [...res.list]
		})
	},
	mounted() {
		this.setTime(1000, 0, false)
	},
	methods: {
		// 封装 axios
		setRequest(url, data = {}, method = 'get') {
			return new Promise((resolve, reject) => {
				axios({
					url,
					method,
					data
				}).then(res => {
					resolve(res.data)
				}).catch(err => {
					reject(err)
				})
			})
		},

		// 获取筛选组件选中的值
		getFilterSelData(data) {
			this.filterSelData = data
		},

		// 模拟延时显示数据视图
		setTime(startTime, endTime, bool) {
			setTimeout(() => {
				this.viewTime.time = bool
				setTimeout(() => {
					this.viewTime.time = false
				}, endTime)
			}, startTime)
		}
	}
})
  1. 过滤筛选组件
// 过滤组件
Vue.component('demo-filter', {
	template: `
		
{{v.title}}
{{val.value}}
更多
`
, data() { return { isShow: false } }, props: { getList: { type: Array, default: () => [] } }, methods: { tabClick(data, key, k) { // 添加 active ==> true 显示 `active样式` this.getList[k].childer.map(item => { item.active = false }) this.getList[k].childer[key].active = true // 选中的数据 let newArray = [] this.getList.map(data => { data.childer.map(item => { if (item.active == true) { newArray.push(item) } }) }) this.$emit('get-sel-data', newArray) this.$emit('set-time', 0, 1000, true) } } })
  1. 布局组件
Vue.component('view-layout', {
	template: `
{{v.title}}
{{viewTime.msg}}
`
, props: { viewData: { type: Array, default: () => [] }, width: { type: String, default: "25%" }, height: { type: String, default: "300px" }, viewTime: { type: Object, default: { time: true, msg: '数据加载中...' } } }, computed: { style() { return { width: `${this.width.replace(/%+/, '')}%`, height: `${this.height.replace(/px+/, '')}px` } } } })
  1. 页面调用
<demo-filter :get-list="filterList" @get-sel-data="getFilterSelData" @set-time="setTime">demo-filter>
<view-layout :view-data="viewList" width="25%" height="300px" :view-time="viewTime">view-layout>
  1. json数据
1.布局组件json ==> 路径: json/demo2.json
{
	"list": [{
			"title": "11"
		},
		{
			"title": "22"
		},
		{
			"title": "33"
		},
		{
			"title": "44"
		},
		{
			"title": "55"
		},
		{
			"title": "66"
		}
	]
}
2. 过滤筛选组件json ==> 路径: json/demo3.json 
{
	"list": [{
			"title": "分类:",
			"childer": [{
					"value": "全部",
					"active": true
				},
				{
					"value": "漂浮素材",
					"active": false
				},
				{
					"value": "效果元素",
					"active": false
				},
				{
					"value": "卡通手绘",
					"active": false
				},
				{
					"value": "装饰图案",
					"active": false
				},
				{
					"value": "图标元素",
					"active": false
				},
				{
					"value": "促销标签",
					"active": false
				},
				{
					"value": "边框纹理",
					"active": false
				},
				{
					"value": "不规则图形",
					"active": false
				},
				{
					"value": "表情包213123",
					"active": false
				},
				{
					"value": "表情包2323",
					"active": false
				},
				{
					"value": "表情包1111",
					"active": false
				},
				{
					"value": "表情包3333",
					"active": false
				},
				{
					"value": "表情包444",
					"active": false
				}
			]
		},
		{
			"title": "格式:",
			"childer": [{
					"value": "全部",
					"active": true
				},
				{
					"value": "PSD",
					"active": false
				},
				{
					"value": "AI",
					"active": false
				},
				{
					"value": "EPS",
					"active": false
				}
			]
		},
		{
			"title": "排序:",
			"childer": [{
					"value": "推荐",
					"active": true
				},
				{
					"value": "昨日热门",
					"active": false
				},
				{
					"value": "最新上传",
					"active": false
				},
				{
					"value": "热门下载",
					"active": false
				},
				{
					"value": "热门收藏",
					"active": false
				}
			]
		}
	]
}
  1. css 样式
/* 布局组件:start */
.view-warp {
	flex: 1;
	overflow: hidden;
	margin: auto;
	display: flex;
}

.view-box {
	overflow: auto;
	width: 1220px;
	height: 100%;
	display: flex;
	flex-wrap: wrap;
	align-content: flex-start;
	margin: 0 -10px;
}

.view-flex {
	padding: 10px;
	cursor: pointer;
	transition: ease .5s;
	transform-style: preserve-3d;
}

.view-flex:hover {
	transform: translateY(-10px);
	transition: ease .5s;
}

.view-item {
	height: 100%;
	border: 1px solid red;
	display: flex;
}

.view-item>span {
	margin: auto;
}

.view-no-data {
	margin: auto;
}

/* 布局组件:end */

/* 过滤列表:start */
.demo {
	box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
	margin-bottom: 15px;
	min-height: 140px;
	height: auto !important;
	height: 140px;
}

.demo-warp {
	display: flex;
	max-width: 1200px;
	margin: auto;
	height: 100%;
	flex-direction: column;
	padding: 15px 0;
}

.demo-flex {
	display: flex;
	margin-bottom: 15px;
}

.demo-flex:last-of-type {
	margin-bottom: 0;
}

.demo-title {
	flex-basis: 70px;
	margin-top: 5px;
}

.demo-content {
	display: flex;
	flex: 1;
}

.demo-tab {
	flex: 1;
	margin-right: 15px;
	height: 35px;
	overflow: hidden;
}

.demo-tab span {
	display: inline-block;
	margin: 0 5px 15px 5px;
	cursor: pointer;
	padding: 5px 10px;
	color: #999999;
}

.demo-more {
	margin-top: 5px;
	cursor: pointer;
}

.demo-active {
	background-color: #09F;
	color: white !important;
	border-radius: 3px;
}

.demo-tab span:hover {
	background-color: #09F;
	color: white;
	border-radius: 3px;
}

.demo-hide {
	min-height: 35px;
	height: auto !important;
}

/* 过滤列表:end */

三、全部html:


<html>
   <head>
   	<meta charset="utf-8">
   	<title>title>
   	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
   	<script src="https://unpkg.com/axios/dist/axios.min.js">script>
   	<style type="text/css">
   		* {
   			margin: 0;
   			padding: 0;
   			box-sizing: border-box;
   		}

   		html,
   		body,
   		section {
   			width: 100%;
   			height: 100%;
   		}

   		[v-clock] {
   			display: none;
   		}

   		section {
   			display: flex;
   			flex-direction: column;
   		}

   		/* 布局组件:start */
   		.view-warp {
   			flex: 1;
   			overflow: hidden;
   			margin: auto;
   			display: flex;
   		}

   		.view-box {
   			overflow: auto;
   			width: 1220px;
   			height: 100%;
   			display: flex;
   			flex-wrap: wrap;
   			align-content: flex-start;
   			margin: 0 -10px;
   		}

   		.view-flex {
   			padding: 10px;
   			cursor: pointer;
   			transition: ease .5s;
   			transform-style: preserve-3d;
   		}

   		.view-flex:hover {
   			transform: translateY(-10px);
   			transition: ease .5s;
   		}

   		.view-item {
   			height: 100%;
   			border: 1px solid red;
   			display: flex;
   		}

   		.view-item>span {
   			margin: auto;
   		}

   		.view-no-data {
   			margin: auto;
   		}

   		/* 布局组件:end */

   		/* 过滤列表:start */
   		.demo {
   			box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
   			margin-bottom: 15px;
   			min-height: 140px;
   			height: auto !important;
   			height: 140px;
   		}

   		.demo-warp {
   			display: flex;
   			max-width: 1200px;
   			margin: auto;
   			height: 100%;
   			flex-direction: column;
   			padding: 15px 0;
   		}

   		.demo-flex {
   			display: flex;
   			margin-bottom: 15px;
   		}

   		.demo-flex:last-of-type {
   			margin-bottom: 0;
   		}

   		.demo-title {
   			flex-basis: 70px;
   			margin-top: 5px;
   		}

   		.demo-content {
   			display: flex;
   			flex: 1;
   		}

   		.demo-tab {
   			flex: 1;
   			margin-right: 15px;
   			height: 35px;
   			overflow: hidden;
   		}

   		.demo-tab span {
   			display: inline-block;
   			margin: 0 5px 15px 5px;
   			cursor: pointer;
   			padding: 5px 10px;
   			color: #999999;
   		}

   		.demo-more {
   			margin-top: 5px;
   			cursor: pointer;
   		}

   		.demo-active {
   			background-color: #09F;
   			color: white !important;
   			border-radius: 3px;
   		}

   		.demo-tab span:hover {
   			background-color: #09F;
   			color: white;
   			border-radius: 3px;
   		}

   		.demo-hide {
   			min-height: 35px;
   			height: auto !important;
   		}

   		/* 过滤列表:end */
   	style>
   head>
   <body>
   	<section id="view" clock>
   		<demo-filter :get-list="filterList" @get-sel-data="getFilterSelData" @set-time="setTime">demo-filter>
   		<view-layout :view-data="viewList" width="25%" height="300px" :view-time="viewTime">view-layout>
   		<pre>
   			选中的数据:{{filterSelData}}
   		pre>
   	section>

   	<script type="text/javascript">
   		// 过滤筛选组件
   		Vue.component('demo-filter', {
   			template: `
   				
{{v.title}}
{{val.value}}
更多
`
, data() { return { isShow: false } }, props: { getList: { type: Array, default: () => [] } }, methods: { tabClick(data, key, k) { // 添加 active ==> true 显示 `active样式` this.getList[k].childer.map(item => { item.active = false }) this.getList[k].childer[key].active = true // 选中的数据 let newArray = [] this.getList.map(data => { data.childer.map(item => { if (item.active == true) { newArray.push(item) } }) }) this.$emit('get-sel-data', newArray) this.$emit('set-time', 0, 1000, true) } } }) // 布局组件 Vue.component('view-layout', { template: `
{{v.title}}
{{viewTime.msg}}
`
, props: { viewData: { type: Array, default: () => [] }, width: { type: String, default: "25%" }, height: { type: String, default: "300px" }, viewTime: { type: Object, default: { time: true, msg: '数据加载中...' } } }, computed: { style() { return { width: `${this.width.replace(/%+/, '')}%`, height: `${this.height.replace(/px+/, '')}px` } } } })
script> <script type="text/javascript"> const vm = new Vue({ el: '#view', data() { return { viewList: [], viewTime: { time: true, msg: '数据拼命加载中...' }, param: {}, filterList: [], filterSelData: [] // 过滤选中的数据 } }, created() { // 请求数据 this.setRequest('json/demo2.json', this.param, 'get').then(res => { this.viewList = [...res.list] return this.setRequest('json/demo3.json', this.param, 'get') }).then(res => { this.filterList = [...res.list] }) }, mounted() { this.setTime(1000, 0, false) }, methods: { // 封装 axios setRequest(url, data = {}, method = 'get') { return new Promise((resolve, reject) => { axios({ url, method, data }).then(res => { resolve(res.data) }).catch(err => { reject(err) }) }) }, // 获取筛选组件选中的值 getFilterSelData(data) { this.filterSelData = data }, // 模拟延时显示数据视图 setTime(startTime, endTime, bool) { setTimeout(() => { this.viewTime.time = bool setTimeout(() => { this.viewTime.time = false }, endTime) }, startTime) } } }) script> body> html>

你可能感兴趣的:([vue] 实现多条件筛选)