vue实现前台列表数据过滤搜索、分页效果


Posted in Javascript onMay 28, 2019

本文实例为大家分享了vue实现列表数据过滤搜索、分页效果的具体代码,供大家参考,具体内容如下

vue实现前台列表数据过滤搜索、分页效果

job.vue页面

<style lang="scss">
.job-wrapper {
 padding-top: 50px;
}
.job-left {
 float: left;
 margin-right: 20px;
 padding: 20px;
 width: 310px;
 background: #fff;
}
.job-serach-title {
 margin: 8px 0 10px 0;
 color: rgb(51, 51, 51);
 font-size: 16px;
}

.job-search-input {
 display: flex;
}
.job-keywords {
 width: 400px;
}
.job-search-btn {
 display: flex;
 align-items: center;
 justify-content: center;
 margin-left: 10px;
 width: 50px;
 height: 40px;
 border-radius: 4px;
 background-color: rgb(254, 62, 98);
}
.line {
 margin: 25px 0 0 0;
 width: 100%;
 height: 1px;
 background: #dfdfdf;
}

.halogg {
 margin-top: 30px;
 color: rgb(102, 102, 102);
 font-weight: 300;
 font-size: 14px;
}
.job-right {
 float: right;
 width: 870px;
 background: #fff;
}
</style>

<style lang="scss">
// 重置样式
#job-select-1,
#job-select-2 {
 margin-top: 20px;
 select {
 width: 100%;
 }
}
</style>
<template>
 <article class="job">

 <div class="job-content layout">
 <div class="job-wrapper">
 <div class="job-left">
  <div class="job-serach-title">搜索更多职位</div>
  <div class="job-search-input">
  <input v-model.trim="formData.keywords" @change="searchData" placeholder="搜索更多职位" class="job-keywords" />
  <div class="job-search-btn pointer" @click="searchData">
  搜
  </div>
  </div>
  <div class="line"></div>
  <div class="job-select" id="job-select-1">
  <select v-model="formData.address" @change="searchData">
  <option v-for="item,index in regionArr" :key="index">{{item.name}}</option>
  </select>
  </div>
  <div class="job-select" id="job-select-2">
  <select v-model="formData.title" @change="searchData">
  <option v-for="(item,index) in searchList" :key="index">{{item}}</option>
  </select>
  </div>
 </div>
 <div class="job-right">
  <joblist></joblist>
 </div>
 </div>

 </div>
 </article>
</template>
<script>
import joblist from 'src/components/job/list';
import { mapGetters, mapActions, mapMutations } from 'vuex';

export default {
 name: 'reportFormIndex',
 data() {
 return {
 formData: {
 title: '',
 address: '',
 keywords: '',
 },
 };
 },
 computed: {
 ...mapGetters(['searchList', 'regionArr', 'show']),
 },
 watch: {},
 title() {
 return '行业';
 },
 methods: {
 ...mapActions(['getData']),
 // select 选中后的回调数据
 searchData() {
 const payload = {
 formData: Object.assign({}, this.formData),
 pageIndex: 0, // 每次搜索后, 显示搜索结果的第一页
 };
 this.$store.commit('setState', payload);
 },
 },
 mounted() {
 this.$nextTick(() => {
 this.getData();
 });
 },
 components: {
 joblist,
 },
};
</script>

组件list.vue

<style lang="scss">
.list-header {
 position: relative;
 display: flex;
 padding: 25px 30px 20px 30px;
 color: rgb(153, 153, 153);
 font-size: 14px;
 &:after {
 position: absolute;
 right: 0;
 bottom: 0;
 left: 0;
 display: inline-block;
 width: 100%;
 height: 1px;
 background-color: #dfdfdf;
 content: '';
 }
}
.l-header-item-1 {
 padding-left: 20px;
 width: 37.3%;
}
.l-header-item-2 {
 padding-left: 10px;
 width: 32.7%;
}
.l-header-item-3 {
 padding-left: 10px;
 width: 18.7%;
}
.l-header-item-4 {
 display: flex;
 width: 11.3%;
 .open {
 color: #3e8bf5;
 text-decoration: underline;
 font-size: 14px;
 }
 .arrow-open {
 margin-top: 5px;
 margin-left: 5px;
 width: 11px;
 height: 7px;
 transition: all 0.5s linear;
 }
}
.inner-item {
 padding: 0 30px;
}
.inner-box {
 position: relative;
 display: flex;
 padding: 25px 0;
 color: rgb(51, 51, 51);
 font-size: 16px;
 transition: all 0.5s linear;
 &:after {
 position: absolute;
 right: 0px;
 bottom: 0;
 left: 0px;
 display: inline-block;
 height: 1px;
 background-color: #dfdfdf;
 content: '';
 }
}
//
.list-item {
 &.active {
 .list-show-detail {
 visibility: visible;
 padding: 0 50px;
 max-height: 1000px;
 transition: all 0.5s linear;
 }
 .inner-box {
 background: #f2f2f2;
 transition: all 0.5s linear;
 &:after {
 background-color: transparent;
 }
 }
 .arrow-open {
 transition: all 0.5s linear;
 transform: rotate(-180deg);
 }
 }
}
.list-show-detail {
 visibility: hidden;
 max-height: 0;
 transition: all 0.5s linear;
}
.list-task-title {
 margin: 25px 0 15px 0;
 color: rgb(51, 51, 51);
 font-size: 14px;
}

