亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

京東優(yōu)選小程序的實現(xiàn)代碼示例

 更新時間:2020年02月25日 10:50:22   作者:Horace  
這篇文章主要介紹了京東優(yōu)選小程序的實現(xiàn)代碼示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

寫在前面

過年有大把的時光,為何一直宅在家里不出家門看著電腦,這究竟是道德的淪喪還是人性的泯滅...這一切都還得從一只蝙蝠說起...

咳咳,好了不皮了,言歸正傳。微信推出的小程序可謂是輕量又強大,所以最近我也開始了小程序的學(xué)習(xí),學(xué)了挺多也看了很多文檔,但總覺得自己沒學(xué)到什么,感覺很迷茫。正所謂實踐出真知,所以我選擇了從高仿別人的小程序開始,選來選去最后選擇了京東優(yōu)選這個小程序(絕對不是因為它的界面清爽!)。

開發(fā)工具

微信開發(fā)者工具

VS Code

效果速覽

廢話不多說,咱先來搞一波圖片看看,點這里查看更多圖片


項目結(jié)構(gòu)

這個項目我使用的是普通的開發(fā),把所有的數(shù)據(jù)都放在了json-server中模擬。
可能很多人會覺得很奇怪,但這是因為我發(fā)現(xiàn)easy mock的網(wǎng)站經(jīng)常打不開請求失敗非常的不方便,所以我暫時沒有選擇mock數(shù)據(jù),后期有時間我會把數(shù)據(jù)挪到easy mock上。

|-jd_recommend 項目名
  |-api 模擬數(shù)據(jù)接口
    |-db.json 模擬的數(shù)據(jù)
  |-assets 資源文件
    |-icons  圖標(biāo)資源
    |-images 圖片資源
  |-components 組件模塊
    |-navigationBar 自定義導(dǎo)航欄
    |-toast     自定義toast
    |-stepper    有贊vant步進(jìn)器組件
    |-...      其他小程序所需組件
  |-pages 項目頁面
    |-about     關(guān)于頁面
    |-account    我的訂單頁面
    |-afterMarket  售后類型頁面
    |-appointment  我的預(yù)約頁面
    |-buy      填寫訂單信息頁面
    |-commentDetail 評論詳情頁面
    |-discount    優(yōu)惠券頁面
    |-explore    發(fā)現(xiàn)頁面
    |-feedback    反饋頁面
    |-fix      售后頁面
    |-goodsDetail  值得買優(yōu)惠詳情頁面
    |-index     首頁
    |-jd       京東商品詳情頁面
    |-login     登錄頁面
    |-orderDetail  訂單詳情頁面
    |-seller     客服頁面
    |-service    退換/售后頁面
    |-shopCart    購物車頁面
    |-user      個人中心頁面
  |-style 公共樣式
    |-comment.wxss  評論區(qū)樣式
    |-goodsCard.wxss 商品卡片樣式
    |-nav.wxss    導(dǎo)航欄樣式
    |-orderCard.wxss 訂單卡片樣式
    |-popright.wxss  篩選框樣式
    |-popup.wxss   上拉菜單樣式
  |-utils 公共模塊
    |-util.js promise封裝接口
  app.js     全局js
  app.json    全局json配置
  app.wxss    全局wxss

自定義組件

大部分人寫小程序肯定要涉及修改navigationBar的title,微信小程序開發(fā)內(nèi)置了這個組件,可以直接在app.json中配置。但是,自帶的navigationBar的樣子是固定的,你肯定見過長成下面這樣的navigationBar:


相比平時常見的navigationBar,它左上角多了一個返回主頁的按鈕,這對于有多級頁面的小程序來說是非常必要的,不然訪問的層級太深用戶不知道怎么返回主頁。然而,小程序開發(fā)自帶并沒有這個樣子的,好在可以自定義,接下來我們就來自定義一個。

navigationBar

首先,我們構(gòu)建一下頁面的結(jié)構(gòu):

