其他分享
首页 > 其他分享> > .NET经销商实战(十二)——优化用户体验,完善产品列表查询

.NET经销商实战(十二)——优化用户体验,完善产品列表查询

作者:互联网

商品列表查询时,查询条件显示在url后面

1.在商品列表页面中引入useRouter()

代码如下:
import { useRouter,useRoute } from 'vue-router'
var router = useRouter()
var route = useRoute()

2.前端查询方法代码如下:

点击查看代码
search: async () => {
        clearTimeout(productInfo.timer)
        productInfo.timer = setTimeout(async () => {
          router.push(`productList?keyword=${productInfo.searchText}`)
          // productInfo.products = await getProduct({
          //   searchText: productInfo.searchText,
          //   systemNo: productInfo.systemIndex,
          //   productType: productInfo.typeSelected,
          //   sort: 'ProductName',
          //   pageIndex: 1,
          // })
        }, 1000)
      },

3.ProductList.vue完整代码如下:

点击查看代码
<template>
  <div>
    <div class="search-pad">
      <input
        v-model="searchText"
        type="text"
        name=""
        id=""
        @focus="searchFocus()"
        @blur="searchBlur()"
        @input="search"
      />
      <button v-show="isShowSearchBtn">搜索</button>
      <button v-show="!isShowSearchBtn" @click="showRight()">筛选</button>
    </div>
    <div class="system-pad">
      <div
        v-for="belongType in belongTypes"
        :key="belongType.sysNo"
        :class="[
          'system-item',
          { 'system-select': systemIndex == belongType.sysNo },
        ]"
        @click="getSystemProduct(belongType.sysNo)"
      >
        <span>{{ belongType.belongTypeName }}</span>
      </div>
    </div>
    <div class="product-list">
      <ul>
        <li v-for="product in products" :key="product.id">
          <img :src="product.productPhoto?.productPhotoUrl" alt="" />
          <div>
            <p class="p-name">{{ product.productName }}</p>
            <p class="p-type">类别:{{ product.typeName }}</p>
            <p class="p-price">
              &yen;{{ tranPrice(product.productSale?.salePrice) }}/张
            </p>
          </div>
        </li>
      </ul>

      <div :class="['left-menu', { 'left-menu-show': isShowLeft }]">
        <div class="left-switch" @click="showLeft()">
          <img src="/img/dealerImgs/up.png" alt="" />
        </div>
        <ul>
          <li
            v-for="productType in productTypes"
            :key="productType.typeNo"
            @click="selectType(productType.typeNo)"
            :class="{ 'left-item-select': typeSelected == productType.typeNo }"
          >
            {{ productType.typeName }}
          </li>
        </ul>
      </div>
    </div>
    <div class="right-pad">
      <div class="list-pad">
        <ul class="f-type-list">
          <template v-for="(values, key) in productProps">
            <li v-if="values.length > 0" :key="key">
              <p>{{ formatKey(key) }}</p>
              <ul class="f-item-list">
                <li v-for="value in values" :key="value">
                  <span>{{ value }}</span>
                </li>
                <!-- <li><span class="prop-select">胡桃色</span></li> -->
              </ul>
              <div class="clear-tag"></div>
            </li>
          </template>
        </ul>
      </div>
      <div class="right-edit">
        <button
          @click="confirmFilter()"
          style="background-color: rgb(188, 0, 0); color: #fff"
        >
          确定
        </button>
        <button @click="hideRight()">取消</button>
      </div>
    </div>
    <div class="cover" v-show="isShowCover" @click="hideRight()"></div>
  </div>
</template>

<script lang="ts">
import { ref, onMounted, reactive, toRefs } from 'vue'
import {
  getProduct,
  getBelongType,
  getProductType,
  getProps,
} from '@/httpRequests/ProductListRequest'
import { IProductInfo } from '@/Interfaces/ProductList'
import { useRouter, useRoute } from 'vue-router'
import router from '@/router'

export default {
  setup() {
    var router = useRouter()
    var route = useRoute()
    const pageController = reactive({
      isShowLeft: ref(false),
      isShowCover: ref(false),
      isShowSearchBtn: ref(false),
    })
    //IProductInfo
    const productInfo: IProductInfo = reactive({
      systemIndex: '1',
      products: [],
      belongTypes: [],
      productTypes: [],
      typeSelected: '',
      searchText: '',
      productProps: {},
      timer: 0,
      /**
       * 获取物品
       */
      getProducts: async (
        systemIndex: string,
        productType: string | null = null,
        searchText: string | null
      ) => {
        productInfo.products = await getProduct({
          searchText: searchText,
          systemNo: systemIndex,
          productType: productType,
          sort: 'ProductName',
          pageIndex: 1,
        })

        console.log(productInfo.products)
      },
      tranPrice: (price: number) => {
        if (price == null) {
          return '0.00'
        } else {
          return price.toFixed(2).toString()
        }
      },
      getBelongType: async () => {
        productInfo.belongTypes = await getBelongType()
        console.log(productInfo.belongTypes)
      },
      //
      getProductType: async (sysNo: string) => {
        productInfo.productTypes = await getProductType(sysNo)
      },
      //增加注释
      getSystemProduct: async (index: string) => {
        productInfo.typeSelected = null
        productInfo.systemIndex = index
        await productInfo.getProducts(index, null, null)
        await productInfo.getProductType(index)
        await productInfo.getProps(index, null)
      },
      getProps: async (belongTypeNo: string, typeNo: string | null = null) => {
        console.log('belongTypeNo:' + belongTypeNo)
        var res = await getProps({ belongTypeNo, typeNo })
        productInfo.productProps = res
        console.log(res)
      },
      formatKey: (key: string) => {
        return key.split('|')[1]
      },
      selectType: async (typeNo: string) => {
        if (productInfo.typeSelected == typeNo) {
          productInfo.typeSelected = ''
        } else {
          productInfo.typeSelected = typeNo
        }

        await productInfo.getProducts(
          productInfo.systemIndex,
          productInfo.typeSelected,
          null
        )
        console.log('productInfo.typeSelected: ' + productInfo.typeSelected)
      },
      search: async () => {
        clearTimeout(productInfo.timer)
        productInfo.timer = setTimeout(async () => {
          router.push(`productList?keyword=${productInfo.searchText}`)
          // productInfo.products = await getProduct({
          //   searchText: productInfo.searchText,
          //   systemNo: productInfo.systemIndex,
          //   productType: productInfo.typeSelected,
          //   sort: 'ProductName',
          //   pageIndex: 1,
          // })
        }, 1000)
      },
    })

    const showLeft = () => {
      pageController.isShowLeft = !pageController.isShowLeft
    }
    const searchFocus = () => {
      pageController.isShowSearchBtn = true
    }
    const searchBlur = () => {
      pageController.isShowSearchBtn = false
    }
    const confirmFilter = () => {}
    const showRight = () => {
      pageController.isShowCover = true
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '0'
    }
    const hideRight = () => {
      pageController.isShowCover = false
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '-85%'
    }
    //解析地址
    let keyword: string | null = ''
    const resoluationAddress = () => {
      keyword = route.query.keyword as string
      console.log(keyword)
    }
    onMounted(async () => {
      resoluationAddress()
      await productInfo.getProducts('bc', null, keyword)
      await productInfo.getBelongType()
      await productInfo.getProductType('1')
      await productInfo.getProps('1', null)
    })
    return {
      ...toRefs(pageController),
      ...toRefs(productInfo),
      showLeft,
      searchFocus,
      searchBlur,
      confirmFilter,
      showRight,
      hideRight,
    }
  },
}
</script>

<style lang="scss" scoped>
.i-search:after {
  background-color: #b70101 !important;
}

.search-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  padding: 6px 20px;
  background-color: #f0f0f0;
  display: flex;

  input {
    height: 28px;
    box-sizing: border-box;
    border: 1px solid #ddd;
    border-radius: 3px;
    flex: 1;
    outline: none;
  }

  button {
    background-color: transparent;
    width: 56px;
    border: 0 none;
    font-size: 14px;
    font-weight: bold;
    color: #333;
    outline: none;
  }
}

.system-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  top: 40px;
  background-color: #fff;
  display: flex;

  .system-item {
    flex: 1;
    text-align: center;
    border-bottom: 1px #ddd solid;
    border-right: 1px transparent solid;
    border-left: 1px transparent solid;

    span {
      border: 0 none !important;
      background-color: #f0f2f5;
      margin: 6px 5px;
      font-size: 12px;
      font-weight: normal;
      text-align: center;
      border-radius: 4px;
      padding: 6px 0;
      display: block;
      height: 20px;
      line-height: 12px;
    }
  }

  .system-select {
    border-bottom: 1px transparent solid;
    border-right: 1px #ddd solid;
    border-left: 1px #ddd solid;

    span {
      background-color: transparent;
    }
  }
}

