diff --git a/README.md b/README.md index 5e9fb9a..f5b9495 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# swzl +# swzl 曳光 ## Project setup ``` @@ -16,4 +16,4 @@ npm run build ``` ### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). +See [Configuration Reference](https://cli.vuejs.org/config/) diff --git a/src/router/index.js b/src/router/index.js index d1ca182..0927a45 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -13,6 +13,11 @@ const routes = [ path: '/account', name: 'Account', component: () => import(/* webpackChunkName: "account" */ '../views/Account/Account.vue') + }, + { + path: '/search', + name: 'Search', + component: () => import(/* webpackChunkName: "search" */ '../views/Search/Search.vue') }, { path: '*', // 页面不存在的情况下会跳到主页 diff --git a/src/views/Account/Account.vue b/src/views/Account/Account.vue index f1d90cd..56a11c4 100644 --- a/src/views/Account/Account.vue +++ b/src/views/Account/Account.vue @@ -213,6 +213,134 @@ export default { pwd: "", openid: "", created: [ + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, + { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }, { title: "这是丢失的物品", create_time: "2020-01-01", @@ -262,6 +390,81 @@ export default { good_id: "sdsdsd", type: 3 }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, + { + good_type: "lost", + good_id: "sdsdsd", + type: 4 + }, { good_type: "lost", good_id: "sdsdsd", diff --git a/src/views/Account/children/Created.vue b/src/views/Account/children/Created.vue index 935b8d5..3feb228 100644 --- a/src/views/Account/children/Created.vue +++ b/src/views/Account/children/Created.vue @@ -17,25 +17,40 @@ <v-spacer></v-spacer> </v-toolbar> - <v-sheet> - <v-container fluid> + <v-sheet class="fill-height overflow-y-auto"> + <v-container fluid style="padding-bottom: 100px;"> <v-row no-gutters> - <Card v-for="(item, i) in list" :key="i" :content="item"></Card> + <Card + v-for="(item, i) in list" + :key="i" + :content="item" + :openDetailSheet="openDetailSheet" + ></Card> </v-row> </v-container> </v-sheet> + <v-bottom-sheet v-model="detail_switch" persistent fullscreen @touchmove.prevent> + <Detail :closeBottomSheet="closeDetailSheet" :content="detail_content"></Detail> + </v-bottom-sheet> </v-sheet> </template> <script> // @ is an alias to /src import { mapState, mapActions } from "vuex"; -import Card from './Card' +import Card from '../../components/Card' +import Detail from "../../components/Detail"; + export default { name: "Created", props: ["closeBottomSheet", "list"], data: () => { return { + loading_switch: false, + // 详情窗口 + detail_switch: false, + // 详情内容 + detail_content: "" }; }, computed: { @@ -43,6 +58,16 @@ export default { }, methods: { init() {}, + // 关闭底部表单-detail + closeDetailSheet() { + this.detail_switch = false; + }, + + // 开启底部表单-detail + openDetailSheet(content) { + this.detail_switch = true; + this.detail_content = content; + }, }, created() { this.init(); @@ -50,7 +75,8 @@ export default { mounted() { }, components: { - Card + Card, + Detail } }; </script> diff --git a/src/views/Account/children/Message.vue b/src/views/Account/children/Message.vue index 87dce9a..4d4d30b 100644 --- a/src/views/Account/children/Message.vue +++ b/src/views/Account/children/Message.vue @@ -23,8 +23,8 @@ </v-btn> </v-toolbar> - <v-sheet> - <v-container fluid> + <v-sheet class="fill-height overflow-y-auto"> + <v-container fluid style="padding-bottom: 100px;"> <v-card class="ma-2 mb-5" shaped v-for="(item, i) in list" :key="i"> <v-list-item> <v-list-item-avatar> @@ -48,7 +48,9 @@ export default { name: "Message", props: ["closeBottomSheet", "list"], data: () => { - return {}; + return { + loading_switch:false, + }; }, computed: { ...mapState(["bg_img_url"]) diff --git a/src/views/Home/Home.vue b/src/views/Home/Home.vue index 1cd59c1..812e370 100644 --- a/src/views/Home/Home.vue +++ b/src/views/Home/Home.vue @@ -17,7 +17,7 @@ <v-spacer></v-spacer> <!-- 搜索icon --> - <v-btn icon @click="banner_switch = !banner_switch"> + <v-btn icon @click="goTo('/search')"> <v-icon>mdi-magnify</v-icon> </v-btn> @@ -68,7 +68,7 @@ <v-list-item-content> <v-list-item-title>设置</v-list-item-title> </v-list-item-content> - </v-list-item> --> + </v-list-item>--> <!-- 分享 --> <v-list-item v-ripple> @@ -104,7 +104,12 @@ <v-sheet v-show="page_type=='lost'"> <v-container fluid> <v-row no-gutters> - <Card v-for="(item, i) in found" :key="i" :content="item"></Card> + <Card + v-for="(item, i) in found" + :key="i" + :content="item" + :openDetailSheet="openDetailSheet" + ></Card> </v-row> </v-container> </v-sheet> @@ -113,14 +118,23 @@ <v-sheet v-show="page_type=='found'"> <v-container fluid> <v-row no-gutters> - <Card v-for="(item, i) in found" :key="i" :content="item"></Card> + <Card + v-for="(item, i) in found" + :key="i" + :content="item" + :openDetailSheet="openDetailSheet" + ></Card> </v-row> </v-container> </v-sheet> </v-sheet> <v-bottom-sheet v-model="add_switch" persistent fullscreen @touchmove.prevent> - <Add :closeBottomSheet="closeBottomSheet"></Add> + <Add :closeBottomSheet="closeAddSheet"></Add> + </v-bottom-sheet> + + <v-bottom-sheet v-model="detail_switch" persistent fullscreen> + <Detail v-if="detail_switch" :closeBottomSheet="closeDetailSheet" :content="detail_content" @touchmove.prevent></Detail> </v-bottom-sheet> <!-- 小圆纽 --> @@ -135,7 +149,8 @@ <script> // @ is an alias to /src import { mapState, mapActions } from "vuex"; -import Card from "./children/Card"; +import Card from "../components/Card"; +import Detail from "../components/Detail"; import Add from "./children/Add"; export default { name: "Home", @@ -150,7 +165,11 @@ export default { // 未登录banner banner_switch: false, // 新建窗口 - add_switch: false + add_switch: false, + // 详情窗口 + detail_switch: false, + // 详情内容 + detail_content: "" }; }, computed: { @@ -158,28 +177,39 @@ export default { }, methods: { init() { - let item = { - title: "这是丢失的物品", - create_time: "2020-01-01", - img_url: "https://picsum.photos/1920/1080?random", - total_addr: "长理东区", - good_type: "lost", - good_id: "1111" - }; for (let i = 0; i < 10; i++) { + let item = { + title: "这是丢失的物品", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: i + }; this.lost.push(item); this.found.push(item); } }, // 关闭底部表单-add - closeBottomSheet() { + closeAddSheet() { this.add_switch = false; }, + // 关闭底部表单-detail + closeDetailSheet() { + this.detail_switch = false; + }, + + // 开启底部表单-detail + openDetailSheet(content) { + this.detail_switch = true; + this.detail_content = content; + }, + // 跳转到某页 goTo(route) { - this.$router.push(route) + this.$router.push(route); }, // 设置空白占位的高度 @@ -205,7 +235,8 @@ export default { }, components: { Card, - Add + Add, + Detail } }; </script> diff --git a/src/views/Home/children/Card.vue b/src/views/Home/children/Card.vue deleted file mode 100644 index 11b54b7..0000000 --- a/src/views/Home/children/Card.vue +++ /dev/null @@ -1,25 +0,0 @@ -<template> - <v-col cols="6" xs="6" sm="6" md="4" lg="3"> - <v-card class="ma-2" raised> - <v-img - :src="content.img_url" - gradient="to bottom, rgba(0,0,0,.1), rgba(0,0,0,.5)" - :aspect-ratio="16/9" - ></v-img> - - <v-list-item> - <v-list-item-content> - <p class="subtitle-2">{{content.title}}</p> - <div class="caption">{{content.total_addr}} {{content.create_time}}</div> - </v-list-item-content> - </v-list-item> - </v-card> - </v-col> -</template> - -<script> -export default { - name: "Card", - props: ["content"] -}; -</script> \ No newline at end of file diff --git a/src/views/Search/Search.vue b/src/views/Search/Search.vue new file mode 100644 index 0000000..8be7dff --- /dev/null +++ b/src/views/Search/Search.vue @@ -0,0 +1,206 @@ +<template> + <v-app id="home-app"> + <!-- 标题栏 --> + <v-app-bar dark :src="bg_img_url" app relative> + <!-- 图片遮罩 --> + <template v-slot:img="{ props }"> + <v-img v-bind="props" gradient="to top right, rgba(0,0,0,0.3), rgba(0,0,0,0.4)"></v-img> + </template> + + <!-- 返回按钮 --> + <v-btn icon @click="back()"> + <v-icon>mdi-arrow-left</v-icon> + </v-btn> + + <!-- 搜索框 --> + <v-autocomplete + v-model="search_content" + :items="titles" + class="mx-4" + flat + hide-no-data + hide-details + label="在此搜索标题" + solo-inverted + dense + ></v-autocomplete> + + <!-- 拓展插槽 --> + <template v-slot:extension> + <!-- 切换卡 --> + <v-tabs grow> + <v-tab @click="page_type = 'lost'">失物</v-tab> + <v-tab @click="page_type = 'found'">招领</v-tab> + </v-tabs> + </template> + </v-app-bar> + + <v-sheet class="fill-height"> + <!-- 空白占位 --> + <div id="sheets"></div> + + <!-- 卡片阵列 --> + <v-container fluid> + <v-row no-gutters> + <Card + v-for="(item, i) in show_list" + :key="i" + :content="item" + :openDetailSheet="openDetailSheet" + ></Card> + </v-row> + </v-container> + + <v-bottom-sheet v-model="detail_switch" persistent fullscreen @touchmove.prevent> + <Detail :closeBottomSheet="closeDetailSheet" :content="detail_content"></Detail> + </v-bottom-sheet> + </v-sheet> + </v-app> +</template> + +<script> +// @ is an alias to /src +import { mapState, mapActions } from "vuex"; +import Card from "../components/Card"; +import Detail from "../components/Detail"; + +export default { + name: "Search", + data: () => { + return { + // 搜索内容 + search_content: "", + // + titles: [], + show_list: [], + lost_titles: [], + found_titles: [], + lost: [], + found: [], + page_type: "lost", + // 详情窗口 + detail_switch: false, + // 详情内容 + detail_content: "" + }; + }, + computed: { + ...mapState(["bg_img_url"]) + }, + methods: { + init() { + for (let i = 0; i < 10; i++) { + let item = { + title: "d", + create_time: "2020-01-01", + img_url: "https://picsum.photos/1920/1080?random", + total_addr: "长理东区", + good_type: "lost", + good_id: "1111" + }; + this.lost.push(item); + this.found.push(item); + } + this.separateTitle(); + this.show_list = this.lost; + }, + + // 分离标题 + separateTitle() { + for (let i of this.lost) { + this.lost_titles.push(i.title); + } + console.log("失物标题分离完成"); + for (let i of this.found) { + this.found_titles.push(i.title); + } + console.log("招领标题分离完成"); + this.titles = this.lost_titles; + }, + + // 模糊搜索 + fuzzySearch() { + // 空内容拦截器,显示全部 + let search_content = this.search_content.toString(); + if (!search_content.trim()) { + this.show_list = this.page_type == "lost" ? this.lost : this.found; + console.log(`空内容搜索,已拦截,覆写${this.page_type}表`); + return; + } + let data_list = []; + for (let item of this.page_type == "lost" ? this.lost : this.found) { + if (this.generReg(search_content.trim()).test(item.title)) { + data_list.push(item); + } + } + this.show_list = data_list; + console.log("模糊搜索已完成"); + }, + + // 模糊搜索辅助轮 + generReg(val) { + let head = "(.*)("; + let tail = ")(.*)"; + let body = val.split("").join(")(.*)("); + return new RegExp(head + body + tail, "i"); + }, + + // 返回上一界面 + back() { + this.$router.go(-1); + }, + + // 设置空白占位的高度 + resetSheetHeight() { + // 设置空白高度 + document.getElementById( + "sheets" + ).style.height = document.getElementsByTagName("header")[0].style.height; + console.log("空白占位高度设置完成"); + }, + + // 关闭底部表单-detail + closeDetailSheet() { + this.detail_switch = false; + }, + + // 开启底部表单-detail + openDetailSheet(content) { + this.detail_switch = true; + this.detail_content = content; + } + }, + created() { + this.init(); + }, + mounted() { + // 设置空白占位的高度 + this.resetSheetHeight(); + // 屏幕变化的时候也更新高度 + window.onresize = function temp() { + console.log("屏幕大小发生改变"); + this.resetSheetHeight(); + }.bind(this); + }, + watch: { + // 如果 `search_content` 发生改变,这个函数就会运行 + search_content: function() { + this.fuzzySearch(); + }, + page_type: function() { + let search_content = this.search_content; + this.titles = + this.page_type == "lost" ? this.lost_titles : this.found_titles; + this.search_content = search_content; + this.fuzzySearch(); + } + }, + components: { + Card, + Detail + } +}; +</script> + +<style lang="scss" scoped> +</style> \ No newline at end of file diff --git a/src/views/Account/children/Card.vue b/src/views/components/Card.vue similarity index 83% rename from src/views/Account/children/Card.vue rename to src/views/components/Card.vue index 11b54b7..fbf212a 100644 --- a/src/views/Account/children/Card.vue +++ b/src/views/components/Card.vue @@ -1,6 +1,6 @@ <template> <v-col cols="6" xs="6" sm="6" md="4" lg="3"> - <v-card class="ma-2" raised> + <v-card class="ma-2" raised @click="openDetailSheet(content)"> <v-img :src="content.img_url" gradient="to bottom, rgba(0,0,0,.1), rgba(0,0,0,.5)" @@ -20,6 +20,6 @@ <script> export default { name: "Card", - props: ["content"] + props: ["content", "openDetailSheet"] }; </script> \ No newline at end of file diff --git a/src/views/components/Detail.vue b/src/views/components/Detail.vue new file mode 100644 index 0000000..975577d --- /dev/null +++ b/src/views/components/Detail.vue @@ -0,0 +1,134 @@ +<template> + <v-sheet class="fill-height"> + <!-- 标题栏 --> + <v-toolbar dark :src="bg_img_url"> + <!-- 图片遮罩 --> + <template v-slot:img="{ props }"> + <v-img v-bind="props" gradient="to top right, rgba(0,0,0,0.3), rgba(0,0,0,0.4)"></v-img> + </template> + + <!-- 关闭按钮 --> + <v-btn icon @click="closeBottomSheet" :disabled="loading_switch"> + <v-icon>mdi-close</v-icon> + </v-btn> + + <!-- 标题 --> + <v-toolbar-title>详情</v-toolbar-title> + + <v-spacer></v-spacer> + + <!-- 评论 --> + <v-btn icon @click="closeBottomSheet" :disabled="loading_switch"> + <v-icon>mdi-comment-text-outline</v-icon> + </v-btn> + + <!-- 删除 --> + <v-btn icon @click="closeBottomSheet" :disabled="loading_switch"> + <v-icon>mdi-delete</v-icon> + </v-btn> + </v-toolbar> + + <v-sheet class="fill-height overflow-y-auto"> + <v-container relative> + <v-card raised> + <v-img src="https://cdn.vuetifyjs.com/images/cards/docks.jpg"></v-img> + <v-card-title>{{current.title}}</v-card-title> + <v-card-subtitle>{{current.create_time}}</v-card-subtitle> + <v-card-text>{{current.content}}</v-card-text> + <v-card-text>{{current.total_addr}} - {{current.detail_addr}}</v-card-text> + <v-card-text v-if="current.contact_content">联系方式 - {{current.contact_content}}</v-card-text> + </v-card> + </v-container> + <v-container style="padding-bottom: 100px;"> + <p class="subtitle-1">评论区</p> + <v-row no-gutters> + <v-col cols="6" xs="6" sm="6" md="4" lg="3"> + <v-card shaped class="ma-2"> + <v-card-title>{{current.user_info.nick}}</v-card-title> + <v-card-subtitle>{{current.create_time}}</v-card-subtitle> + <v-card-text>{{current.content}}</v-card-text> + </v-card> + </v-col> + <v-col cols="6" xs="6" sm="6" md="4" lg="3"> + <v-card shaped class="ma-2"> + <v-card-title>{{current.user_info.nick}}</v-card-title> + <v-card-subtitle>{{current.create_time}}</v-card-subtitle> + <v-card-text>{{current.content}}</v-card-text> + </v-card> + </v-col> + <v-col cols="6" xs="6" sm="6" md="4" lg="3"> + <v-card shaped class="ma-2"> + <v-card-title>{{current.user_info.nick}}</v-card-title> + <v-card-subtitle>{{current.create_time}}</v-card-subtitle> + <v-card-text>{{current.content}}</v-card-text> + </v-card> + </v-col> + <v-col cols="6" xs="6" sm="6" md="4" lg="3"> + <v-card shaped class="ma-2"> + <v-card-title>{{current.user_info.nick}}</v-card-title> + <v-card-subtitle>{{current.create_time}}</v-card-subtitle> + <v-card-text>{{current.content}}</v-card-text> + </v-card> + </v-col> + <v-col cols="6" xs="6" sm="6" md="4" lg="3"> + <v-card shaped class="ma-2"> + <v-card-title>{{current.user_info.nick}}</v-card-title> + <v-card-subtitle>{{current.create_time}}</v-card-subtitle> + <v-card-text>{{current.content}}</v-card-text> + </v-card> + </v-col> + </v-row> + + </v-container> + </v-sheet> + </v-sheet> +</template> + +<script> +// @ is an alias to /src +import { mapState, mapActions } from "vuex"; +export default { + name: "Detail", + props: ["closeBottomSheet", "content"], + data: () => { + return { + loading_switch: false, + current: null + }; + }, + computed: { + ...mapState(["bg_img_url"]) + }, + methods: { + init() { + this.current = { + title: "我是挺长的一段标题", + content: + "我是内容我是内容我是内容我是内容我是内容我是内容我是内容我是内容", + create_time: "2020-01-02", + img_url: this.bg_img_url, + total_addr: "长理东区", + detail_addr: "南研楼1213", + contact_content: "d", + good_type: "lost", + good_id: "1234", + comment: [], + user_info: { + nick: "嘤嘤嘤", + openid: "12345" + } + }; + } + }, + created() { + this.init(); + }, + activated() { + console.log("activated"); + }, + mounted() {} +}; +</script> + +<style lang="scss" scoped> +</style> \ No newline at end of file