ゼロから、シンプルなショッピングプラットフォームを構築します(14)フロントエンドモール部分

ゼロから、シンプルなショッピングプラットフォームを構築します(13)フロントエンドモールパーツ:
https //blog.csdn.net/time_____/article/details/108514710
プロジェクトのソースコード(継続的な更新):https//gitee.com/ DieHunter / myCode / tree / master / Shopping

この記事では、いくつかのコンポーネントとホームページの実装を紹介します。ホームページのコンポーネントは次のとおりです。ホームページのデータは、バッチで非同期にロードされます。つまり、データ要求の輻輳を減らすために、各コンポーネントのデータが個別に要求されます。実装プロセスを以下に紹介します。

pageTitle(ページタイトル)

  • まず、タイトルのリターン関数を検討し、メソッドにルートリターン関数を記述します。
     methods: {
        goBack() {
          this.$router.go(-1);
        }
      }

     

  • 次に、コンポーネントのプロパティ(タイトルの内容、戻るボタンがあるかどうか)を介してパラメーターを渡し、小道具を介して現在のデータにコンポーネントのプロパティを配置します

    props: ["title", "isBack"],

     

  • ラベルは、isBackに基づいて戻るボタンがあるかどうかを判別し、タイトル値を表示します

    <template>
      <div id="top">
        <span v-if="isBack" class="back iconfont icon-fanhui" @click="goBack"></span>
        <span class="title">{
         
         {title}}</span>
      </div>
    </template>

     