.product-list {
  padding-top: 75px;
  ul {
    background-color: #fff;

    li {
      list-style: none;
      height: 88px;
      padding-left: 108px;
      position: relative;

      img {
        height: 66px;
        width: 66px;
        background-color: #ccc;
        position: absolute;
        left: 28px;
        top: 11px;
      }

      div {
        padding: 10px 0;
        border-bottom: 1px solid #f0f0f0;
        padding-bottom: 12px;
        text-align-last: left;
        .p-name {
          font-size: 13px;
        }

        .p-type {
          font-size: 12px;
          color: #666;
          margin-top: 8px;
        }

        .p-price {
          font-size: 13px;
          color: #f23030;
          margin-top: 8px;
        }
      }
    }
  }

  .left-menu {
    position: fixed;
    height: calc(100% - 116px);
    left: -106px;
    width: 125px;
    background-color: #fff;
    top: 76px;
    border-radius: 0 18px 0 0;
    border: 1px solid #d7d7d7;
    overflow: hidden;
    transition: 0.5s;
    margin-bottom: 120px;

    .left-switch {
      width: 20px;
      background-color: #fff;
      position: absolute;
      right: 0;
      height: 100%;

      img {
        position: absolute;
        top: 42%;
        left: 2px;
        width: 20px;
        transform: rotate(90deg);
        transition: 0.5s;
      }
    }

    ul {
      position: absolute;
      height: 100%;
      width: 106px;
      background-color: #f0f0f0;
      overflow: auto;

      li {
        width: 106px;
        height: 50px;
        text-align: center;
        line-height: 50px;
        border-bottom: 1px solid #d7d7d7;
        padding: 0;
        font-size: 12px;
        color: #333;
      }

      li.left-item-select {
        background-color: #fff;
      }
    }
  }

  .left-menu-show {
    left: 0;

    .left-switch {
      img {
        transform: rotate(-90deg);
      }
    }
  }
}

.right-pad {
  position: fixed;
  /* right: -85%; */
  right: -85%;
  top: 0;
  width: 85%;
  height: 100%;
  background-color: #f7f7f7;
  z-index: 103;
  transition: 580ms;
  z-index: 101;

  ul {
    list-style: none;
    overflow: hidden;
  }
  .list-pad {
    overflow: auto;
    height: 100%;
    padding-bottom: 40px;
    .f-type-list {
      overflow: hidden;

      > li {
        padding: 10px;
        background-color: #fff;
        margin-bottom: 10px;

        .f-item-list {
          overflow: auto;
          display: flex;
          flex-wrap: wrap;

          li {
            flex-basis: 33.3%;

            span {
              display: block;
              margin-top: 10px;
              margin-right: 10px;
              background: #eee;
              border: 1px solid #eee;
              padding: 5px 0;
              text-align: center;
              border-radius: 6px;
              font-size: 13px;
              overflow: hidden;
              height: 39px;
            }

            .prop-select {
              border: 1px solid red;
              background: #fff;
              color: red;
            }
          }
        }

        p {
          font-size: 14px;
        }
      }
    }
  }
  .right-edit {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;

    button {
      float: left;
      height: 40px;
      width: 50%;
      line-height: 40px;
      text-align: center;
      border: 0px none;
    }
  }
}

.cover {
  position: fixed;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  background-color: rgba(51, 51, 51, 0.36);
  z-index: 11;
}
</style>

4.修改Layout.vue代码如下:

埋种子

点击查看代码
<template>
  <div>
    <router-view :key="key" />
    <div class="foot-menu-pad">
      <div class="foot-menu">
        <router-link to="/productList" v-slot="{ navigate }" custom>
          <div class="foot-item" @click="navigate">
            <b :class="['i-search', 'f-menu-sel']"></b>
          </div>
        </router-link>
        <router-link to="/shoppingCart" v-slot="{ navigate }" custom>
          <div class="foot-item" @click="navigate">
            <b :class="['i-cart', 'f-menu-sel']">
              <i>58</i>
            </b>
          </div>
        </router-link>
        <router-link to="/main" v-slot="{ navigate }" custom>
          <div class="foot-item" @click="navigate">
            <b :class="['i-user', 'f-menu-sel']"></b>
          </div>
        </router-link>
      </div>
    </div>
  </div>
</template>

<script>
import { ref } from 'vue'
export default {
  setup() {
    const key = ref(Date.now())
    return key
  },
}
</script>

<style lang="scss" scoped>
.foot-menu-pad {
  height: 40px;

  .foot-menu {
    position: fixed;
    height: 40px;
    background-color: #fff;
    width: 100%;
    left: 0;
    bottom: 0;
    display: flex;

    .foot-item {
      flex: 1;
      text-align: center;
      height: 40px;
      line-height: 40px;
      position: relative;

      b {
        background-color: #acacac;
        width: 26px;
        height: 26px;
        background-size: 16px;
        background-repeat: no-repeat;
        background-position: center;
        border-radius: 13px;
        margin-top: 6px;
        display: inline-block;
        position: relative;

        i {
          position: absolute;
          font-size: 12px;
          color: #fff;
          // background-color: red;
          padding: 1px 3px;
          text-align: center;
          font-style: normal;
          display: inline;
          top: -5px;
          right: -12px;
          border-radius: 12px;
          line-height: 12px;
          font-weight: normal;
        }
      }

      b.i-search {
        background-image: require('/img/icons-png/search-white.png');
      }

      b.i-cart {
        background-image: require('/img/icons-png/shoppingCar-white.png');
      }

      b.i-user {
        background-image: require('/img/icons-png/user-white.png');
      }

      .f-menu-sel {
        background-color: #b70101;
      }
    }
  }
}
</style>

5.输入搜索框你要搜索的内容进行立刻刷新

商品列表代码如下:

点击查看代码
<template>
  <div>
    <div class="search-pad">
      <input
        v-model="searchText"
        type="text"
        name=""
        id=""
        @focus="searchFocus()"
        @blur="searchBlur()"
        @input="search"
      />
      <button v-show="isShowSearchBtn">搜索</button>
      <button v-show="!isShowSearchBtn" @click="showRight()">筛选</button>
    </div>
    <div class="system-pad">
      <div
        v-for="belongType in belongTypes"
        :key="belongType.sysNo"
        :class="[
          'system-item',
          { 'system-select': systemIndex == belongType.sysNo },
        ]"
        @click="getSystemProduct(belongType.sysNo)"
      >
        <span>{{ belongType.belongTypeName }}</span>
      </div>
    </div>
    <div class="product-list">
      <ul>
        <li v-for="product in products" :key="product.id">
          <img :src="product.productPhoto?.productPhotoUrl" alt="" />
          <div>
            <p class="p-name">{{ product.productName }}</p>
            <p class="p-type">类别:{{ product.typeName }}</p>
            <p class="p-price">
              &yen;{{ tranPrice(product.productSale?.salePrice) }}/张
            </p>
          </div>
        </li>
      </ul>

      <div :class="['left-menu', { 'left-menu-show': isShowLeft }]">
        <div class="left-switch" @click="showLeft()">
          <img src="/img/dealerImgs/up.png" alt="" />
        </div>
        <ul>
          <li
            v-for="productType in productTypes"
            :key="productType.typeNo"
            @click="selectType(productType.typeNo)"
            :class="{ 'left-item-select': typeSelected == productType.typeNo }"
          >
            {{ productType.typeName }}
          </li>
        </ul>
      </div>
    </div>
    <div class="right-pad">
      <div class="list-pad">
        <ul class="f-type-list">
          <template v-for="(values, key) in productProps">
            <li v-if="values.length > 0" :key="key">
              <p>{{ formatKey(key) }}</p>
              <ul class="f-item-list">
                <li v-for="value in values" :key="value">
                  <span>{{ value }}</span>
                </li>
                <!-- <li><span class="prop-select">胡桃色</span></li> -->
              </ul>
              <div class="clear-tag"></div>
            </li>
          </template>
        </ul>
      </div>
      <div class="right-edit">
        <button
          @click="confirmFilter()"
          style="background-color: rgb(188, 0, 0); color: #fff"
        >
          确定
        </button>
        <button @click="hideRight()">取消</button>
      </div>
    </div>
    <div class="cover" v-show="isShowCover" @click="hideRight()"></div>
  </div>
</template>

<script lang="ts">
import { ref, onMounted, reactive, toRefs } from 'vue'
import {
  getProduct,
  getBelongType,
  getProductType,
  getProps,
} from '@/httpRequests/ProductListRequest'
import { IProductInfo } from '@/Interfaces/ProductList'
import { useRouter, useRoute } from 'vue-router'
import router from '@/router'

