From e72677f19b20b3b5e51de881078861e972e717e0 Mon Sep 17 00:00:00 2001 From: Tevin <tingquanren@163.com> Date: Wed, 31 Mar 2021 19:18:36 +0800 Subject: [PATCH] 列表页筛选组件,第一部分 --- plugins/filter/CFilterSelect.vue | 72 ++++++++++++++ plugins/filter/index.js | 10 ++ plugins/filter/CFilter.vue | 94 ++++++++++++++++++ plugins/filter/cFilter.scss | 103 ++++++++++++++++++++ 4 files changed, 279 insertions(+), 0 deletions(-) diff --git a/plugins/filter/CFilter.vue b/plugins/filter/CFilter.vue new file mode 100644 index 0000000..62a0889 --- /dev/null +++ b/plugins/filter/CFilter.vue @@ -0,0 +1,94 @@ +/** + * CFilter - 页面筛选 + * @author Tevin + */ + +<template> + <view class="c-filter"> + <view + class="c-filter-bar" + v-if="bar" + > + <CFilterSelect + v-if="!bar.type || bar.type==='select'" + type="bar" + :label="bar.label" + :options="bar.options" + :onChange="evt=>handleChange(bar.name, evt)" + /> + </view> + <view + class="c-filter-more" + v-if="items && items.length > 0" + @tap="evt => drawerShow=true" + >更多筛选 »</view> + <AtDrawer + class="c-filter-drawer" + mask + right + :show="drawerShow" + :onClose="evt => drawerShow=false" + > + <scroll-view + class="c-filter-drawer-list" + :scrollY="true" + > + <view + class="box" + v-for="(item,index) of items" + :key="index" + > + <CFilterSelect + v-if="!item.type || item.type==='select'" + type="item" + :label="item.label" + :options="item.options" + :onChange="evt=>handleChange(item.name, evt)" + /> + </view> + </scroll-view> + <view class="c-filter-drawer-btn"> + 重置 完成 + </view> + </AtDrawer> + </view> +</template> + +<script> +import Taro from '@tarojs/taro'; +import { AtDrawer } from 'taro-ui-vue'; +import CFilterSelect from './CFilterSelect'; +import './cFilter.scss'; + +export default { + name: 'CFilter', + components: { + AtDrawer, + CFilterSelect, + }, + props: { + // 筛选横条 + bar: Object, + // 展开层筛选项目列表 + items: Array, + // 筛选变化时的回调 + onChange: Function, + }, + data() { + return { + filters: {}, + drawerShow: false, + }; + }, + methods: { + handleChange(name, value) { + if (typeof value === 'undefined') { + delete this.filters[name]; + } else { + this.filters[name] = value; + } + this.onChange(this.filters); + }, + }, +}; +</script> diff --git a/plugins/filter/CFilterSelect.vue b/plugins/filter/CFilterSelect.vue new file mode 100644 index 0000000..5c8aefe --- /dev/null +++ b/plugins/filter/CFilterSelect.vue @@ -0,0 +1,72 @@ +/** + * CFilterSelect - 筛选项目,单项选择 + * @author Tevin + */ + +<template> + <view + class="c-filter-select" + :class="'type-'+type" + > + <view + class="label" + v-if="type==='item'" + >{{label}}</view> + <picker + mode="selector" + range-key="name" + :range="options2" + @change="evt=>handleChange(evt.detail.value)" + > + <view class="content"> + <view + class="label" + v-if="type==='bar'" + > + {{label}}: + </view> + <view :class="selected ? 'value':'empty'"> + {{selected ? options2[selectIndex].name : ('请选择' + label)}} + </view> + <view class='at-icon at-icon-chevron-down' /> + </view> + </picker> + </view> +</template> + +<script> +import Taro from '@tarojs/taro'; + +export default { + name: 'CFilterSelect', + props: { + type: String, + label: String, + options: Array, + onChange: Function, + }, + data() { + return { + selectIndex: 0, + selected: false, + }; + }, + computed: { + options2() { + return [{ name: '- 取消选择 -' }, ...this.options]; + }, + }, + methods: { + handleChange(index) { + this.selectIndex = Number(index); + if (this.selectIndex > 0) { + this.selected = true; + this.onChange(this.options2[this.selectIndex].value); + } else { + this.selected = false; + this.onChange(); + } + }, + }, +}; +</script> \ No newline at end of file diff --git a/plugins/filter/cFilter.scss b/plugins/filter/cFilter.scss new file mode 100644 index 0000000..ccf34c4 --- /dev/null +++ b/plugins/filter/cFilter.scss @@ -0,0 +1,103 @@ +/** + * filter + * @author Tevin + */ + +@import "../../common/sassMixin"; + +.c-filter { + width: 100%; + height: 86px; + line-height: 86px; + font-size: 30px; + color: #666; + background-color: #fff; + border-top: 1px solid #eee; + .c-filter-bar { + float: left; + width: 550px; + height: 100%; + padding: 0 20px; + box-sizing: border-box; + } + .c-filter-more { + float: right; + width: 200px; + height: 100%; + box-sizing: border-box; + text-align: center; + border-left: 1PX solid #d6e4ef; + transition: background-color .3s; + &:active { + background-color: #f2f2f2; + } + } + .c-filter-drawer { + .at-drawer__content { + width: 550px; + } + .c-filter-drawer-list { + height: calc(100% - 90px); + border-top: 1PX solid #eee; + .box { + min-height: 20px; + padding: 30px 0 10px 30px; + border-bottom: 1PX solid #eee; + } + } + .c-filter-drawer-btn { + height: 90px; + } + } +} + +.c-filter-select { + .content { + @include flexbox(flex, flex-start center); + white-space: nowrap; + .empty, + .value { + display: inline-block; + vertical-align: middle; + @include ellipsis(); + } + .empty { + color: #ccc; + } + .value { + color: #6190e8; + } + .at-icon { + text-align: center; + color: #666; + } + } + &.type-bar { + .content { + height: 86px; + line-height: 1; + .label { + color: #666; + } + .at-icon { + vertical-align: middle; + } + } + } + &.type-item { + .label { + font-weight: bold; + color: #666; + line-height: 35px; + } + .content { + .empty, + .value { + flex: 6; + } + .at-icon { + flex: 1; + } + } + } +} \ No newline at end of file diff --git a/plugins/filter/index.js b/plugins/filter/index.js new file mode 100644 index 0000000..08669b4 --- /dev/null +++ b/plugins/filter/index.js @@ -0,0 +1,10 @@ +/** + * filters + * @author Tevin + */ + +import CFilter from '@components/plugins/filter/CFilter.vue'; + +export { + CFilter +} \ No newline at end of file -- Gitblit v1.9.1