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

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

前回の記事では、ホームページ、カテゴリリスト、公開コンポーネント、ツールを実装しましたが、今回は商品詳細ページの実現をご紹介します。ここでは、商品詳細ページを複数のコンポーネントに絞り込み、コンポーネント通信方式を採用します。データ配信と効果ロジックを実現するために、監視配信方法を実行し
ます。最初に効果を見てみましょう。

このインターフェイスでは、ページをいくつかのコンポーネントに分割できます。つまり、上部の上部、製品情報の表示、製品オプションボックスとカートへの追加ボタン、最後に下部のタブ切り替え効果です。

製品オプションボックス:

まず、mint-uiの公式ピッカーとナビバーで簡単なセカンダリパッケージを実行してから、製品オプションボックスのピッカーコンポーネントとアドインショッピングカートボタンコンポーネントをトリガーします。ショッピングカートに追加するときに、アニメーションアニメーションを必要とするアニメーションが追加されます。グローバルショッピングカートリストの更新

  • shopPicker.vueは、公式コンポーネントをパッケージ化し、製品の最大数でリストを表示します
    <template>
      <div class="shopPicker">
        <mt-popup v-model="popupVisible" position="bottom">
          <mt-picker class="pickerItem" :slots="count" :showToolbar="true" @change="onValuesChange">
            <div>{
         
         {pickerTitle}}</div>
          </mt-picker>
        </mt-popup>
      </div>
    </template>
    <script>
    import { Picker, Popup } from "mint-ui";
    import Config from "../../config/config";
    const { EventName } = Config;
    export default {
      name: "shopPicker",
      props: ["ShopMaxCount","pickerTitle"],//最大购买数,picker的标题
      data() {
        return {
          popupVisible: false,//是否显示组件
          count: [{ flex: 1, values: [] }]//组件默认模板
        };
      },
      mounted() {
        this.createShopCount();//初始化组件
        this.$events.onEvent(EventName.ShowPicker, this.showPicker);//监听显示picker事件
      },
      destroyed() {
        this.$events.offEvent(EventName.ShowPicker);//注销显示picker事件
      },
      methods: {
        onValuesChange(comp, count) {//数据变化时触发counter中的显示商品数量
          this.$events.emitEvent(EventName.ChangeCount, count[0]);
        },
        showPicker() {
          this.popupVisible = true;
        },
        createShopCount() {//根据传进来的最大数量显示商品数量列表
          this.count[0].values = this.ShopMaxCount;
          for (let i = 0; i < this.ShopMaxCount; i++) {
            this.count[0].values.push(i + 1);
          }
        }
      }
    };
    </script>
    
    <style lang="less" scoped>
    @import "../../style/init.less";
    
    </style>
  •  navbarスタイルを変更して、独自のコンポーネントに適用します
    <template>
      <div class="info">
        <mt-navbar v-model="selected">
          <mt-tab-item v-for="(item,index) in navTitle" :key="index" :id="item.val">{
         
         {item.name}}</mt-tab-item>
        </mt-navbar>
        <mt-tab-container v-model="selected">
          <mt-tab-container-item class="doc" id="0">
            <div>名称:{
         
         {shopName}}</div>
            <div>类型:{
         
         {Type[shopType].name}}</div>
            <div>数量:{
         
         {shopNum}}个</div>
            <div>¥{
         
         {shopPrice}}元</div>
          </mt-tab-container-item>
          <mt-tab-container-item class="doc" id="1">
            <div>净含量/克(g):{
         
         {shopScale}}</div>
            <div>口味:{
         
         {taste}}</div>
            <div>产地:{
         
         {address}}</div>
            <div>保质期:{
         
         {expiryDate}}</div>
            <div>上架时间:{
         
         {time}}</div>
          </mt-tab-container-item>
          <mt-tab-container-item id="2">
            <h3>7天包退</h3>
            <h3>15天包换</h3>
            <h3>一年保修</h3>
          </mt-tab-container-item>
        </mt-tab-container>
      </div>
    </template>
    
    <script>
    import { Navbar, TabItem } from "mint-ui";
    import NavConfig from "../../config/navConfig";
    import ShopType from "../../config/shopType";
    
    export default {
      name: "infoNav",
      data() {
        return {
          selected: "0",//默认选中第一项
          navTitle: NavConfig.NavTitle,
          Type: ShopType.shopType,
          ...this.$route.query//路由传参,将商品信息传递到data中
        };
      }
    };
    </script>
    
    <style lang="less" scoped>
    @import "../../style/init.less";
    @fontcolor: #bababa;
    .info {
      .mg(20px auto);
      .navBar();
      h3 {
        text-align: center;
        color: @mainColor;
      }
      .doc div {
        text-align: center;
        padding: 0.625rem 0;
      }
    }
    </style>

     

  •  ここでの難しさの1つは、ショッピングカートのアニメーションを追加することです。さまざまな方法を考えました。
    最後に、一方のラベルを非表示にし、もう一方のラベルを使用してアニメーションを実行し、アニメーション効果を向上させまし
    た。showAnimate変数は、アニメーションを実行するラベルv-showを制御するために使用されます。

    アニメーションタグのanimate.cssでzoomOutUpエフェクトを使用します

    <transition enter-active-class="animated zoomOutUp slow">
            <span v-show="showAnimate" class="icon-jiarugouwuche iconfont addIcon"></span>
    </transition>

     クリックしてカートに追加すると、イベントがトリガーされます

    addShopCar() {
          this.showAnimate = true;//显示元素
          setTimeout(() => {//延时的目的是等待动画完成
            this.shopCar.countShopItem({//缓存添加购物车数据
              ...this.$route.query,
              shopCount: this.shopCount
            });
            this.showAnimate = false;//隐藏元素
          }, 1000);
        }

    完全なカウンターコンポーネント

    <template>
      <ul class="counter">
        <li @click="showPicker">
          数量
          <span>{
         
         {shopCount}}</span>
        </li>
        <li @click="addShopCar">
          加入购物车
          <span class="icon-jiarugouwuche iconfont"></span>
          <transition enter-active-class="animated zoomOutUp slow">
            <span v-show="showAnimate" class="icon-jiarugouwuche iconfont addIcon"></span>
          </transition>
        </li>
      </ul>
    </template>
    
    <script>
    import Config from "../../config/config";
    const { EventName } = Config;
    export default {
      name: "Counter",
      data() {
        return {
          shopCount: 1,//默认购买商品数量
          showAnimate: false//动画标签隐藏
        };
      },
      created() {
        this.$events.onEvent(EventName.ChangeCount, _count => {//添加事件监听,监听商品数量变化
          this.shopCount = _count;
        });
        this.shopCar = new this.$store.ShopCar();
      },
      destroyed() {
        this.$events.offEvent(EventName.ChangeCount);
      },
      methods: {
        showPicker() {
          this.$events.emitEvent(EventName.ShowPicker);
        },
        addShopCar() {
          this.showAnimate = true;//显示元素
          setTimeout(() => {//延时的目的是等待动画完成
            this.shopCar.countShopItem({//缓存添加购物车数据
              ...this.$route.query,
              shopCount: this.shopCount
            });
            this.showAnimate = false;//隐藏元素
          }, 1000);
        }
      }
    };
    </script>
    <style lang="less" scoped>
    @import "../../style/init.less";
    .counter {
      .h(120);
      .w(850);
      background: @mainColor;
      border-radius: 4rem;
      margin: 0 auto;
      .l_h(120);
      li {
        width: 49%;
        display: inline-block;
        .h(46);
        .l_h(46);
        .titleFont();
        .f_s(32);
        text-align: center;
      }
      li:nth-child(2) {
        margin-left: -2px;
        border-left: 1px dashed #dacda3;
        .addIcon {
          position: fixed;
          .f_s(75);
          z-index: -1;
          color: black;
        }
      }
    }
    </style>

    最後に、グローバルストアにショッピングカート変数処理メソッド追加します

     countShopItem(_data) {
        if (!_data._id) {//阻塞商品id为空现象
          return
        }
        let _shopCar = this.state//获取原购物车列表
        let list = _shopCar.filter(function (item) {
          return item._id === _data._id;//通过id查找购物车中传递项
        });
        if (list.length == 0) {//未找到时新建购物车商品
          _data.sum = _data.shopCount * _data.shopPrice;//商品总价
          _data.isSelect = false//是否选中商品,购物车界面默认值
          _shopCar.push(_data);
        } else if ((_data.shopNum > list[0].shopCount + _data.shopCount) && (list[0].shopCount + _data.shopCount <= 9) && list[0].shopCount + _data.shopCount > 0) {//找到时更新商品
          list[0].shopCount += _data.shopCount;
          list[0].sum = list[0].shopCount * list[0].shopPrice;
        } else if (list[0].shopCount + _data.shopCount <= 0) {//购物车允许最小值
          this.$events.emitEvent(EventName.CountShop, 'min');
          return;
        } else {//购物车允许最大值
          this.$events.emitEvent(EventName.CountShop, 'max');
          return;
        }
        this.state = _shopCar
        this.$events.emitEvent(EventName.CountShop);
      }

    このようにして、簡単な製品詳細ページが完成します

次の記事では、アイテムの削除、すべての選択、注文インターフェースの追加など、ショッピングカートの他の機能の実装を紹介します。

おすすめ

転載: blog.csdn.net/time_____/article/details/108769229
おすすめ