export default {
  setup() {
    var router = useRouter()
    var route = useRoute()
    const pageController = reactive({
      isShowLeft: ref(false),
      isShowCover: ref(false),
      isShowSearchBtn: ref(false),
    })
    //IProductInfo
    const productInfo: IProductInfo = reactive({
      systemIndex: '1',
      products: [],
      belongTypes: [],
      productTypes: [],
      typeSelected: '',
      searchText: '',
      productProps: {},
      timer: 0,
      /**
       * 获取物品
       */
      getProducts: async (
        systemIndex: string,
        productType: string | null = null,
        searchText: string | null
      ) => {
        productInfo.products = await getProduct({
          searchText: searchText,
          systemNo: systemIndex,
          productType: productType,
          sort: 'ProductName',
          pageIndex: 1,
        })

        console.log(productInfo.products)
      },
      tranPrice: (price: number) => {
        if (price == null) {
          return '0.00'
        } else {
          return price.toFixed(2).toString()
        }
      },
      getBelongType: async () => {
        productInfo.belongTypes = await getBelongType()
        console.log(productInfo.belongTypes)
      },
      //
      getProductType: async (sysNo: string) => {
        productInfo.productTypes = await getProductType(sysNo)
      },
      //增加注释
      getSystemProduct: async (index: string) => {
        productInfo.typeSelected = null
        productInfo.systemIndex = index
        await productInfo.getProducts(index, null, null)
        await productInfo.getProductType(index)
        await productInfo.getProps(index, null)
      },
      getProps: async (belongTypeNo: string, typeNo: string | null = null) => {
        console.log('belongTypeNo:' + belongTypeNo)
        var res = await getProps({ belongTypeNo, typeNo })
        productInfo.productProps = res
        console.log(res)
      },
      formatKey: (key: string) => {
        return key.split('|')[1]
      },
      selectType: async (typeNo: string) => {
        if (productInfo.typeSelected == typeNo) {
          productInfo.typeSelected = ''
        } else {
          productInfo.typeSelected = typeNo
        }

        await productInfo.getProducts(
          productInfo.systemIndex,
          productInfo.typeSelected,
          null
        )
        console.log('productInfo.typeSelected: ' + productInfo.typeSelected)
      },
      search: async () => {
        clearTimeout(productInfo.timer)
        productInfo.timer = setTimeout(async () => {
          router.push(`/productList?keyword=${productInfo.searchText}`)
          // location.href = `/productList?keyword=${productInfo.searchText}`
          // productInfo.products = await getProduct({
          //   searchText: productInfo.searchText,
          //   systemNo: productInfo.systemIndex,
          //   productType: productInfo.typeSelected,
          //   sort: 'ProductName',
          //   pageIndex: 1,
          // })
        }, 1000)
      },
    })

    const showLeft = () => {
      pageController.isShowLeft = !pageController.isShowLeft
    }
    const searchFocus = () => {
      pageController.isShowSearchBtn = true
    }
    const searchBlur = () => {
      pageController.isShowSearchBtn = false
    }
    const confirmFilter = () => {}
    const showRight = () => {
      pageController.isShowCover = true
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '0'
    }
    const hideRight = () => {
      pageController.isShowCover = false
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '-85%'
    }
    //解析地址
    let keyword: string | null = ''
    const resoluationAddress = () => {
      keyword = route.query.keyword as string
      console.log(keyword)
    }
    onMounted(async () => {
      resoluationAddress()
      await productInfo.getProducts('1', null, keyword)
      await productInfo.getBelongType()
      await productInfo.getProductType('1')
      await productInfo.getProps('1', null)
    })
    return {
      ...toRefs(pageController),
      ...toRefs(productInfo),
      showLeft,
      searchFocus,
      searchBlur,
      confirmFilter,
      showRight,
      hideRight,
    }
  },
}
</script>

<style lang="scss" scoped>
.i-search:after {
  background-color: #b70101 !important;
}

.search-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  padding: 6px 20px;
  background-color: #f0f0f0;
  display: flex;

  input {
    height: 28px;
    box-sizing: border-box;
    border: 1px solid #ddd;
    border-radius: 3px;
    flex: 1;
    outline: none;
  }

  button {
    background-color: transparent;
    width: 56px;
    border: 0 none;
    font-size: 14px;
    font-weight: bold;
    color: #333;
    outline: none;
  }
}

.system-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  top: 40px;
  background-color: #fff;
  display: flex;

  .system-item {
    flex: 1;
    text-align: center;
    border-bottom: 1px #ddd solid;
    border-right: 1px transparent solid;
    border-left: 1px transparent solid;

    span {
      border: 0 none !important;
      background-color: #f0f2f5;
      margin: 6px 5px;
      font-size: 12px;
      font-weight: normal;
      text-align: center;
      border-radius: 4px;
      padding: 6px 0;
      display: block;
      height: 20px;
      line-height: 12px;
    }
  }

  .system-select {
    border-bottom: 1px transparent solid;
    border-right: 1px #ddd solid;
    border-left: 1px #ddd solid;

    span {
      background-color: transparent;
    }
  }
}

.product-list {
  padding-top: 75px;
  ul {
    background-color: #fff;

    li {
      list-style: none;
      height: 88px;
      padding-left: 108px;
      position: relative;

      img {
        height: 66px;
        width: 66px;
        background-color: #ccc;
        position: absolute;
        left: 28px;
        top: 11px;
      }

      div {
        padding: 10px 0;
        border-bottom: 1px solid #f0f0f0;
        padding-bottom: 12px;
        text-align-last: left;
        .p-name {
          font-size: 13px;
        }

        .p-type {
          font-size: 12px;
          color: #666;
          margin-top: 8px;
        }

        .p-price {
          font-size: 13px;
          color: #f23030;
          margin-top: 8px;
        }
      }
    }
  }

  .left-menu {
    position: fixed;
    height: calc(100% - 116px);
    left: -106px;
    width: 125px;
    background-color: #fff;
    top: 76px;
    border-radius: 0 18px 0 0;
    border: 1px solid #d7d7d7;
    overflow: hidden;
    transition: 0.5s;
    margin-bottom: 120px;

    .left-switch {
      width: 20px;
      background-color: #fff;
      position: absolute;
      right: 0;
      height: 100%;

      img {
        position: absolute;
        top: 42%;
        left: 2px;
        width: 20px;
        transform: rotate(90deg);
        transition: 0.5s;
      }
    }

    ul {
      position: absolute;
      height: 100%;
      width: 106px;
      background-color: #f0f0f0;
      overflow: auto;

      li {
        width: 106px;
        height: 50px;
        text-align: center;
        line-height: 50px;
        border-bottom: 1px solid #d7d7d7;
        padding: 0;
        font-size: 12px;
        color: #333;
      }

      li.left-item-select {
        background-color: #fff;
      }
    }
  }

  .left-menu-show {
    left: 0;

    .left-switch {
      img {
        transform: rotate(-90deg);
      }
    }
  }
}

.right-pad {
  position: fixed;
  /* right: -85%; */
  right: -85%;
  top: 0;
  width: 85%;
  height: 100%;
  background-color: #f7f7f7;
  z-index: 103;
  transition: 580ms;
  z-index: 101;

  ul {
    list-style: none;
    overflow: hidden;
  }
  .list-pad {
    overflow: auto;
    height: 100%;
    padding-bottom: 40px;
    .f-type-list {
      overflow: hidden;

      > li {
        padding: 10px;
        background-color: #fff;
        margin-bottom: 10px;

        .f-item-list {
          overflow: auto;
          display: flex;
          flex-wrap: wrap;

          li {
            flex-basis: 33.3%;

            span {
              display: block;
              margin-top: 10px;
              margin-right: 10px;
              background: #eee;
              border: 1px solid #eee;
              padding: 5px 0;
              text-align: center;
              border-radius: 6px;
              font-size: 13px;
              overflow: hidden;
              height: 39px;
            }

            .prop-select {
              border: 1px solid red;
              background: #fff;
              color: red;
            }
          }
        }

        p {
          font-size: 14px;
        }
      }
    }
  }
  .right-edit {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;

    button {
      float: left;
      height: 40px;
      width: 50%;
      line-height: 40px;
      text-align: center;
      border: 0px none;
    }
  }
}

.cover {
  position: fixed;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  background-color: rgba(51, 51, 51, 0.36);
  z-index: 11;
}
</style>

6.优化产品类型查询

商品列表代码如下:

点击查看代码
<template>
  <div>
    <div class="search-pad">
      <input
        v-model="searchText"
        type="text"
        name=""
        id=""
        @focus="searchFocus()"
        @blur="searchBlur()"
        @input="search"
      />
      <button v-show="isShowSearchBtn">搜索</button>
      <button v-show="!isShowSearchBtn" @click="showRight()">筛选</button>
    </div>
    <div class="system-pad">
      <div
        v-for="belongType in belongTypes"
        :key="belongType.sysNo"
        :class="[
          'system-item',
          { 'system-select': systemIndex == belongType.sysNo },
        ]"
        @click="getSystemProduct(belongType.sysNo)"
      >
        <span>{{ belongType.belongTypeName }}</span>
      </div>
    </div>
    <div class="product-list">
      <ul>
        <li v-for="product in products" :key="product.id">
          <img :src="product.productPhoto?.productPhotoUrl" alt="" />
          <div>
            <p class="p-name">{{ product.productName }}</p>
            <p class="p-type">类别:{{ product.typeName }}</p>
            <p class="p-price">
              &yen;{{ tranPrice(product.productSale?.salePrice) }}/张
            </p>
          </div>
        </li>
      </ul>

      <div :class="['left-menu', { 'left-menu-show': isShowLeft }]">
        <div class="left-switch" @click="showLeft()">
          <img src="/img/dealerImgs/up.png" alt="" />
        </div>
        <ul>
          <li
            v-for="productType in productTypes"
            :key="productType.typeNo"
            @click="selectType(productType.typeNo)"
            :class="{ 'left-item-select': typeSelected == productType.typeNo }"
          >
            {{ productType.typeName }}
          </li>
        </ul>
      </div>
    </div>
    <div class="right-pad">
      <div class="list-pad">
        <ul class="f-type-list">
          <template v-for="(values, key) in productProps">
            <li v-if="values.length > 0" :key="key">
              <p>{{ formatKey(key) }}</p>
              <ul class="f-item-list">
                <li v-for="value in values" :key="value">
                  <span>{{ value }}</span>
                </li>
                <!-- <li><span class="prop-select">胡桃色</span></li> -->
              </ul>
              <div class="clear-tag"></div>
            </li>
          </template>
        </ul>
      </div>
      <div class="right-edit">
        <button
          @click="confirmFilter()"
          style="background-color: rgb(188, 0, 0); color: #fff"
        >
          确定
        </button>
        <button @click="hideRight()">取消</button>
      </div>
    </div>
    <div class="cover" v-show="isShowCover" @click="hideRight()"></div>
  </div>
</template>

<script lang="ts">
import { ref, onMounted, reactive, toRefs } from 'vue'
import {
  getProduct,
  getBelongType,
  getProductType,
  getProps,
} from '@/httpRequests/ProductListRequest'
import { IProductInfo } from '@/Interfaces/ProductList'
import { useRouter, useRoute } from 'vue-router'
import router from '@/router'