.list-task-item {
 color: rgb(102, 102, 102);
 font-size: 14px;
 line-height: 1.714;
}
.list-apply {
 display: flex;
 align-items: center;
 justify-content: center;
 margin: 25px 0 30px 0;
 width: 140px;
 height: 50px;
 border-radius: 4px;
 background-color: rgb(254, 62, 98);
 color: rgb(255, 255, 255);
 font-size: 16px;
}

/////pagination
.job-pagination {
 padding: 50px 0;
 .pagination-wrapper {
 display: flex;
 justify-content: center;
 margin: 0 auto;
 width: 100%;
 .subscript {
 display: flex;
 align-items: center;
 justify-content: center;
 margin: 0 5px;
 width: 28px;
 height: 28px;
 border: 1px solid rgb(223, 223, 223);
 border-radius: 4px;
 color: blue;
 color: rgb(102, 102, 102);
 text-align: center;
 font-size: 14px;

 &.active {
 border: 1px solid rgb(254, 62, 98);
 background-color: rgb(254, 62, 98);
 color: #fff;
 }
 }
 .pagination-page {
 display: inline-block;
 width: 7px;
 height: 11px;
 background-image: url('./images/arrow.png');
 &.pagination-next {
 transform: rotate(180deg);
 }
 }
 }
}
////
.job-no-data {
 padding: 100px 0;
 .job-no-data-img {
 margin: 0 auto;
 width: 170px;
 height: 170px;
 background-image: url('./images/job@2x.png');
 background-size: cover;
 background-repeat: no-repeat;
 }
 .job-no-data-msg {
 margin-top: 10px;
 color: rgb(51, 51, 51);
 text-align: center;
 font-size: 18px;
 line-height: 2.778;
 }
}

@media only screen and (max-width: 1200px) {
 .list-header {
 padding: 25px 30px 20px 30px;
 }
}

@media only screen and (max-width: 767px) {
 .list-header {
 padding: 20px 15px 15px 15px;
 }
 .inner-item {
 padding: 0px 15px 0 15px;
 &:after {
 right: 15px;
 left: 15px;
 transform: scaleY(0.5);
 }
 }

 .l-header-item-1 {
 padding-left: 10px;
 }
 .l-header-item-2 {
 padding-left: 10px;
 width: 28.7%;
 }
 .l-header-item-3 {
 padding-left: 10px;
 width: 19.7%;
 }
 .l-header-item-4 {
 width: 14.3%;
 }
}
</style>
<template>
 <article id="list">
 <ul class="list-wrapper">
 <li class="list-header">
 <div class="l-header-item-1">职位名称</div>
 <div class="l-header-item-2">职位分类</div>
 <div class="l-header-item-3">所在地区</div>
 <div class="l-header-item-4"></div>
 </li>
 <li class="list-item" v-for="(item,index) in curList" :key="index" :class="{'active':item.show}" v-show="curList.length">
 <div class="inner-item">
  <div class="inner-box">
  <div class="list-position l-header-item-1">{{item.position}}</div>
  <div class="list-title l-header-item-2">{{item.title}}</div>
  <div class="list-address l-header-item-3">{{item.address}}</div>
  <div class="list-action l-header-item-4 pointer" @click="showHandler(item.id)">
  <span class="open">展开</span>
  <img src="./images/arrow-open.png" alt="" class="arrow-open">
  </div>
  </div>
 </div>
 <transition name="el-zoom-in-top">
  <div class="list-show-detail" v-show="item.show">
  <div class="list-task-title">岗位职责:</div>
  <div class="list-task-wrapper">
  <div class="list-task-item" v-for="(item2,index2) in item.task" :key="index2">{{item2}}</div>
  </div>
  <div class="list-task-title">岗位要求:</div>
  <div class="list-task-wrapper">
  <div class="list-task-item" v-for="(item3,index3) in item.rule" :key="index3">{{item3}}</div>
  </div>
  </div>
 </transition>
 </li>
 <li class="job-no-data" v-show="!curList.length">
 <div class="job-no-data-img"></div>
 <div class="job-no-data-msg">暂未合适的职位</div>
 </li>
 <li class="job-pagination" v-show="curList.length">
 <div class="pagination-wrapper">
  <span class="subscript pointer" @click="prev">
  <span class="pagination-prev pagination-page"></span>
  </span>
  <span class="subscript pointer" @click="selectPageHandler(index - 1)" v-for="index in pageLength" :key="index" :class="{active: pageIndex === index - 1}">{{index}}</span>
  <span class="subscript pointer" @click="next">
  <span class="pagination-next pagination-page"></span>
  </span>
 </div>
 </li>
 </ul>

 </article>
