guhongwei 3 年之前
父節點
當前提交
a92aa8ef44

+ 38 - 0
src/components/mobile-frame/foot.vue

@@ -0,0 +1,38 @@
+<template>
+  <div id="foot">
+    <van-tabbar route>
+      <van-tabbar-item v-for="(i, index) in menuList" :key="index" :to="i.index" :icon="i.icon">{{ i.name }}</van-tabbar-item>
+    </van-tabbar>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'foot',
+  props: {
+    menuList: { type: Array },
+  },
+  components: {},
+  data: function() {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 111 - 0
src/components/mobile-frame/mobile-main.vue

@@ -0,0 +1,111 @@
+<template>
+  <div id="mobile-main">
+    <van-row>
+      <van-col span="24" class="main" :style="{ height: client.height + 'px' }">
+        <van-col span="24" class="top" v-if="useTop">
+          <top :topType="topType" @search="topSearch" :leftArrow="leftArrow" @back="back" :rightArrow="rightArrow" @add="add">
+            <template v-slot:top>
+              <slot name="slotTop"></slot>
+            </template>
+          </top>
+        </van-col>
+        <van-col span="24" class="info" :style="{ height: getHeight() }">
+          <slot name="info"></slot>
+        </van-col>
+        <van-col span="24" class="page" v-if="usePage">
+          <page :limit="limit" :total="total" @search="search"></page>
+        </van-col>
+        <van-col span="24" class="foot" v-if="useNav"><foot :menuList="menuList"></foot></van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import top from './top.vue';
+import page from './page.vue';
+import foot from './foot.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'mobile-main',
+  props: {
+    // 头部
+    useTop: { type: Boolean, default: () => true },
+    topType: { type: String, default: () => '1' },
+    leftArrow: { type: Boolean, default: () => true },
+    rightArrow: { type: Boolean, default: () => true },
+    // 分页
+    usePage: { type: Boolean, default: () => true },
+    limit: { type: Number, default: () => 10 },
+    total: { type: Number, default: () => 0 },
+    // 底部菜单
+    useNav: { type: Boolean, default: () => true },
+  },
+  components: {
+    top,
+    page,
+    foot,
+  },
+  data: function() {
+    return {
+      client: {},
+      menuList: [
+        { name: '首页1', index: '/', icon: 'after-sale' },
+        { name: '首页2', index: '/index', icon: 'cart-o' },
+      ],
+    };
+  },
+  created() {},
+  methods: {
+    // 头部名称查询
+    topSearch(searchName) {
+      this.$emit('search', searchName);
+    },
+    // 分页查询
+    search(skip) {
+      this.$emit('search', skip);
+    },
+    // 返回
+    back() {
+      this.$emit('back');
+    },
+    // 添加
+    add() {
+      this.$emit('add');
+    },
+    // 计算中间高度
+    getHeight() {
+      let windowH = this.client.height;
+      if (this.useTop) windowH = windowH - 45;
+      else windowH = windowH - 0;
+      if (this.usePage) windowH = windowH - 40;
+      else windowH = windowH - 0;
+      if (this.useNav) windowH = windowH - 50;
+      else windowH = windowH - 0;
+      return windowH + 'px';
+    },
+  },
+  mounted() {
+    let client = {
+      height: document.documentElement.clientHeight || document.body.clientHeight,
+      width: document.documentElement.clientWidth || document.body.clientWidth,
+    };
+    this.$set(this, `client`, client);
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 43 - 0
src/components/mobile-frame/page.vue

@@ -0,0 +1,43 @@
+<template>
+  <div id="page">
+    <van-pagination v-model="currentPage" @change="changePage" :total-items="total" :items-per-page="limit" :show-page-size="5" force-ellipses />
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'page',
+  props: {
+    total: { type: Number },
+    limit: { type: Number, default: () => 6 },
+  },
+  components: {},
+  data: function() {
+    return {
+      currentPage: 1,
+    };
+  },
+  created() {},
+  methods: {
+    changePage(page) {
+      this.$emit('search', { skip: (page - 1) * this.limit });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 9 - 0
src/components/mobile-frame/top.md

@@ -0,0 +1,9 @@
+<!-- 头部类型 -->
+# topType
+## topType=="1" 只有查询 search
+
+## topType=="2" 带有返回,标题,添加,返回方法:back,添加方法:add
+
+## topType=="3" 带有返回和查询,返回方法:back,查询方法:search
+
+## topType=="4" 自定义 slotTop

+ 123 - 0
src/components/mobile-frame/top.vue

@@ -0,0 +1,123 @@
+<template>
+  <div id="top">
+    <van-row>
+      <van-col span="24" class="main">
+        <van-col span="24" class="common type_1" v-if="topType == '1'">
+          <van-search v-model="searchName" placeholder="请输入信息标题" @search="search" />
+        </van-col>
+        <van-col span="24" class="common type_2" v-else-if="topType == '2'">
+          <van-nav-bar :title="this.$route.meta.title">
+            <template #left>
+              <van-col span="24" v-if="leftArrow" @click="back" class="leftArrow">
+                <van-icon name="arrow-left" />
+                <span>返回</span>
+              </van-col>
+            </template>
+            <template #right>
+              <van-col span="24" v-if="rightArrow" @click="add"><van-icon name="plus"/></van-col>
+            </template>
+          </van-nav-bar>
+        </van-col>
+        <van-col span="24" class="common type_3" v-else-if="topType == '3'">
+          <van-col span="4" class="left" @click.native="back">
+            <van-icon name="arrow-left" />
+            <span>返回</span>
+          </van-col>
+          <van-col span="20" class="right">
+            <van-search v-model="searchName" placeholder="请输入信息标题" @search="search" />
+          </van-col>
+        </van-col>
+        <van-col span="24" class="common type_4" v-else-if="topType == '4'">
+          <slot name="top"></slot>
+        </van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'top',
+  props: {
+    topType: { typ: String },
+    leftArrow: { typ: Boolean },
+    rightArrow: { typ: Boolean },
+  },
+  components: {},
+  data: function() {
+    return {
+      searchName: '',
+    };
+  },
+  created() {},
+  methods: {
+    // 搜索
+    search() {
+      this.$emit('search', { searchName: this.searchName });
+    },
+    // 返回
+    back() {
+      this.$emit('back');
+    },
+    // 添加
+    add() {
+      this.$emit('add');
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .common {
+    height: 45px;
+    overflow: hidden;
+    border-bottom: 1px solid #f1f1f1;
+  }
+  .type_1 {
+    padding: 5px;
+    /deep/.van-search {
+      padding: 0;
+    }
+  }
+  .type_2 {
+    .leftArrow {
+      span {
+        color: #409eff;
+        position: relative;
+        top: -2px;
+      }
+    }
+  }
+  .type_3 {
+    padding: 5px;
+    /deep/.van-search {
+      padding: 0;
+    }
+    .left {
+      color: #409eff;
+      font-size: 15px;
+      text-align: center;
+      padding: 8px 0;
+      span {
+        position: relative;
+        top: -2px;
+      }
+    }
+  }
+}
+</style>