export default {
  setup() {
    var router = useRouter()
    var route = useRoute()
    const pageController = reactive({
      isShowLeft: ref(false),
      isShowCover: ref(false),
      isShowSearchBtn: ref(false),
    })
    //IProductInfo
    const productInfo: IProductInfo = reactive({
      systemIndex: '1',
      products: [],
      belongTypes: [],
      productTypes: [],
      typeSelected: '',
      searchText: '',
      productProps: {},
      timer: 0,
      /**
       * 获取物品
       */
      getProducts: async (
        systemIndex: string,
        productType: string | null = null,
        searchText: string | null
      ) => {
        productInfo.products = await getProduct({
          searchText: searchText,
          systemNo: systemIndex,
          productType: productType,
          sort: 'ProductName',
          pageIndex: 1,
        })

        console.log(productInfo.products)
      },
      tranPrice: (price: number) => {
        if (price == null) {
          return '0.00'
        } else {
          return price.toFixed(2).toString()
        }
      },
      getBelongType: async () => {
        productInfo.belongTypes = await getBelongType()
        console.log(productInfo.belongTypes)
      },
      //
      getProductType: async (sysNo: string) => {
        productInfo.productTypes = await getProductType(sysNo)
      },
      //增加注释
      /**
       * 点击大类时我们不需要考虑搜索的内容,因为每次点击大类,都应该清空搜索框
       * 但是搜索物品时,就应该考虑大类
       *
       */
      getSystemProduct: async (index: string) => {
        router.push(`/productList?belongType=${index}`)
        // productInfo.typeSelected = null
        // productInfo.systemIndex = index
        // await productInfo.getProducts(index, null, null)
        // await productInfo.getProductType(index)
        // await productInfo.getProps(index, null)
      },
      getProps: async (belongTypeNo: string, typeNo: string | null = null) => {
        console.log('belongTypeNo:' + belongTypeNo)
        var res = await getProps({ belongTypeNo, typeNo })
        productInfo.productProps = res
        console.log(res)
      },
      formatKey: (key: string) => {
        return key.split('|')[1]
      },
      selectType: async (typeNo: string) => {
        if (productInfo.typeSelected == typeNo) {
          productInfo.typeSelected = ''
        } else {
          productInfo.typeSelected = typeNo
        }

        await productInfo.getProducts(
          productInfo.systemIndex,
          productInfo.typeSelected,
          null
        )
        console.log('productInfo.typeSelected: ' + productInfo.typeSelected)
      },
      search: async () => {
        clearTimeout(productInfo.timer)
        productInfo.timer = setTimeout(async () => {
          router.push(
            `/productList?belongType=${productInfo.systemIndex}&keyword=${productInfo.searchText}`
          )
          // location.href = `/productList?keyword=${productInfo.searchText}`
          // productInfo.products = await getProduct({
          //   searchText: productInfo.searchText,
          //   systemNo: productInfo.systemIndex,
          //   productType: productInfo.typeSelected,
          //   sort: 'ProductName',
          //   pageIndex: 1,
          // })
        }, 1000)
      },
    })

    const showLeft = () => {
      pageController.isShowLeft = !pageController.isShowLeft
    }
    const searchFocus = () => {
      pageController.isShowSearchBtn = true
    }
    const searchBlur = () => {
      pageController.isShowSearchBtn = false
    }
    const confirmFilter = () => {}
    const showRight = () => {
      pageController.isShowCover = true
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '0'
    }
    const hideRight = () => {
      pageController.isShowCover = false
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '-85%'
    }
    //解析地址
    let keyword: string | null = ''
    let systemIndex: string = ''
    const resoluationAddress = () => {
      keyword = route.query.keyword as string
      productInfo.systemIndex = systemIndex =
        (route.query.belongType as string) ?? '1'
      console.log(systemIndex)
    }
    onMounted(async () => {
      resoluationAddress()
      await productInfo.getProducts(systemIndex, null, keyword)
      await productInfo.getBelongType()
      await productInfo.getProductType(systemIndex)
      await productInfo.getProps(systemIndex, null)
    })
    return {
      ...toRefs(pageController),
      ...toRefs(productInfo),
      showLeft,
      searchFocus,
      searchBlur,
      confirmFilter,
      showRight,
      hideRight,
    }
  },
}
</script>

<style lang="scss" scoped>
.i-search:after {
  background-color: #b70101 !important;
}

.search-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  padding: 6px 20px;
  background-color: #f0f0f0;
  display: flex;

  input {
    height: 28px;
    box-sizing: border-box;
    border: 1px solid #ddd;
    border-radius: 3px;
    flex: 1;
    outline: none;
  }

  button {
    background-color: transparent;
    width: 56px;
    border: 0 none;
    font-size: 14px;
    font-weight: bold;
    color: #333;
    outline: none;
  }
}

.system-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  top: 40px;
  background-color: #fff;
  display: flex;

  .system-item {
    flex: 1;
    text-align: center;
    border-bottom: 1px #ddd solid;
    border-right: 1px transparent solid;
    border-left: 1px transparent solid;

    span {
      border: 0 none !important;
      background-color: #f0f2f5;
      margin: 6px 5px;
      font-size: 12px;
      font-weight: normal;
      text-align: center;
      border-radius: 4px;
      padding: 6px 0;
      display: block;
      height: 20px;
      line-height: 12px;
    }
  }

  .system-select {
    border-bottom: 1px transparent solid;
    border-right: 1px #ddd solid;
    border-left: 1px #ddd solid;

    span {
      background-color: transparent;
    }
  }
}

.product-list {
  padding-top: 75px;
  ul {
    background-color: #fff;

    li {
      list-style: none;
      height: 88px;
      padding-left: 108px;
      position: relative;

      img {
        height: 66px;
        width: 66px;
        background-color: #ccc;
        position: absolute;
        left: 28px;
        top: 11px;
      }

      div {
        padding: 10px 0;
        border-bottom: 1px solid #f0f0f0;
        padding-bottom: 12px;
        text-align-last: left;
        .p-name {
          font-size: 13px;
        }

        .p-type {
          font-size: 12px;
          color: #666;
          margin-top: 8px;
        }

        .p-price {
          font-size: 13px;
          color: #f23030;
          margin-top: 8px;
        }
      }
    }
  }

  .left-menu {
    position: fixed;
    height: calc(100% - 116px);
    left: -106px;
    width: 125px;
    background-color: #fff;
    top: 76px;
    border-radius: 0 18px 0 0;
    border: 1px solid #d7d7d7;
    overflow: hidden;
    transition: 0.5s;
    margin-bottom: 120px;

    .left-switch {
      width: 20px;
      background-color: #fff;
      position: absolute;
      right: 0;
      height: 100%;

      img {
        position: absolute;
        top: 42%;
        left: 2px;
        width: 20px;
        transform: rotate(90deg);
        transition: 0.5s;
      }
    }

    ul {
      position: absolute;
      height: 100%;
      width: 106px;
      background-color: #f0f0f0;
      overflow: auto;

      li {
        width: 106px;
        height: 50px;
        text-align: center;
        line-height: 50px;
        border-bottom: 1px solid #d7d7d7;
        padding: 0;
        font-size: 12px;
        color: #333;
      }

      li.left-item-select {
        background-color: #fff;
      }
    }
  }

  .left-menu-show {
    left: 0;

    .left-switch {
      img {
        transform: rotate(-90deg);
      }
    }
  }
}

.right-pad {
  position: fixed;
  /* right: -85%; */
  right: -85%;
  top: 0;
  width: 85%;
  height: 100%;
  background-color: #f7f7f7;
  z-index: 103;
  transition: 580ms;
  z-index: 101;

  ul {
    list-style: none;
    overflow: hidden;
  }
  .list-pad {
    overflow: auto;
    height: 100%;
    padding-bottom: 40px;
    .f-type-list {
      overflow: hidden;

      > li {
        padding: 10px;
        background-color: #fff;
        margin-bottom: 10px;

        .f-item-list {
          overflow: auto;
          display: flex;
          flex-wrap: wrap;

          li {
            flex-basis: 33.3%;

            span {
              display: block;
              margin-top: 10px;
              margin-right: 10px;
              background: #eee;
              border: 1px solid #eee;
              padding: 5px 0;
              text-align: center;
              border-radius: 6px;
              font-size: 13px;
              overflow: hidden;
              height: 39px;
            }

            .prop-select {
              border: 1px solid red;
              background: #fff;
              color: red;
            }
          }
        }

        p {
          font-size: 14px;
        }
      }
    }
  }
  .right-edit {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;

    button {
      float: left;
      height: 40px;
      width: 50%;
      line-height: 40px;
      text-align: center;
      border: 0px none;
    }
  }
}

.cover {
  position: fixed;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  background-color: rgba(51, 51, 51, 0.36);
  z-index: 11;
}
</style>

7.产品左侧菜单栏查询优化

代码如下:

点击查看代码
<template>
  <div>
    <div class="search-pad">
      <input
        v-model="searchText"
        type="text"
        name=""
        id=""
        @focus="searchFocus()"
        @blur="searchBlur()"
        @input="search"
      />
      <button v-show="isShowSearchBtn">搜索</button>
      <button v-show="!isShowSearchBtn" @click="showRight()">筛选</button>
    </div>
    <div class="system-pad">
      <div
        v-for="belongType in belongTypes"
        :key="belongType.sysNo"
        :class="[
          'system-item',
          { 'system-select': systemIndex == belongType.sysNo },
        ]"
        @click="getSystemProduct(belongType.sysNo)"
      >
        <span>{{ belongType.belongTypeName }}</span>
      </div>
    </div>
    <div class="product-list">
      <ul>
        <li v-for="product in products" :key="product.id">
          <img :src="product.productPhoto?.productPhotoUrl" alt="" />
          <div>
            <p class="p-name">{{ product.productName }}</p>
            <p class="p-type">类别:{{ product.typeName }}</p>
            <p class="p-price">
              &yen;{{ tranPrice(product.productSale?.salePrice) }}/张
            </p>
          </div>
        </li>
      </ul>

      <div :class="['left-menu', { 'left-menu-show': isShowLeft }]">
        <div class="left-switch" @click="showLeft()">
          <img src="/img/dealerImgs/up.png" alt="" />
        </div>
        <ul>
          <li
            v-for="productType in productTypes"
            :key="productType.typeNo"
            @click="selectType(productType.typeNo)"
            :class="{ 'left-item-select': typeSelected == productType.typeNo }"
          >
            {{ productType.typeName }}
          </li>
        </ul>
      </div>
    </div>
    <div class="right-pad">
      <div class="list-pad">
        <ul class="f-type-list">
          <template v-for="(values, key) in productProps">
            <li v-if="values.length > 0" :key="key">
              <p>{{ formatKey(key) }}</p>
              <ul class="f-item-list">
                <li v-for="value in values" :key="value">
                  <span>{{ value }}</span>
                </li>
                <!-- <li><span class="prop-select">胡桃色</span></li> -->
              </ul>
              <div class="clear-tag"></div>
            </li>
          </template>
        </ul>
      </div>
      <div class="right-edit">
        <button
          @click="confirmFilter()"
          style="background-color: rgb(188, 0, 0); color: #fff"
        >
          确定
        </button>
        <button @click="hideRight()">取消</button>
      </div>
    </div>
    <div class="cover" v-show="isShowCover" @click="hideRight()"></div>
  </div>
</template>

<script lang="ts">
import { ref, onMounted, reactive, toRefs } from 'vue'
import {
  getProduct,
  getBelongType,
  getProductType,
  getProps,
} from '@/httpRequests/ProductListRequest'
import { IProductInfo } from '@/Interfaces/ProductList'
import { useRouter, useRoute } from 'vue-router'
import router from '@/router'

export default {
  setup() {
    var router = useRouter()
    var route = useRoute()
    const pageController = reactive({
      isShowLeft: ref(false),
      isShowCover: ref(false),
      isShowSearchBtn: ref(false),
    })
    //IProductInfo
    const productInfo: IProductInfo = reactive({
      systemIndex: '1',
      products: [],
      belongTypes: [],
      productTypes: [],
      typeSelected: '',
      searchText: '',
      productProps: {},
      timer: 0,
      /**
       * 获取物品
       */
      getProducts: async (
        systemIndex: string,
        productType: string | null = null,
        searchText: string | null
      ) => {
        productInfo.products = await getProduct({
          searchText: searchText,
          systemNo: systemIndex,
          productType: productType,
          sort: 'ProductName',
          pageIndex: 1,
        })

        console.log(productInfo.products)
      },
      tranPrice: (price: number) => {
        if (price == null) {
          return '0.00'
        } else {
          return price.toFixed(2).toString()
        }
      },
      getBelongType: async () => {
        productInfo.belongTypes = await getBelongType()
        console.log(productInfo.belongTypes)
      },
      //
      getProductType: async (sysNo: string) => {
        productInfo.productTypes = await getProductType(sysNo)
      },
      /**
       * 点击大类时我们不需要考虑搜索的内容,因为每次点击大类,都应该清空搜索框
       * 但是搜索物品时,就应该考虑大类
       *
       */
      getSystemProduct: async (index: string) => {
        router.push(`/productList?belongType=${index}`)
      },
      getProps: async (belongTypeNo: string, typeNo: string | null = null) => {
        console.log('belongTypeNo:' + belongTypeNo)
        var res = await getProps({ belongTypeNo, typeNo })
        productInfo.productProps = res
        console.log(res)
      },
      formatKey: (key: string) => {
        return key.split('|')[1]
      },
      selectType: async (typeNo: string) => {
        var url = `/productList?belongType=${productInfo.systemIndex}`
        if (productInfo.typeSelected != typeNo) {
          url += `&type=${typeNo}`
        }

        router.push(url)
        // await productInfo.getProducts(
        //   productInfo.systemIndex,
        //   productInfo.typeSelected,
        //   null
        // )
        console.log('productInfo.typeSelected: ' + productInfo.typeSelected)
      },
      search: async () => {
        clearTimeout(productInfo.timer)
        productInfo.timer = setTimeout(async () => {
          var url = `/productList?belongType=${productInfo.systemIndex}`
          if (productInfo.searchText?.trim() != '') {
            url += `&keyword=${productInfo.searchText}`
          }
          if (productInfo.typeSelected?.trim() != '') {
            url += `&type=${productInfo.typeSelected}`
          }
          router.push(url)
        }, 1000)
      },
    })

    const showLeft = () => {
      pageController.isShowLeft = !pageController.isShowLeft
    }
    const searchFocus = () => {
      pageController.isShowSearchBtn = true
    }
    const searchBlur = () => {
      pageController.isShowSearchBtn = false
    }
    const confirmFilter = () => {}
    const showRight = () => {
      pageController.isShowCover = true
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '0'
    }
    const hideRight = () => {
      pageController.isShowCover = false
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '-85%'
    }
    //解析地址
    let keyword: string | null = ''
    let systemIndex: string = ''
    let typeSelected: string = ''
    const resoluationAddress = () => {
      keyword = (route.query.keyword as string) ?? ''
      productInfo.systemIndex = systemIndex =
        (route.query.belongType as string) ?? '1'
      productInfo.typeSelected = typeSelected =
        (route.query.type as string) ?? ''
      console.log(systemIndex)
    }
    onMounted(async () => {
      resoluationAddress()
      await productInfo.getProducts(systemIndex, typeSelected, keyword)
      await productInfo.getBelongType()
      await productInfo.getProductType(systemIndex)
      await productInfo.getProps(systemIndex, typeSelected)
    })
    return {
      ...toRefs(pageController),
      ...toRefs(productInfo),
      showLeft,
      searchFocus,
      searchBlur,
      confirmFilter,
      showRight,
      hideRight,
    }
  },
}
</script>

<style lang="scss" scoped>
.i-search:after {
  background-color: #b70101 !important;
}

.search-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  padding: 6px 20px;
  background-color: #f0f0f0;
  display: flex;

  input {
    height: 28px;
    box-sizing: border-box;
    border: 1px solid #ddd;
    border-radius: 3px;
    flex: 1;
    outline: none;
  }

  button {
    background-color: transparent;
    width: 56px;
    border: 0 none;
    font-size: 14px;
    font-weight: bold;
    color: #333;
    outline: none;
  }
}

.system-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  top: 40px;
  background-color: #fff;
  display: flex;

  .system-item {
    flex: 1;
    text-align: center;
    border-bottom: 1px #ddd solid;
    border-right: 1px transparent solid;
    border-left: 1px transparent solid;

    span {
      border: 0 none !important;
      background-color: #f0f2f5;
      margin: 6px 5px;
      font-size: 12px;
      font-weight: normal;
      text-align: center;
      border-radius: 4px;
      padding: 6px 0;
      display: block;
      height: 20px;
      line-height: 12px;
    }
  }

  .system-select {
    border-bottom: 1px transparent solid;
    border-right: 1px #ddd solid;
    border-left: 1px #ddd solid;

    span {
      background-color: transparent;
    }
  }
}

.product-list {
  padding-top: 75px;
  ul {
    background-color: #fff;

    li {
      list-style: none;
      height: 88px;
      padding-left: 108px;
      position: relative;

      img {
        height: 66px;
        width: 66px;
        background-color: #ccc;
        position: absolute;
        left: 28px;
        top: 11px;
      }

      div {
        padding: 10px 0;
        border-bottom: 1px solid #f0f0f0;
        padding-bottom: 12px;
        text-align-last: left;
        .p-name {
          font-size: 13px;
        }

        .p-type {
          font-size: 12px;
          color: #666;
          margin-top: 8px;
        }

        .p-price {
          font-size: 13px;
          color: #f23030;
          margin-top: 8px;
        }
      }
    }
  }

  .left-menu {
    position: fixed;
    height: calc(100% - 116px);
    left: -106px;
    width: 125px;
    background-color: #fff;
    top: 76px;
    border-radius: 0 18px 0 0;
    border: 1px solid #d7d7d7;
    overflow: hidden;
    transition: 0.5s;
    margin-bottom: 120px;

    .left-switch {
      width: 20px;
      background-color: #fff;
      position: absolute;
      right: 0;
      height: 100%;

      img {
        position: absolute;
        top: 42%;
        left: 2px;
        width: 20px;
        transform: rotate(90deg);
        transition: 0.5s;
      }
    }

    ul {
      position: absolute;
      height: 100%;
      width: 106px;
      background-color: #f0f0f0;
      overflow: auto;

      li {
        width: 106px;
        height: 50px;
        text-align: center;
        line-height: 50px;
        border-bottom: 1px solid #d7d7d7;
        padding: 0;
        font-size: 12px;
        color: #333;
      }

      li.left-item-select {
        background-color: #fff;
      }
    }
  }

  .left-menu-show {
    left: 0;

    .left-switch {
      img {
        transform: rotate(-90deg);
      }
    }
  }
}