</template>
<script>
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex';

const PER_PAGE = 8; // 每页显示多少个

export default {
 name: 'list',
 data() {
 return {};
 },
 computed: {
 ...mapState({
 // pageIndex: state => state.job.pageIndex,
 }),
 ...mapGetters(['filterJobList', 'pageIndex']),
 curList() {
 const { filterJobList, pageIndex } = this;
 const startIndex = pageIndex * PER_PAGE;
 const endIndex = startIndex + PER_PAGE;
 return filterJobList.slice(startIndex, endIndex);
 },
 pageLength() {
 const { filterJobList } = this;
 if (filterJobList.length) {
 return Math.ceil(filterJobList.length / PER_PAGE);
 }
 return 0;
 },
 },
 methods: {
 ...mapActions(['showAndHide']),
 // 操作 展开 隐藏
 showHandler(id) {
 this.showAndHide(id);
 },
 selectPageHandler(pageIndex) {
 this.$store.commit('setState', {
 pageIndex,
 });
 //同时关闭已经打开的职位详情页
 this.$store.commit('hideAllDetailMutations');
 },
 // 上一页
 prev() {
 this.$store.commit('prevMutations');
 },
 // 下一页
 next() {
 this.$store.commit('nextMutations', this.pageLength);
 },
 },
 mounted() {},
 components: {},
};
</script>

store/job.js

import { unique } from 'src/assets/script/util.js';
import jobData from 'src/views/job/data.js';

// 初始状态
const state = {
 realData: [],
 searchList: [],
 regionArr: [{
  name: '上海',
  id: 1,
 },
 {
  name: '武汉',
  id: 2,
 },
 ],
 // 右侧搜索,用户输入
 formData: {
 title: '', // 职位分类
 address: '', // 地区
 keywords: '', // 搜索更多职位
 },
 pageIndex: 0, // 第 0 页
 show: false, // 申请工作的 modal
 ApplyJobPosition: '' // 申请工作的职位
};

// 读取数据
const getters = {
 ApplyJobPosition: state => state.ApplyJobPosition,
 show: state => state.show,
 pageIndex: state => state.pageIndex,
 regionArr: state => state.regionArr,
 searchList: state => {
 const cache = [];
 state.realData.forEach(n => {
  cache.push(n.title);
 });
 return unique(cache);
 },
 // 符合条件的职位
 filterJobList({ realData, formData }) {
 const { title, address, keywords } = formData;

 return (
  realData
  // 职位筛选逻辑
  .filter(item => {
  let matchAddress = true; // 地区筛选
  let matchPosition = true; // 职位筛选
  let matchKeywrod = true; // 关键字 筛选
  if (title) {
   matchPosition = item.title === title;
  }
  if (address) {
   matchAddress = item.address === address;
  }
  if (keywords) {
   // 模糊搜索;
   const keys = keywords
   .toUpperCase() // 转大写
   .replace(' ', '') // 删掉空格
   .split(''); // 切割成 单个字

   matchKeywrod = keys.every(key => item.position.toUpperCase().includes(key));
  }
  return matchAddress && matchPosition && matchKeywrod;
  })
 );
 },
};

// 数据改变
const mutations = {

 // 从json文件直接获取元数据
 getDataMutations(state, jobData) {
 state.realData = jobData;
 },
 // 职位详情 显示/隐藏
 showAndHideMutations(state, id) {
 state.realData.forEach((n, i) => {
  if (id === n.id) {
  n.show = !n.show;
  }
 });
 },
 // 职位详情 全部隐藏
 hideAllDetailMutations(state) {
 state.realData.forEach((n, i) => {
  n.show = false;
 });
 },
 setState(state, payload = {}) {
 // console.log('payload', payload);
 Object.entries(payload).forEach(([key, value]) => {
  state[key] = value;
 });
 },
 // prev
 prevMutations(state, payload = {}) {
 if (!state.pageIndex) {
  return;
 }
 state.pageIndex--
 },
 // next
 nextMutations(state, payload = {}) {
 // console.info(state.pageIndex, payload)
 if (state.pageIndex < payload - 1) {
  state.pageIndex++
 }

 },
 // open modal
 openApplyJobModal(state, payload = {}) {
 state.show = true
 state.ApplyJobPosition = payload
 },
 //close modal
 closeApplyJobModal(state) {
 state.show = false
 },
};

