ゼロから、シンプルなショッピングプラットフォームを構築します(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); }
このようにして、簡単な製品詳細ページが完成します