.right-pad {
  position: fixed;
  /* right: -85%; */
  right: -85%;
  top: 0;
  width: 85%;
  height: 100%;
  background-color: #f7f7f7;
  z-index: 103;
  transition: 580ms;
  z-index: 101;

  ul {
    list-style: none;
    overflow: hidden;
  }
  .list-pad {
    overflow: auto;
    height: 100%;
    padding-bottom: 40px;
    .f-type-list {
      overflow: hidden;

      > li {
        padding: 10px;
        background-color: #fff;
        margin-bottom: 10px;

        .f-item-list {
          overflow: auto;
          display: flex;
          flex-wrap: wrap;

          li {
            flex-basis: 33.3%;

            span {
              display: block;
              margin-top: 10px;
              margin-right: 10px;
              background: #eee;
              border: 1px solid #eee;
              padding: 5px 0;
              text-align: center;
              border-radius: 6px;
              font-size: 13px;
              overflow: hidden;
              height: 39px;
            }

            .prop-select {
              border: 1px solid red;
              background: #fff;
              color: red;
            }
          }
        }

        p {
          font-size: 14px;
        }
      }
    }
  }
  .right-edit {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;

    button {
      float: left;
      height: 40px;
      width: 50%;
      line-height: 40px;
      text-align: center;
      border: 0px none;
    }
  }
}

.cover {
  position: fixed;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  background-color: rgba(51, 51, 51, 0.36);
  z-index: 11;
}
</style>

8.抽离search方法,抽离出setRouter方法:

点击查看代码
search: async () => {
        clearTimeout(productInfo.timer)
        productInfo.timer = setTimeout(async () => {
          setRouter()
        }, 1000)
      },

const setRouter = () => {
      var url = `/productList?belongType=${productInfo.systemIndex}`
      if (productInfo.searchText?.trim() != '') {
        url += `&keyword=${productInfo.searchText}`
      }
      if (productInfo.typeSelected?.trim() != '') {
        url += `&type=${productInfo.typeSelected}`
      }
      router.push(url)
    }

9.selectType方法更新如下:

productList.vue代码如下:

点击查看代码
selectType: async (typeNo: string) => {
        if (productInfo.typeSelected != typeNo) {
          productInfo.typeSelected = typeNo
        }

        setRouter()
        // await productInfo.getProducts(
        //   productInfo.systemIndex,
        //   productInfo.typeSelected,
        //   null
        // )
        console.log('productInfo.typeSelected: ' + productInfo.typeSelected)
      },

10.为左侧筛选框增加样式

点击查看代码
<template>
  <div>
    <!-- 搜索面板 -->
    <div class="search-pad">
      <input
        v-model="searchText"
        type="text"
        name=""
        id=""
        @focus="searchFocus()"
        @blur="searchBlur()"
        @input="search"
      />
      <button v-show="isShowSearchBtn">搜索</button>
      <button v-show="!isShowSearchBtn" @click="showRight()">筛选</button>
    </div>
    <!-- 物品大类面板 -->
    <div class="system-pad">
      <div
        v-for="belongType in belongTypes"
        :key="belongType.sysNo"
        :class="[
          'system-item',
          { 'system-select': systemIndex == belongType.sysNo },
        ]"
        @click="getSystemProduct(belongType.sysNo)"
      >
        <span>{{ belongType.belongTypeName }}</span>
      </div>
    </div>
    <!-- 物品展示列表 -->
    <div class="product-list">
      <ul>
        <li v-for="product in products" :key="product.id">
          <img :src="product.productPhoto?.productPhotoUrl" alt="" />
          <div>
            <p class="p-name">{{ product.productName }}</p>
            <p class="p-type">类别:{{ product.typeName }}</p>
            <p class="p-price">
              &yen;{{ tranPrice(product.productSale?.salePrice) }}/张
            </p>
          </div>
        </li>
      </ul>
      <!-- 左边物品类型面板 -->
      <div :class="['left-menu', { 'left-menu-show': isShowLeft }]">
        <div class="left-switch" @click="showLeft()">
          <img src="/img/dealerImgs/up.png" alt="" />
        </div>
        <ul>
          <li
            v-for="productType in productTypes"
            :key="productType.typeNo"
            @click="selectType(productType.typeNo)"
            :class="{ 'left-item-select': typeSelected == productType.typeNo }"
          >
            {{ productType.typeName }}
          </li>
        </ul>
      </div>
    </div>
    <!-- 右边物品属性面板 -->
    <div class="right-pad">
      <div class="list-pad">
        <ul class="f-type-list">
          <template v-for="(values, key) in productProps">
            <li v-if="values.length > 0" :key="key">
              <p>{{ getPropKey(key, 1) }}</p>
              <ul class="f-item-list">
                <li
                  v-for="value in values"
                  :key="value"
                  @click="selectProp(getPropKey(key, 0), value)"
                >
                  <span
                    :class="{
                      'prop-select': propSelect[getPropKey(key, 0)] == value,
                    }"
                    >{{ value }}</span
                  >
                </li>
                <!-- <li><span class="prop-select">胡桃色</span></li> -->
              </ul>
              <div class="clear-tag"></div>
            </li>
          </template>
        </ul>
      </div>
      <div class="right-edit">
        <button
          @click="confirmFilter()"
          style="background-color: rgb(188, 0, 0); color: #fff"
        >
          确定
        </button>
        <button @click="hideRight()">取消</button>
      </div>
    </div>
    <div class="cover" v-show="isShowCover" @click="hideRight()"></div>
  </div>
</template>

<script lang="ts">
import { ref, onMounted, reactive, toRefs } from 'vue'
import {
  getProduct,
  getBelongType,
  getProductType,
  getProps,
} from '@/httpRequests/ProductListRequest'
import { IProductInfo } from '@/Interfaces/ProductList'
import { useRouter, useRoute } from 'vue-router'
import router from '@/router'

export default {
  setup() {
    var router = useRouter()
    var route = useRoute()
    const pageController = reactive({
      isShowLeft: ref(false),
      isShowCover: ref(false),
      isShowSearchBtn: ref(false),
    })
    //IProductInfo
    const productInfo: IProductInfo = reactive({
      systemIndex: '1',
      products: [],
      belongTypes: [],
      productTypes: [],
      typeSelected: '',
      searchText: '',
      propSelect: {},
      productProps: {},
      timer: 0,
      /**
       * 获取物品
       */
      getProducts: async (
        systemIndex: string,
        productType: string | null = null,
        searchText: string | null
      ) => {
        productInfo.products = await getProduct({
          searchText: searchText,
          systemNo: systemIndex,
          productType: productType,
          sort: 'ProductName',
          pageIndex: 1,
        })

        console.log(productInfo.products)
      },
      /**
       *价格保留两位小数
       */
      tranPrice: (price: number) => {
        if (price == null) {
          return '0.00'
        } else {
          return price.toFixed(2).toString()
        }
      },
      getBelongType: async () => {
        productInfo.belongTypes = await getBelongType()
        console.log(productInfo.belongTypes)
      },
      /**
       * 从后端获取物品类型
       */
      getProductType: async (sysNo: string) => {
        productInfo.productTypes = await getProductType(sysNo)
      },
      /**
       * 点击大类时我们不需要考虑搜索的内容,因为每次点击大类,都应该清空搜索框
       * 但是搜索物品时,就应该考虑大类
       */
      getSystemProduct: async (index: string) => {
        router.push(`/productList?belongType=${index}`)
      },
      /**
       *从后端获取物品属性
       */
      getProps: async (belongTypeNo: string, typeNo: string | null = null) => {
        console.log('belongTypeNo:' + belongTypeNo)
        var res = await getProps({ belongTypeNo, typeNo })
        productInfo.productProps = res
        console.log(res)
      },
      /**
       * 获取物品属性种类的名称
       */
      getPropKey: (key: string, index: number) => {
        return key.split('|')[index]
      },
      /**
       * 选择物品类型 ,选择物品类型时可以清空搜索栏
       */
      selectType: async (typeNo: string) => {
        if (productInfo.typeSelected != typeNo) {
          productInfo.typeSelected = typeNo
        }
        setRouter()
      },
      /**
       *搜索物品
       */
      search: async () => {
        clearTimeout(productInfo.timer)
        productInfo.timer = setTimeout(async () => {
          setRouter()
        }, 1000)
      },
      selectProp: (propKey: string, propValue: string) => {
        if (productInfo.propSelect[propKey] == propValue) {
          productInfo.propSelect[propKey] = ''
        } else {
          productInfo.propSelect[propKey] = propValue
        }
        console.log(productInfo.propSelect)
      },
      confirmFilter: () => {
        for (const key in productInfo.propSelect) {
          const value = productInfo.propSelect[key]
          productProps += `${key}_${value}%5E`
        }
        // console.log(productProps)
        productProps = productProps.substring(0, productProps.length - 3)
        console.log(productProps)
        // productInfo.propSelect.forEach((value: any, key: any) => {
        //   console.log(value)
        //   console.log(key)
        // })
      },
    })
    const setRouter = () => {
      var url = `/productList?belongType=${productInfo.systemIndex}`
      if (productInfo.searchText?.trim() != '') {
        url += `&keyword=${productInfo.searchText}`
      }
      if (productInfo.typeSelected?.trim() != '') {
        url += `&type=${productInfo.typeSelected}`
      }
      router.push(url)
    }
    const showLeft = () => {
      pageController.isShowLeft = !pageController.isShowLeft
    }
    const searchFocus = () => {
      pageController.isShowSearchBtn = true
    }
    const searchBlur = () => {
      pageController.isShowSearchBtn = false
    }
    const showRight = () => {
      pageController.isShowCover = true
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '0'
    }
    const hideRight = () => {
      pageController.isShowCover = false
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '-85%'
    }
    //解析地址
    let keyword: string | null = ''
    let systemIndex: string = ''
    let typeSelected: string = ''
    let productProps: string = ''
    const resoluationAddress = () => {
      keyword = (route.query.keyword as string) ?? ''
      productInfo.systemIndex = systemIndex =
        (route.query.belongType as string) ?? '1'
      productInfo.typeSelected = typeSelected =
        (route.query.type as string) ?? ''
      productProps = (route.query.prop as string) ?? ''
      if (productProps != '') {
        var arrayProductProps = productProps.split('%5E')
        for (let i = 0; i < arrayProductProps.length; i++) {
          const value: any = arrayProductProps[i]
          productInfo.propSelect[value.split('_')[0]] = value.split('_')[1]
        }
      }
      //格式大约是 &prop=xxx_xxx%5Eyyy_yy
      console.log(systemIndex)
    }

    onMounted(async () => {
      resoluationAddress()
      await productInfo.getProducts(systemIndex, typeSelected, keyword)
      await productInfo.getBelongType()
      await productInfo.getProductType(systemIndex)
      await productInfo.getProps(systemIndex, typeSelected)
    })
    return {
      ...toRefs(pageController),
      ...toRefs(productInfo),
      showLeft,
      searchFocus,
      searchBlur,
      showRight,
      hideRight,
    }
  },
}
</script>