<!-- components/navigationBar/index.wxml -->
<view class='nav-wrap' style='height: {{height*2 + 20}}px;'>
  <!-- 導(dǎo)航欄 中間的標(biāo)題 -->
  <view class='nav-title' style='line-height: {{height*2 + 44}}px;'>{{navbarData.title}}</view>
  <view style='display: flex; justify-content: space-around;flex-direction: column'>
    <!-- 導(dǎo)航欄 左上角的返回按鈕和home按鈕 -->
    <!-- 其中wx:if='{{navbarData.showCapsule}}' 是控制左上角按鈕的顯示隱藏,首頁不顯示 -->
    <view class='nav-capsule' style='height: {{height*2 + 44}}px;' wx:if='{{navbarData.showCapsule}}'>
      <!-- 左上角的返回按鈕,wx:if='{{!share}}'空制返回按鈕顯示 -->
      <view bindtap='_navback'>
        <image src='../../assets/icons/back.png' mode='aspectFill' class='back-pre'></image>
      </view>
      <view class='navbar-v-line' wx:if='{{!share}}'></view>
      <view bindtap='_backhome'>
        <image src='../../assets/icons/back_home.png' mode='aspectFill' class='back-home'></image>
      </view>
    </view>
  </view>
</view>

這就是一個很普通的頁面結(jié)構(gòu),值得注意的是,它的高度是根據(jù)獲取的設(shè)備的高度來確定的。
接下來又到了切圖仔上線的時候了(誤):

/* components/navigationBar/index.wxss */
/* 頂部要固定定位  標(biāo)題要居中  自定義按鈕和標(biāo)題要和右邊微信原生的膠囊上下對齊 */
.nav-wrap {
  position: fixed;
  width: 100%;
  top: 0;
  background: #fff;
  color: #000;
  z-index: 9999999;
  border-bottom: 1rpx solid #EFEFF4;
}
/* 標(biāo)題要居中 */
.nav-title {
  position: absolute;
  text-align: center;
  max-width: 400rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  font-size: 36rpx;
  color: #2c2b2b;
  /* font-weight: 600; */
}
.nav-capsule {
  display: flex;
  align-items: center;
  margin-left: 30rpx;
  width: 140rpx;
  justify-content: space-between;
  height: 100%;
}
.navbar-v-line {
  width: 1px;
  height: 32rpx;
  background-color: #e5e5e5;
}
.back-pre, .back-home {
  width: 32rpx;
  height: 36rpx;
  margin-top: 4rpx;
  padding: 10rpx;
}
.nav-capsule .back-home {
  width: 36rpx;
  height: 40rpx;
  margin-top: 3rpx;
}
// components/navigationBar/index.js
const app = getApp()
Component({
 properties: {
  navbarData: {  //navbarData  由父頁面?zhèn)鬟f的數(shù)據(jù),變量名字自命名
   type: Object,
   value: {},
   // observer: function (newVal, oldVal) { }
  }
 },
 data: {
  height: '',
  //默認(rèn)值 默認(rèn)顯示左上角
  navbarData: {
   showCapsule: 1
  }
 },
 attached: function () {
  // 定義導(dǎo)航欄的高度  方便對齊
  this.setData({
   height: app.globalData.height
  })
 },
 methods: {
  // 返回上一頁面
  _navback() {
   wx.navigateBack()
  },
  //返回到首頁
  _backhome() {
   wx.switchTab({
    url: '/pages/index/index',
   })
  }
 }
}) 

京東優(yōu)選小程序這里的兩個按鈕都是返回首頁,我在開發(fā)的時候覺得不對勁,所以我改過來了。
在這里還去取了一下全局定義的變量,也就是獲取的設(shè)備頂部窗口的高度(不同設(shè)備窗口高度不一樣,根據(jù)這個來設(shè)置自定義導(dǎo)航欄的高度),在app.js中要定義一下:

app.js
App({
 onLaunch: function () {
  ......
  wx.getSystemInfo({
   success: (res) => {
    this.globalData.height = res.statusBarHeight
   }
  })
 },
 globalData: {
  ...
  height: 0
 }
})

記得自定組件的時候一定要在json中寫成自定義組件

// components/navigationBar/index.json
{
 "component": true
}

接下來就是調(diào)用該組件了

<navigationBar navbar-data='{{navbarData}}'></navigationBar>

別忘了在要引用頁面的json中引入該組件

"usingComponents": {
  "navigationBar": "../../components/navigationBar/index"
 }

Toast

Toast同樣也是小程序開發(fā)已經(jīng)做好給你用的了,雖然它可以支持替換里面的圖標(biāo),但是你會發(fā)現(xiàn)很雞肋的一點是,如果你想顯示兩行文字你就沒辦法做到了。我在開發(fā)過程中也搜索過相關(guān)的實現(xiàn)方法,找到了大部分是說在要換行的文字后背加上rn就能實現(xiàn)了,但是我自己親測無效,所以實在忍不住也自己做了一個。

<!-- components/toast/index.wxml -->
<!-- 距離頂部高度由業(yè)務(wù)需要動態(tài)確定 -->
<view class='mask' hidden="{{hide}}" style='top: {{toastData.top}}'>
  <image class="image" src='../../assets/icons/{{toastData.icon}}.png' mode='aspectFit'></image>
  <view class="info">
    <view class='info1' wx:if="{{toastData.info1 != ''}}">{{toastData.info1}}</view>
    <view class="info2" wx:if="{{toastData.info2 != ''}}">{{toastData.info2}}</view>
  </view>