バナー(ホームページカルーセル)

  • カルーセル図コンポーネントの画像は個別に要求されるため、モデル管理データが使用され、ビジネスが要求され、後続のコンポーネントにはすべてこのように記述されたデータ要求の相互作用があります。
  • Model.jsコンテンツ、バナーリスト、vueインスタンス、ページ構成情報を保存します
    export default class BannerModel {//banner数据存取
      constructor() {
        this._bannerList = []
        this._pageConfig = {}
      }
      static getInstance() { //单例写法
        if (!BannerModel._instance) {
          Object.defineProperty(BannerModel, "_instance", {
            value: new BannerModel()
          })
        }
        return BannerModel._instance;
      }
      set vueComponent(val) {
        this._vueComponent = val
      }
      get vueComponent() {
        return this._vueComponent
      }
      set pageConfig(val) {
        this._pageConfig = val
        this._pageConfig.picType = 1
      }
      get pageConfig() {
        return this._pageConfig
      }
      set bannerList(val) {
        this._bannerList = val
        this._vueComponent.list = this.bannerList
      }
      get bannerList() {
        return this._bannerList
      }
    }
    
  • bussiness.jsはリクエストとロジック処理を行います
    import Vue from 'vue'
    import config from "../../config/config"
    import BannerModel from "./model";
    import Clone from "../../utils/clone"
    const {
      DefaultPageConfig,
      ServerApi
    } = config
    export default class BannerBussiness extends Vue {//业务处理
      constructor(_vueComponent) {
        super()
        BannerModel.getInstance().vueComponent = _vueComponent//取到显示层vue实例
        this.initPageConfig()
        this.getBanner()
      }
      initPageConfig() {//拷贝分页默认配置,并且不更改原常量
        BannerModel.getInstance().pageConfig = Clone.shallowClone(DefaultPageConfig)
      }
      getBanner() {//请求处理,this.$crypto.setCrypto加密
        this.$axios
          .get(ServerApi.shop.shopList, {
            params: {
              crypto: this.$crypto.setCrypto(BannerModel.getInstance().pageConfig)
            },
          }).then(res => {
            switch (res.result) {
              case 1:
                BannerModel.getInstance().bannerList = res.data.list
                break;
              default:
                break;
            }
          })
      }
    }
    
  • Banner.vueページの表示
    <template>
      <div class="swiper">
        <mt-swipe :auto="3000">
          <mt-swipe-item v-for="(item,index) in list" :key="index">
            <img class="imgs" :src="imgPath+item.shopPic" @click="clickHandler(item)" />
          </mt-swipe-item>
        </mt-swipe>
      </div>
    </template>
    
    <script>
    import { Swipe, SwipeItem } from "mint-ui";
    import Config from "../../config/config";
    import BannerBussiness from "./bussiness";
    export default {
      name: "banner",
      data() {
        return {
          list: [],//图片列表
          imgPath: Config.RequestPath//图片根路径
        };
      },
      created() {
        this.init();
      },
      methods: {
        init() {
          new BannerBussiness(this);//初始化banner请求
        },
        clickHandler(_shop) {//banner点击跳转
          this.$router.push({
            name: "ShopTheme",
            query: { _type: _shop.shopType, _shopName: _shop.shopName }
          });
        }
      }
    };
    </script>
    
    <style lang="less" scoped>
    @import "../../style/init.less";
    .imgs {
      .h(500);
      width: 100%;
    }
    .swiper {
      width: 100%;
      .h(500);
    }
    </style>

 tableBar(ナビゲーションバー)

  • 対応するアイコンフォントリソースをiconfontでダウンロードします。スタイルディレクトリに直接ダウンロードして、クラス名として表示します。タブバーフォルダに新しいmodel.jsを作成して、データをフェッチします(実際、これはconfigに配置できます)。
    export default class TableBarModel {
      static MenuList = [{
          name: "主页",
          path: "/Home",
          icon: "icon-shouye li iconfont"
        },
        {
          name: "分类",
          path: "/Kind",
          icon: "icon-fenlei li iconfont"
        },
        {
          name: "购物车",
          path: "/ShopCar",
          icon: "icon-daohang-gouwuche li iconfont"
        },
        {
          name: "我的",
          path: "/Info",
          icon: "icon-wode li iconfont"
        }
      ]
    }
    
  • tabbar.vue、リストから
    <template>
      <ul id="tab">
        <router-link
          v-for="(item, index) in menuList"
          :key="index"
          :to="item.path"
          tag="li"
          :class="item.icon"
          active-class="change"
          replace
        >
          <br />
          {
         
         {item.name}}
        </router-link>
      </ul>
    </template>
    
    <script>
    import tableBarModel from "./model";
    export default {
      name: "tabBar",
      data() {
        return {
          menuList: tableBarModel.MenuList
        };
      }
    };
    </script>
    
    <style lang='less' scoped>
    @import "../../style/init.less";
    #tab {
      display: flex;
      
      box-shadow: -1px 0 8px #999;
      z-index: 100;
      justify-content: space-around;
      position: fixed;
      bottom: 0;
      left: 0;
      right: 0;
      .h(130);
      .bcolor();
      .li {
        .h(130);
        box-sizing: border-box;
        padding-top: unit(10 / @pxtorem, rem);
        width: 25%;
        text-align: center;
        .fontColorOff();
      }
      .li::before {
        .f_s(58);
      }
      .li {
        .f_s(26);
      }
      .change {
        .fontColorOn();
      }
    }
    </style>

題名

  • タイトルはh2で簡単なスタイル変更を行いました
    <template>
      <div>
        <h2>{
         
         {title}}</h2>
      </div>
    </template>
    
    <script>
    export default {
      props: ["title"]
    };
    </script>
    
    <style lang="less" scoped>
    @import "../../style/init.less";
    h2 {
      .h2Font();
    }
    </style>