<style lang="scss" scoped>
.i-search:after {
  background-color: #b70101 !important;
}

.search-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  padding: 6px 20px;
  background-color: #f0f0f0;
  display: flex;

  input {
    height: 28px;
    box-sizing: border-box;
    border: 1px solid #ddd;
    border-radius: 3px;
    flex: 1;
    outline: none;
  }

  button {
    background-color: transparent;
    width: 56px;
    border: 0 none;
    font-size: 14px;
    font-weight: bold;
    color: #333;
    outline: none;
  }
}

.system-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  top: 40px;
  background-color: #fff;
  display: flex;

  .system-item {
    flex: 1;
    text-align: center;
    border-bottom: 1px #ddd solid;
    border-right: 1px transparent solid;
    border-left: 1px transparent solid;

    span {
      border: 0 none !important;
      background-color: #f0f2f5;
      margin: 6px 5px;
      font-size: 12px;
      font-weight: normal;
      text-align: center;
      border-radius: 4px;
      padding: 6px 0;
      display: block;
      height: 20px;
      line-height: 12px;
    }
  }

  .system-select {
    border-bottom: 1px transparent solid;
    border-right: 1px #ddd solid;
    border-left: 1px #ddd solid;

    span {
      background-color: transparent;
    }
  }
}

.product-list {
  padding-top: 75px;
  ul {
    background-color: #fff;

    li {
      list-style: none;
      height: 88px;
      padding-left: 108px;
      position: relative;

      img {
        height: 66px;
        width: 66px;
        background-color: #ccc;
        position: absolute;
        left: 28px;
        top: 11px;
      }

      div {
        padding: 10px 0;
        border-bottom: 1px solid #f0f0f0;
        padding-bottom: 12px;
        text-align-last: left;
        .p-name {
          font-size: 13px;
        }

        .p-type {
          font-size: 12px;
          color: #666;
          margin-top: 8px;
        }

        .p-price {
          font-size: 13px;
          color: #f23030;
          margin-top: 8px;
        }
      }
    }
  }

  .left-menu {
    position: fixed;
    height: calc(100% - 116px);
    left: -106px;
    width: 125px;
    background-color: #fff;
    top: 76px;
    border-radius: 0 18px 0 0;
    border: 1px solid #d7d7d7;
    overflow: hidden;
    transition: 0.5s;
    margin-bottom: 120px;

    .left-switch {
      width: 20px;
      background-color: #fff;
      position: absolute;
      right: 0;
      height: 100%;

      img {
        position: absolute;
        top: 42%;
        left: 2px;
        width: 20px;
        transform: rotate(90deg);
        transition: 0.5s;
      }
    }

    ul {
      position: absolute;
      height: 100%;
      width: 106px;
      background-color: #f0f0f0;
      overflow: auto;

      li {
        width: 106px;
        height: 50px;
        text-align: center;
        line-height: 50px;
        border-bottom: 1px solid #d7d7d7;
        padding: 0;
        font-size: 12px;
        color: #333;
      }

      li.left-item-select {
        background-color: #fff;
      }
    }
  }

  .left-menu-show {
    left: 0;

    .left-switch {
      img {
        transform: rotate(-90deg);
      }
    }
  }
}

.right-pad {
  position: fixed;
  /* right: -85%; */
  right: -85%;
  top: 0;
  width: 85%;
  height: 100%;
  background-color: #f7f7f7;
  z-index: 103;
  transition: 580ms;
  z-index: 101;

  ul {
    list-style: none;
    overflow: hidden;
  }
  .list-pad {
    overflow: auto;
    height: 100%;
    padding-bottom: 40px;
    .f-type-list {
      overflow: hidden;

      > li {
        padding: 10px;
        background-color: #fff;
        margin-bottom: 10px;

        .f-item-list {
          overflow: auto;
          display: flex;
          flex-wrap: wrap;

          li {
            flex-basis: 33.3%;

            span {
              display: block;
              margin-top: 10px;
              margin-right: 10px;
              background: #eee;
              border: 1px solid #eee;
              padding: 5px 0;
              text-align: center;
              border-radius: 6px;
              font-size: 13px;
              overflow: hidden;
              height: 39px;
            }

            .prop-select {
              border: 1px solid red;
              background: #fff;
              color: red;
            }
          }
        }

        p {
          font-size: 14px;
        }
      }
    }
  }
  .right-edit {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;

    button {
      float: left;
      height: 40px;
      width: 50%;
      line-height: 40px;
      text-align: center;
      border: 0px none;
    }
  }
}

.cover {
  position: fixed;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  background-color: rgba(51, 51, 51, 0.36);
  z-index: 11;
}
</style>

11.修复前端bug,左侧筛选框,url地址拼接失败问题

点击查看代码
<template>
  <div>
    <!-- 搜索面板 -->
    <div class="search-pad">
      <input
        v-model="searchText"
        type="text"
        name=""
        id=""
        @focus="searchFocus()"
        @blur="searchBlur()"
        @input="search"
      />
      <button v-show="isShowSearchBtn">搜索</button>
      <button v-show="!isShowSearchBtn" @click="showRight()">筛选</button>
    </div>
    <!-- 物品大类面板 -->
    <div class="system-pad">
      <div
        v-for="belongType in belongTypes"
        :key="belongType.sysNo"
        :class="[
          'system-item',
          { 'system-select': systemIndex == belongType.sysNo },
        ]"
        @click="getSystemProduct(belongType.sysNo)"
      >
        <span>{{ belongType.belongTypeName }}</span>
      </div>
    </div>
    <!-- 物品展示列表 -->
    <div class="product-list">
      <ul>
        <li v-for="product in products" :key="product.id">
          <img :src="product.productPhoto?.productPhotoUrl" alt="" />
          <div>
            <p class="p-name">{{ product.productName }}</p>
            <p class="p-type">类别:{{ product.typeName }}</p>
            <p class="p-price">
              &yen;{{ tranPrice(product.productSale?.salePrice) }}/张
            </p>
          </div>
        </li>
      </ul>
      <!-- 左边物品类型面板 -->
      <div :class="['left-menu', { 'left-menu-show': isShowLeft }]">
        <div class="left-switch" @click="showLeft()">
          <img src="/img/dealerImgs/up.png" alt="" />
        </div>
        <ul>
          <li
            v-for="productType in productTypes"
            :key="productType.typeNo"
            @click="selectType(productType.typeNo)"
            :class="{ 'left-item-select': typeSelected == productType.typeNo }"
          >
            {{ productType.typeName }}
          </li>
        </ul>
      </div>
    </div>
    <!-- 右边物品属性面板 -->
    <div class="right-pad">
      <div class="list-pad">
        <ul class="f-type-list">
          <template v-for="(values, key) in productProps">
            <li v-if="values.length > 0" :key="key">
              <p>{{ getPropKey(key, 1) }}</p>
              <ul class="f-item-list">
                <li
                  v-for="value in values"
                  :key="value"
                  @click="selectProp(getPropKey(key, 0), value)"
                >
                  <span
                    :class="{
                      'prop-select': propSelect[getPropKey(key, 0)] == value,
                    }"
                    >{{ value }}</span
                  >
                </li>
                <!-- <li><span class="prop-select">胡桃色</span></li> -->
              </ul>
              <div class="clear-tag"></div>
            </li>
          </template>
        </ul>
      </div>
      <div class="right-edit">
        <button
          @click="confirmFilter()"
          style="background-color: rgb(188, 0, 0); color: #fff"
        >
          确定
        </button>
        <button @click="hideRight()">取消</button>
      </div>
    </div>
    <div class="cover" v-show="isShowCover" @click="hideRight()"></div>
  </div>
</template>

<script lang="ts">
import { ref, onMounted, reactive, toRefs } from 'vue'
import {
  getProduct,
  getBelongType,
  getProductType,
  getProps,
} from '@/httpRequests/ProductListRequest'
import { IProductInfo } from '@/Interfaces/ProductList'
import { useRouter, useRoute } from 'vue-router'
import router from '@/router'

