From scratch, build a simple shopping platform (15) Front-end mall part

From scratch, build a simple shopping platform (14) Front-end mall part:
https://blog.csdn.net/time_____/article/details/108545330
Project source code (continuous update): https://gitee.com/ DieHunter/myCode/tree/master/shopping

The previous article implemented the interface and function implementation of the homepage and some public components. The tools, routing, and global status used in the project were encapsulated. This article will introduce the product classification and product theme interface. The implementation process is the same A separate asynchronous request in the component is used to reduce data congestion

Categories:

Interface style and effect

Note: Since the category product list and the products on the homepage will not change frequently, we can use the keep-alive component in Vue. Its function is to keep the state in the memory when the component is switched to prevent repeated rendering of the DOM, that is, save The component is not destroyed to prevent unnecessary requests every time the page is loaded. The effect is as follows

Add the keep-alive component to the app.vue to wrap the routing component

<keep-alive include="Home,Kind">
   <router-view class="appView"></router-view>
</keep-alive>

Here we divide the classification list into two components on the left and right to form a tab switching bar, and select and switch through the classification menu on the left to re-render the product list on the right

  • Left switch component leftMenu.vue
    <template>
      <div id="left">
        <div
          v-for="(item,index) in list"
          :key="index"
          @click="sel(item.val)"
          :class="item.val==onesel?'selec':''"
        >{
         
         {item.name}}</div>
      </div>
    </template>
    
    <script>
    import Config from "../../config/config";
    import ShopType from "../../config/shopType";
    const { EventName } = Config;
    export default {
      data() {
        return {
          list: ShopType.shopType,
          onesel: "0"//默认选中第一项
        };
      },
      methods: {
        sel(item) {
          if (this.onesel == item) return;//防止重复点击同一个选项
          this.onesel = item;
          this.$events.emitEvent(EventName.SelectKind, item);//触发选中商品类型事件
        }
      }
    };
    </script>
    
    <style lang="less" scoped>
    @import "../../style/init.less";
    #left {
      .w(215);
      height: 100%;
      position: fixed;
      .f_s(34);
      border-right: unit(1 / @pxtorem, rem) solid #d6d6d6;
      margin-right: unit(215 / @pxtorem, rem);
      div {
        .h(125);
        .l_h(125);
        text-align: center;
      }
      .selec {
        border-left: unit(8 / @pxtorem, rem) solid @mainColor;
        text-indent: unit(-8 / @pxtorem, rem);
        color: @mainColor;
      }
    }
    </style>

     

  • Product list component on the right, rightShop.vue

    <template>
      <transition name="fade">
        <div class="rightShop" v-if="transitionSwitch">
          <h2 id="head">
            <img :src="imgPath+themeList.shopPic" v-if="themeList.shopPic" alt />
          </h2>
          <ul>
            <li v-for="(item,index) in list" :key="index" @click="clickHandler(item)">
              <img :src="imgPath+item.shopPic" />
              <span>{
         
         {item.shopName}} {
         
         {item.shopScale}}克</span>
            </li>
          </ul>
        </div>
      </transition>
    </template>
    <script>
    import Config from "../../config/config";
    import RightShopBussiness from "./bussiness";
    const { EventName } = Config;
    export default {
      data() {
        return {
          themeList: {},
          list: [],
          imgPath: Config.RequestPath,
          rightShopBussiness: null,
          transitionSwitch: true,
          beforeIndex: 0
        };
      },
      created() {
        this.rightShopBussiness = new RightShopBussiness(this);
        this.rightShopBussiness.initPageConfig(this.beforeIndex);
        this.$events.onEvent(EventName.SelectKind, data => {//监听选择种类事件
          this.transitionSwitch = false;//通过v-show实现fade动画效果
          this.rightShopBussiness.initPageConfig(data);
        });
      },
      destroyed() {
        this.$events.offEvent(EventName.SelectKind);//销毁事件监听
      },
      methods: {
        clickHandler(data) {
          this.$router.push({ name: "ShopInfo", query: { ...data } });
        }
      }
    };
    </script>
    
    <style lang="less" scoped>
    @import "../../style/init.less";
    .rightShop {
      padding-left: unit(215 / @pxtorem, rem);
      img {
        width: 90%;
        display: block;
        margin: unit(40 / @pxtorem, rem) auto;
      }
      ul {
        margin-top: unit(70 / @pxtorem, rem);
        margin-bottom: unit(110 / @pxtorem, rem);
        li {
          display: inline-block;
          width: 33%;
          vertical-align: top;
          text-align: center;
          img {
            width: 70%;
            margin: 0 auto;
          }
          span {
            .f_s(28);
            text-align: center;
          }
        }
      }
    }
    </style>

     

  • Add the product classification page to the router configuration, and create a new kind page under the same level page as the homepage and shopping cart interface, and the product classification page has been completed 

    <template>
      <div>
        <Top title="分类"></Top>
        <div class="content">
          <leftMenu></leftMenu>
          <rightShop></rightShop>
        </div>
        <TabBar></TabBar>
      </div>
    </template>
    
    <script>
    import TabBar from "../../components/tabBar/tabBar";
    import Top from "../../components/top/top";
    import leftMenu from "../../components/leftMenu/leftMenu";
    import rightShop from "../../components/rightShop/rightShop";
    export default {
      name: "Kind",
      components: {
        Top,
        leftMenu,
        rightShop,
        TabBar
      }
    };
    </script>
    
    <style lang="less" scoped>
    @import "../../style/init.less";
    </style>

     