</view>
/* components/toast/index.wxss */
.mask {
  width: 440rpx;
  height: auto;
  border-radius: 20rpx;
  position: fixed;
  left: 155rpx;
  z-index: 1000;
  background: rgba(0, 0, 0, 0.6);
  text-align: center;
  padding-bottom: 30rpx;
}
.image {
  z-index: 1000;
  width: 80rpx;
  height: 80rpx;
  padding-top: 30rpx;
  padding-bottom: 20rpx;
}
.info1, .info2 {
  color: #ffffff;
  font-size: 32rpx;
}
.info {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
// components/toast/index.js
Component({
 properties: {       //定義組件屬性
  toastData: {      //用來顯示提示信息
   type: Object,     // 類型(必填),目前接受的類型包括:String, Number, Boolean, Object, Array, null(表示任意類型)
   value: {
    icon: 'success'
   }   // 屬性初始值(可選),如果未指定則會根據(jù)類型選擇一個
  },
 },
 data: {
  hide: true
 },
 methods: {
  showToast: function () {
   let that = this;
   that.setData({
    hide: false
   });
  },
  hideToast: function (e) {
   let that = this;
   setTimeout(function () {
    that.setData({
     hide: true
    });
   }, 2000);
  }
 }
})

這里給組件定義了兩個方法,是用來顯示和隱藏Toast的。這里要注意一下,調(diào)用給自定義組件定義方法要先在頁面上獲取該組件

<toast id="toast" toast-data="{{toastData}}"></toast>
Page({
  data: {
  toastData: { // toast需要的參數(shù)
   icon: "success",
   info1: "加入購物車成功",
   top: "50%"
  }
 },
 onReady() {
  this.toast = this.selectComponent("#toast");
 }
})

然后在需要觸發(fā)Toast的事件中寫上這兩句:

this.toast.showToast()
this.toast.hideToast()

功能實現(xiàn)

導(dǎo)航

所謂導(dǎo)航,也是很常見了,就是根據(jù)選擇欄目的不同,顯示不同的類別內(nèi)容。例如:


功能要求:

  1. 點擊導(dǎo)航欄目,顯示對應(yīng)的欄目數(shù)據(jù)。
  2. 如果欄目中沒有東西,要顯示對應(yīng)的提示信息。

實現(xiàn)它的功能并不難,直接sroll-view往上懟。個人覺得,京東優(yōu)選在這里有一點不足的地方就是,如果點擊了偏右側(cè)的導(dǎo)航欄目的話,導(dǎo)航條不會跟著右移顯示后面的項目,可能它的開發(fā)者有不一樣的想法吧。

<view class="navigator">
 <scroll-view scroll-x="true" class="nav" scroll-left="{{navScrollLeft}}" scroll-with-animation="{{true}}">
  <block wx:for="{{navData}}" wx:for-index="id" wx:for-item="navItem" wx:key="id">
   <view class="nav-item {{currentTab == id?'active':''}}" data-name="{{navItem.name}}" data-current="{{id}}" bindtap="switchNav">
    {{navItem.name}}
   </view>
  </block>
 </scroll-view>
</view>

通過js可以實現(xiàn)動態(tài)的填放數(shù)據(jù),這里設(shè)置的current就是當(dāng)前選擇的欄目,可以根據(jù)這個改變樣式等。

switchNav(e) {
    const cur = e.currentTarget.dataset.current; // Number
    let currData = []
    // console.log(cur.toString());
    if (cur === 0) {
      currData = this.data.goods
    } else {
      this.data.goods.forEach(val => {
        if (val.category === cur.toString()) {
          currData.push(val)
        }
      })
    }
    this.setData({
      currentTab: cur,
      category: cur,
      currData
    });
}

如果是要實現(xiàn)點擊之后自動向點擊的方法滑出顯示更多的內(nèi)容,可以通過動態(tài)改變navScrollLeft的值去實現(xiàn),這里我就不細(xì)說了,不過我在實現(xiàn)的時候還是花了一番功夫,實現(xiàn)的不是很好所以就沒有放在代碼里,如果你以后想做出這種效果的導(dǎo)航欄建議去網(wǎng)上搜一搜demo看懂了之后借過來用一用,畢竟傳說程序猿最高的境界是復(fù)制粘貼,狗頭(誤)

上拉菜單和篩選框

這兩個比較相似,只是拉出的位置不一樣,這里我就舉一個篩選框的例子,我們先看看它長啥樣:


我們先看看結(jié)構(gòu),這里我省略了中間的一些內(nèi)容:

<!-- 點擊篩選彈出的選擇菜單 -->
<view class="float {{isRuleTrue?'isRuleShow':'isRuleHide'}}">
  <view class="animation-element" animation="{{animation}}">
    ...中間自己放的具體內(nèi)容...
    <!-- 底部的兩個按鈕 -->
    <view class='bottom'>
      <view class="animation-reset" bindtap="reset">重置</view>
      <view class="animation-button" bindtap="success">確定</view>
    </view>
  </view>
</view>
/* 篩選彈框 */
/* 彈框的布局 */
.isRuleShow {
  display: block;
}
.isRuleHide {
  display: none;
}
.float {
  height: 100%;
  width: 100%;
  position: fixed;
  z-index: 999;
  top: 0;
  left: 0;
  /* 彈出后背景的顏色 */
  background-color: rgba(0, 0, 0, 0.5);
  padding-left: 30rpx;
  padding-left: 30rpx;
  /* margin-top:80rpx; */
}
.animation-element {
  width: 600rpx;
  height: 100%;
  padding-left: 30rpx;
  padding-right: 30rpx;
  background-color: #ffffff;
  border: 1px solid #f3f0f0;
  position: absolute;
  right: -550rpx;
  box-sizing: border-box;
}
.bottom {
  width: 600rpx;
  height: 110rpx;
  font-size: 32rpx;
  padding-top: 55rpx;
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
}
.animation-reset {
  width: 50%;
  height: 100%;
  line-height: 50%;
  text-align: center;
  padding-top: 55rpx;
  border-top: 1px solid #EFEFF4;
}
.animation-button {
  width: 50%;
  height: 100%;
  line-height: 50%;
  color: #fff;
  text-align: center;
  background-color: #ED7358;
  padding-top: 55rpx;
}

重點是它的顯示和隱藏事件,需要用到animation,如果有不熟悉animation,可以去參考一些資料,或者是官方文檔。同樣,我也去掉了我實現(xiàn)其他業(yè)務(wù)的一些內(nèi)容。

showSelect() { // 顯示選擇菜單
  this.setData({
   isRuleTrue: true
  })
  // 左偏移245 step表示一個動作的開始
  this.animation.translate(-245, 0).step()
  this.setData({ animation: this.animation.export() })
 },
 success: function () { // 關(guān)閉選擇菜單
  this.setData({
   isRuleTrue: false,
   selected: true
  })
  this.animation.translate(0, 0).step()
  this.setData({ animation: this.animation.export() })
 },

購物車邏輯


要實現(xiàn)這樣的效果并不困難,需要自己思路清晰,不能被繞進(jìn)去了。實現(xiàn)加入購物車并不難,細(xì)節(jié)是購物車圖標(biāo)右上角的數(shù)字要根據(jù)加入購物車的數(shù)量進(jìn)行動態(tài)的改變,還要注意如果是同一件商品就不需要添加新的,只需要修改原來的數(shù)量。

在這里我使用的是小程序的wx.setStorage()實現(xiàn)的:

<view class='bottom'>
  <view class="animation-reset" bindtap="addCart">加入購物車</view>
  <view class="animation-button" bindtap="buy">立即購買</view>
</view>
addCart() { // 加入購物車
  this.setData({
   toastData: { // toast需要的參數(shù)
    icon: "success",
    info1: "加入購物車成功",
    top: "50%"
   }
  })
  this.toast.showToast()
  this.toast.hideToast()
  this.hideModal()
  // 真正實現(xiàn)添加購物車的部分
  let cartData = wx.getStorageSync('cart') || [];
  let count = 0
  cartData.map(val => {
   if (val.title === this.data.currData[0].title && val.type === this.data.choose_value) {
    val.num += this.data.num
    count++ // 標(biāo)記是否有找到相同的商品
   }
  })
  if (count === 0) { // 沒找到 添加新的商品信息進(jìn)購物車
   let data = {
    id: this.data.currData[0]._id,
    title: this.data.currData[0].title,
    weight: "0.78kg",
    type: this.data.choose_value,
    num: this.data.num,
    price: this.data.currData[0].plain_price,
    img: this.data.currData[0].thumb,
    discount: 20,
    select: true // 是否選中,方便后續(xù)計算總價
   }
   cartData.push(data)
  }
  // 刷新購物車圖標(biāo)上的數(shù)量
  let allNum = 0
  cartData.forEach(val => {
   allNum += val.num
  });
  this.setData({
   allNum
  })
  wx.setStorage({
   key: 'cart',
   data: cartData
  })
 },

這里你可以根據(jù)自己的開發(fā)來決定方式,如果你使用的是云開發(fā)的話,可以選擇把數(shù)據(jù)存進(jìn)云數(shù)據(jù)庫里。

回到頂部


這也是一個老生常談的功能,當(dāng)你滑到頁面比較后的位置的時候需要快速回頂。這里要記住,用swiper實現(xiàn)。首先是在頁面上擼一個回到頂部的圖標(biāo)出來:

<!-- 滑動一段距離后顯示返回頂部的按鈕 -->
<scroll-view class="bigWrap" 
  scroll-y="true" 
  scroll-top="{{scrollTop}}" 
  bindscroll="scroll" 
  style="position: absolute; left: 0; top:0; bottom: 0; right: -999rpx;">
<view class="goTop" bindtap="goTop" wx:if="{{&& floorstatus}}">
  <image class="icon_goTop" src="../../assets/icons/back_to_top.png"></image>
</view>
</scroll-view>

{{scrollTop}}用來表示滑動的時候距離頂部的位置。它的樣式也很簡單,使用固定定位把它定在屏幕上,這里一定要注意頁面的層級,不然它可能會被其他組件給遮擋掉!

/* 回到頂部 */
.goTop {
  position: fixed;
  bottom: 200rpx;
  right: 20rpx;
  width: 65rpx;
  height: 65rpx;
  border: 1px solid #DDDDDD;
  border-radius: 50%;
  background-color: #fff;
  text-align: center;
}
.icon_goTop {
  width: 40rpx;
  height: 40rpx;
  padding-top: 12rpx;
  padding-left: 2rpx;
}
 goTop(e) { // 回到頂部
  this.setData({
   scrollTop: 0
  })
 }

你肯定也注意到了,當(dāng)滑到了一定距離的時候它才顯示出來,這就要靠swiper綁定的滾動事件了:

scroll(e) { // 滾動事件
  // 容器滾動時將此時的滾動距離賦值給 this.data.scrollTop
  let floorstatus = false
  if (e.detail.scrollTop > 300) {
   floorstatus = true
  }
  this.setData({
   floorstatus
  })
}

功能大致先說這么一點,可能在大??雌饋矶际切┖苋菀撞黄鹧鄣墓δ?,但是對應(yīng)我這個初學(xué)者來說還是有點困難的,希望如果有大牛看了我的一些功能的實現(xiàn)之后我不會被罵死。

值得注意的一點

做過小程序開發(fā)或者是vue等開發(fā)的人一定聽過事件冒泡這個名詞:子元素的事件觸發(fā)了父元素的事件,例如點擊事件。我就是那個幸運鵝,我在開發(fā)的時候就遇到了這個情況。
在購物車中點擊商品可以跳轉(zhuǎn)商品詳情,但是我一開始把跳轉(zhuǎn)事件綁定在了每個商品卡片上,這樣就導(dǎo)致了點擊修改商品數(shù)量的時候修改了數(shù)字但是也會直接跳轉(zhuǎn)商品詳情,比如下面這樣...

這就很不友好了,用戶體驗很差,關(guān)于事件冒泡,微信小程序的解決方法是把bindtap替換成catchtap,這樣可以阻止子元素事件向上冒泡。

然而巧的是,我就是那個最幸運的鵝,步進(jìn)器我用的是有贊Vant Weapp組件庫里的,我搜索了很多資料都沒有找到有效的解決方案,差點就放棄使用組件庫了,好在最后發(fā)現(xiàn)京東優(yōu)選小程序購物車綁定的跳轉(zhuǎn)事件是在商品的圖片和標(biāo)題上。

這一點還是比較重要的,所以大家在開發(fā)的時候一定要考慮事件的冒泡,這也是我把它放在最后來寫的原因。

寫在后面

最后,我想說的是小程序開發(fā)真的不容易,開發(fā)一個好的小程序更是需要考慮性能和用戶體驗的方方面面。當(dāng)我覺得自己第一個小程序差不多要完工的時候真的要跳起來唱joyful了(誤)。作為一個程序猿真的不容易,難怪是個容易掉發(fā)的群體。但好在愿意分享技術(shù)的人很多,在這次開發(fā)的過程中我也查閱了很多的資料、社區(qū)和文檔。小程序的學(xué)習(xí)我也不會停下腳步,這個項目還有非常多做的不好的地方,我發(fā)出來也是希望大家和我進(jìn)行交流分享,后期我也會繼續(xù)完善優(yōu)化這個小程序項目。希望我的作品可以對那些初學(xué)小程序的人有所幫助。

最后附上我的github項目地址:https://github.com/tearill/jd_recommend
如果你覺得這個項目還不錯或者是對你有所幫助的話歡迎star,你點亮的每一個star將都是我前進(jìn)的動力!

到此這篇關(guān)于京東優(yōu)選小程序的實現(xiàn)代碼示例的文章就介紹到這了,更多相關(guān)京東優(yōu)選小程序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論