shopItem(製品リスト) 

  • 新しいmodel.jsを作成して、読み取り可能および書き込み可能な製品、vueコンポーネントインスタンス、およびデフォルトのページング構成のリストを保存します
    export default class ItemModel {//存放可读写商品列表,vue组件实例和默认分页配置
      constructor() {
        this._shopList = []//商品列表
        this._pageConfig = {}//默认分页配置
      }
      static getInstance() { //单例写法
        if (!ItemModel._instance) {
          Object.defineProperty(ItemModel, "_instance", {
            value: new ItemModel()
          })
        }
        return ItemModel._instance;
      }
      set vueComponent(val) {
        this._vueComponent = val
      }
      get vueComponent() {
        return this._vueComponent
      }
      set pageConfig(val) {
        this._pageConfig = val
        this._pageConfig.picType = 0//默认商品类型:单个商品
      }
      get pageConfig() {
        return this._pageConfig
      }
      set shopList(val) {
        this._shopList = val
        this._vueComponent.list = this._shopList//获取到商品列表后重新渲染
      }
      get shopList() {
        return this._shopList
      }
    }
    
  • ビジネス処理用の新しいbussiness.jsを作成します
    import Vue from 'vue';
    import config from "../../config/config";
    import ItemModel from "./model";
    import Clone from "../../utils/clone";
    const {
      DefaultPageConfig,
      ServerApi
    } = config
    export default class ItemBussiness extends Vue {
      constructor(_vueComponent) {
        super()
        ItemModel.getInstance().vueComponent = _vueComponent//Vue组件实例
        this.initPageConfig(_vueComponent.shopType)
        this.getShopItem()
      }
      initPageConfig(_shopType) {//获取默认分页配置
        ItemModel.getInstance().pageConfig = Clone.shallowClone(DefaultPageConfig)
        ItemModel.getInstance().pageConfig.shopType = _shopType
      }
      getShopItem() {//获取商品列表
        this.$axios
          .get(ServerApi.shop.shopList, {
            params: {
              crypto: this.$crypto.setCrypto(ItemModel.getInstance().pageConfig)
            },
          }).then(res => {
            switch (res.result) {
              case 1:
                ItemModel.getInstance().shopList = res.data.list//渲染页面
                break;
              default:
                break;
            }
          })
      }
    }
    
  • shopItem.vueでリストをレンダリングし、クリックイベントを追加して、製品の詳細ページにジャンプします
    <template>
      <ul class="more">
        <li v-for="(item,index) in list" :key="index" @click="clickHandler(item)">
          <img :src="imgPath+item.shopPic" alt :class="'imgs'+index" />
          <span>{
         
         {item.shopName}} {
         
         {item.shopScale}}克</span>
          <div>¥{
         
         {item.shopPrice}}</div>
        </li>
      </ul>
    </template>
    <script>
    import ShopBussiness from "./bussiness";
    import Config from "../../config/config";
    export default {
      name: "shopItem",
      props: ["shopType"],
      data() {
        return {
          list: [],
          imgPath: Config.RequestPath
        };
      },
      mounted() {
        new ShopBussiness(this);
      },
      methods: {
        clickHandler(data) {
          this.$router.push({ name: "ShopInfo", query: { ...data } });
        }
      }
    };
    </script>
    
    <style lang="less" scoped>
    @import "../../style/init.less";
    .more {
      li {
        .shopItem();
      }
    }
    </style>

最終的な製品テーマコンポーネントは製品リストに似ています。クリックイベントを追加して、テーマの詳細ページにジャンプします

ホームページ

ページフォルダの下に新しいホームフォルダとhome.vueファイルを作成し、上記のコンポーネントをホームに導入してページを形成します。効果は次のとおりです。

home.vue

<template>
  <div>
    <Top title="零食商贩"></Top>
    <div class="content">
      <Banner></Banner>
      <H2 title="精选主题"></H2>
      <Theme></Theme>
      <H2 title="最近新品"></H2>
      <ShopItem :shopType="shopType"></ShopItem>
    </div>
    <TabBar></TabBar>
  </div>
</template>

<script>
import TabBar from "../../components/tabBar/tabBar";
import Top from "../../components/top/top";
import Banner from "../../components/banner/banner";
import Theme from "../../components/theme/theme";
import ShopItem from "../../components/shopItem/shopItem";
import H2 from "../../components/h2/h2";
export default {
  name: "Home",
  data() {
    return {
      shopType: ""
    };
  },
  components: {
    Top,
    H2,
    Banner,
    Theme,
    ShopItem,
    TabBar
  }
};
</script>

<style lang="less" scoped>
@import "../../style/init.less";
</style>

以上がホームページ機能の実現といくつかのパブリックコンポーネントの実現です。次の記事では、製品分類リスト、製品テーマのインターフェースと機能を紹介します。

おすすめ

転載: blog.csdn.net/time_____/article/details/108545330