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