Product theme

The product theme page is that the user enters the sub-page of the theme product list by clicking the carousel image and theme module on the homepage, where a single product in the product list can be reused through the components of the homepage

The themeList is the image of the ad title, and the product list on the homepage and the product list on the theme page are distinguished by shopType, thereby introducing the shopItem component

  • themeList.vue ad title
    <template>
      <div class="themeContent">
        <h2>
          <img v-if="themeList.shopPic" :src="imgPath+themeList.shopPic" alt />
        </h2>
      </div>
    </template>
    
    <script>
    import Config from "../../config/config";
    import ThemeListBussiness from "./bussiness";
    export default {
      data() {
        return {
          themeList: {},
          imgPath: Config.RequestPath,
          themeListBussiness: null
        };
      },
      created() {
        this.themeListBussiness = new ThemeListBussiness(this);
        this.themeListBussiness.initPageConfig(this.$route.query);
      },
      methods: {}
    };
    </script>
    
    <style lang="less" scoped>
    @import "../../style/init.less";
    .themeContent {
      h2 {
        width: 100%;
        img {
          width: 100%;
        }
      }
    }
    </style>

     
  • Finally, create a new page page of shopTheme and introduce the previous two components
    <template>
      <div>
        <Top :title="title" :isBack="true"></Top>
        <div class="content">
          <ThemeList></ThemeList>
          <ShopItem :shopType="shopType"></ShopItem>
        </div>
      </div>
    </template>
    
    <script>
    import Top from "../../components/top/top";
    import ThemeList from "../../components/themeList/themeList";
    import ShopItem from "../../components/shopItem/shopItem";
    export default {
      name: "ShopTheme",
      data() {
        return {
          shopType: this.$route.query._type,
          title: this.$route.query._shopName
        };
      },
      components: {
        Top,
        ThemeList,
        ShopItem
      }
    };
    </script>
    
    <style lang="less" scoped>
    @import "../../style/init.less";
    .content {
      padding-bottom: 0;
    }
    </style>

    So far, the product classification and theme list page is completed
     

Finally, the product database data download is provided (all manually entered one by one), and the remote warehouse address can be imported through Robo3t. The
end of this article, the next article will introduce the realization of the product details page

Guess you like

Origin blog.csdn.net/time_____/article/details/108680599