export default {
  setup() {
    var router = useRouter()
    var route = useRoute()
    const pageController = reactive({
      isShowLeft: ref(false),
      isShowCover: ref(false),
      isShowSearchBtn: ref(false),
    })
    //IProductInfo
    const productInfo: IProductInfo = reactive({
      systemIndex: '1',
      products: [],
      belongTypes: [],
      productTypes: [],
      typeSelected: '',
      searchText: '',
      propSelect: {},
      productProps: {},
      timer: 0,
      /**
       * 获取物品
       */
      getProducts: async (
        systemIndex: string,
        productType: string | null = null,
        searchText: string | null
      ) => {
        productInfo.products = await getProduct({
          searchText: searchText,
          systemNo: systemIndex,
          productType: productType,
          sort: 'ProductName',
          pageIndex: 1,
        })

        console.log(productInfo.products)
      },
      /**
       *价格保留两位小数
       */
      tranPrice: (price: number) => {
        if (price == null) {
          return '0.00'
        } else {
          return price.toFixed(2).toString()
        }
      },
      getBelongType: async () => {
        productInfo.belongTypes = await getBelongType()
        console.log(productInfo.belongTypes)
      },
      /**
       * 从后端获取物品类型
       */
      getProductType: async (sysNo: string) => {
        productInfo.productTypes = await getProductType(sysNo)
      },
      /**
       * 点击大类时我们不需要考虑搜索的内容,因为每次点击大类,都应该清空搜索框
       * 但是搜索物品时,就应该考虑大类
       */
      getSystemProduct: async (index: string) => {
        router.push(`/productList?belongType=${index}`)
      },
      /**
       *从后端获取物品属性
       */
      getProps: async (belongTypeNo: string, typeNo: string | null = null) => {
        console.log('belongTypeNo:' + belongTypeNo)
        var res = await getProps({ belongTypeNo, typeNo })
        productInfo.productProps = res
        console.log(res)
      },
      /**
       * 获取物品属性种类的名称
       */
      getPropKey: (key: string, index: number) => {
        return key.split('|')[index]
      },
      /**
       * 选择物品类型 ,选择物品类型时可以清空搜索栏
       */
      selectType: async (typeNo: string) => {
        if (productInfo.typeSelected != typeNo) {
          productInfo.typeSelected = typeNo
        }
        setRouter()
      },
      /**
       *搜索物品
       */
      search: async () => {
        clearTimeout(productInfo.timer)
        productInfo.timer = setTimeout(async () => {
          setRouter()
        }, 1000)
      },
      selectProp: (propKey: string, propValue: string) => {
        if (productInfo.propSelect[propKey] == propValue) {
          productInfo.propSelect[propKey] = ''
        } else {
          productInfo.propSelect[propKey] = propValue
        }
        console.log(productInfo.propSelect)
      },
      /**
       * 确认筛选
       */
      confirmFilter: () => {
        productProps = ''
        for (const key in productInfo.propSelect) {
          const value = productInfo.propSelect[key]
          productProps += `${key}_${value}^`
        }
        productProps = productProps.substring(0, productProps.length - 1)
        console.log(productProps)
        setRouter()
      },
    })
    /**
     * 设置路由
     */
    const setRouter = () => {
      // 根地址 包含根路由以及物品大类信息
      var url = `/productList?belongType=${productInfo.systemIndex}`
      // 拼接物品搜索信息
      if (productInfo.searchText?.trim() != '') {
        url += `&keyword=${productInfo.searchText}`
      }
      // 拼接物品类型
      if (productInfo.typeSelected?.trim() != '') {
        url += `&type=${productInfo.typeSelected}`
      }
      if (productProps != '') {
        url += `&prop=${productProps}`
      }
      // 拼接属性
      router.push(url)
    }
    const showLeft = () => {
      pageController.isShowLeft = !pageController.isShowLeft
    }
    const searchFocus = () => {
      pageController.isShowSearchBtn = true
    }
    const searchBlur = () => {
      pageController.isShowSearchBtn = false
    }
    const showRight = () => {
      pageController.isShowCover = true
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '0'
    }
    const hideRight = () => {
      pageController.isShowCover = false
      var dom = document.querySelector('.right-pad') as HTMLElement
      dom.style.right = '-85%'
    }
    //解析地址
    let keyword: string | null = ''
    let systemIndex: string = ''
    let typeSelected: string = ''
    let productProps: string = ''
    const resoluationAddress = () => {
      keyword = (route.query.keyword as string) ?? ''
      productInfo.systemIndex = systemIndex =
        (route.query.belongType as string) ?? '1'
      productInfo.typeSelected = typeSelected =
        (route.query.type as string) ?? ''
      productProps = (route.query.prop as string) ?? ''
      if (productProps != '') {
        var arrayProductProps = productProps.split('^')
        for (let i = 0; i < arrayProductProps.length; i++) {
          const value: any = arrayProductProps[i]
          productInfo.propSelect[value.split('_')[0]] = value.split('_')[1]
        }
      }
      //格式大约是 &prop=xxx_xxx^yyy_yy
      console.log(systemIndex)
    }

    onMounted(async () => {
      resoluationAddress()
      await productInfo.getProducts(systemIndex, typeSelected, keyword)
      await productInfo.getBelongType()
      await productInfo.getProductType(systemIndex)
      await productInfo.getProps(systemIndex, typeSelected)
    })
    return {
      ...toRefs(pageController),
      ...toRefs(productInfo),
      showLeft,
      searchFocus,
      searchBlur,
      showRight,
      hideRight,
    }
  },
}
</script>

<style lang="scss" scoped>
.i-search:after {
  background-color: #b70101 !important;
}

.search-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  padding: 6px 20px;
  background-color: #f0f0f0;
  display: flex;

  input {
    height: 28px;
    box-sizing: border-box;
    border: 1px solid #ddd;
    border-radius: 3px;
    flex: 1;
    outline: none;
  }

  button {
    background-color: transparent;
    width: 56px;
    border: 0 none;
    font-size: 14px;
    font-weight: bold;
    color: #333;
    outline: none;
  }
}

.system-pad {
  z-index: 10;
  position: fixed;
  width: 100%;
  top: 40px;
  background-color: #fff;
  display: flex;

  .system-item {
    flex: 1;
    text-align: center;
    border-bottom: 1px #ddd solid;
    border-right: 1px transparent solid;
    border-left: 1px transparent solid;

    span {
      border: 0 none !important;
      background-color: #f0f2f5;
      margin: 6px 5px;
      font-size: 12px;
      font-weight: normal;
      text-align: center;
      border-radius: 4px;
      padding: 6px 0;
      display: block;
      height: 20px;
      line-height: 12px;
    }
  }

  .system-select {
    border-bottom: 1px transparent solid;
    border-right: 1px #ddd solid;
    border-left: 1px #ddd solid;

    span {
      background-color: transparent;
    }
  }
}

.product-list {
  padding-top: 75px;
  ul {
    background-color: #fff;

    li {
      list-style: none;
      height: 88px;
      padding-left: 108px;
      position: relative;

      img {
        height: 66px;
        width: 66px;
        background-color: #ccc;
        position: absolute;
        left: 28px;
        top: 11px;
      }

      div {
        padding: 10px 0;
        border-bottom: 1px solid #f0f0f0;
        padding-bottom: 12px;
        text-align-last: left;
        .p-name {
          font-size: 13px;
        }

        .p-type {
          font-size: 12px;
          color: #666;
          margin-top: 8px;
        }

        .p-price {
          font-size: 13px;
          color: #f23030;
          margin-top: 8px;
        }
      }
    }
  }

  .left-menu {
    position: fixed;
    height: calc(100% - 116px);
    left: -106px;
    width: 125px;
    background-color: #fff;
    top: 76px;
    border-radius: 0 18px 0 0;
    border: 1px solid #d7d7d7;
    overflow: hidden;
    transition: 0.5s;
    margin-bottom: 120px;

    .left-switch {
      width: 20px;
      background-color: #fff;
      position: absolute;
      right: 0;
      height: 100%;

      img {
        position: absolute;
        top: 42%;
        left: 2px;
        width: 20px;
        transform: rotate(90deg);
        transition: 0.5s;
      }
    }

    ul {
      position: absolute;
      height: 100%;
      width: 106px;
      background-color: #f0f0f0;
      overflow: auto;

      li {
        width: 106px;
        height: 50px;
        text-align: center;
        line-height: 50px;
        border-bottom: 1px solid #d7d7d7;
        padding: 0;
        font-size: 12px;
        color: #333;
      }

      li.left-item-select {
        background-color: #fff;
      }
    }
  }

  .left-menu-show {
    left: 0;

    .left-switch {
      img {
        transform: rotate(-90deg);
      }
    }
  }
}

.right-pad {
  position: fixed;
  /* right: -85%; */
  right: -85%;
  top: 0;
  width: 85%;
  height: 100%;
  background-color: #f7f7f7;
  z-index: 103;
  transition: 580ms;
  z-index: 101;

  ul {
    list-style: none;
    overflow: hidden;
  }
  .list-pad {
    overflow: auto;
    height: 100%;
    padding-bottom: 40px;
    .f-type-list {
      overflow: hidden;

      > li {
        padding: 10px;
        background-color: #fff;
        margin-bottom: 10px;

        .f-item-list {
          overflow: auto;
          display: flex;
          flex-wrap: wrap;

          li {
            flex-basis: 33.3%;

            span {
              display: block;
              margin-top: 10px;
              margin-right: 10px;
              background: #eee;
              border: 1px solid #eee;
              padding: 5px 0;
              text-align: center;
              border-radius: 6px;
              font-size: 13px;
              overflow: hidden;
              height: 39px;
            }

            .prop-select {
              border: 1px solid red;
              background: #fff;
              color: red;
            }
          }
        }

        p {
          font-size: 14px;
        }
      }
    }
  }
  .right-edit {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;

    button {
      float: left;
      height: 40px;
      width: 50%;
      line-height: 40px;
      text-align: center;
      border: 0px none;
    }
  }
}

.cover {
  position: fixed;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  background-color: rgba(51, 51, 51, 0.36);
  z-index: 11;
}
</style>

12.后端改造

标签:实战,color,列表,productInfo,background,NET,height,border,left
来源: https://www.cnblogs.com/humblexwang/p/16303533.html