// 逻辑响应
const actions = {
 getData({ commit }) {
 commit('getDataMutations', jobData);
 },
 // 显示 隐藏
 showAndHide({ commit }, id) {
 commit('showAndHideMutations', id);
 },
};

export default {
 state,
 getters,
 actions,
 mutations,
};

util.js

// 数组去重
export function unique(arr) {
 var newArr = [arr[0]];

 for (var i = 1; i < arr.length; i++) {


 if (newArr.indexOf(arr[i]) == -1) {
 newArr.push(arr[i]);
 }
 }
 return newArr;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
[原创]来自ImageSee官方 JavaScript图片浏览器
Jan 16 Javascript
JavaScript获取GridView选择的行内容
Apr 14 Javascript
Javascript中Eval函数的使用
Mar 23 Javascript
javascript中处理时间戳为日期格式的方法
Jan 02 Javascript
js获取下拉列表框中的value和text的值示例代码
Jan 11 Javascript
jQuery根据ID、CLASS、等获取对象的实例
Dec 04 Javascript
AngularJS实现的生成随机数与猜数字大小功能示例
Dec 25 Javascript
使用Vuex解决Vue中的身份验证问题
Sep 28 Javascript
VUE引入第三方js包及调用方法讲解
Mar 01 Javascript
Vue开发之封装分页组件与使用示例
Apr 25 Javascript
npm ci命令的基本使用方法
Sep 20 Javascript
vue css 相对路径导入问题级踩坑记录
Jun 05 Vue.js
js 将线性数据转为树形的示例代码
May 28 #Javascript
React中使用外部样式的3种方式(小结)
May 28 #Javascript
vue实现多条件和模糊搜索功能
May 28 #Javascript
vue实现路由切换改变title功能
May 28 #Javascript
Vue 无限滚动加载指令实现方法
May 28 #Javascript
vue实现搜索过滤效果
May 28 #Javascript
微信小程序 image组件遇到的问题
May 28 #Javascript
You might like
兼容各大浏览器带关闭按钮的漂浮多组图片广告代码
2014/06/05 PHP
CodeIgniter多语言实现方法详解
2016/01/20 PHP
PHP解压tar.gz格式文件的方法
2016/02/14 PHP
PHP的mysqli_rollback()函数讲解
2019/01/23 PHP
实现复选框全选/全不选切换
2006/12/23 Javascript
JAVASCRIPT keycode总结
2009/02/04 Javascript
关于UTF-8的客户端用AJAX方式获取GB2312的服务器端乱码问题的解决办法
2010/11/30 Javascript
倒记时60刷新网页的js代码
2014/02/18 Javascript
javascript和jquery实现设置和移除文本框默认值效果代码
2015/01/13 Javascript
AngularJS动态加载模块和依赖的方法分析
2016/11/08 Javascript
利用jQuery插件imgAreaSelect实现获得选择域的图像信息
2016/12/02 Javascript
jQuery EasyUi 验证功能实例解析
2017/01/06 Javascript
Node.js和Express简单入门介绍
2017/03/24 Javascript
使用jQuery.Pin垂直滚动时固定导航
2017/05/24 jQuery
laydate 显示结束时间不小于开始时间的实例
2017/08/11 Javascript
angular内置provider之$compileProvider详解
2017/09/27 Javascript
jquery实现左右轮播切换效果
2018/01/01 jQuery
新手快速上手webpack4打包工具的使用详解
2019/01/28 Javascript
彻底揭秘keep-alive原理(小结)
2019/05/05 Javascript
原生JS实现留言板
2020/03/26 Javascript
vue项目启动出现cannot GET /服务错误的解决方法
2020/04/26 Javascript
解决vue中使用less/sass及使用中遇到无效的问题
2020/10/24 Javascript
vue监听滚动事件的方法
2020/12/21 Vue.js
Selenium执行JavaScript脚本的方法示例
2020/12/31 Javascript
Python解释执行原理分析
2014/08/22 Python
python登录pop3邮件服务器接收邮件的方法
2015/04/30 Python
python 每天如何定时启动爬虫任务(实现方法分享)
2018/05/21 Python
python爬虫 基于requests模块发起ajax的get请求实现解析
2019/08/20 Python
python3实现从kafka获取数据,并解析为json格式,写入到mysql中
2019/12/23 Python
tensorflow的ckpt及pb模型持久化方式及转化详解
2020/02/12 Python
利用Python自动化操作AutoCAD的实现
2020/04/01 Python
纽约复古灵感的现代珠宝品牌:Lulu Frost
2018/03/03 全球购物
英国外籍人士的在线超市:British Corner Shop
2019/06/03 全球购物
2015年全国科普日活动总结
2015/03/23 职场文书
学校节水倡议书
2015/04/29 职场文书
KVM基础命令详解
2022/04/30 Servers