微信小程式——商城篇

llzzzz發表於2018-06-05

前言

隨著wepy和mpvue的出現及流行,開發小程式變的越來越便捷和強大,作為基佬社群的一份子,我們都需要把自己遇到的問題以及如何解決的方式相互分享,這樣才能幫助到更多的朋(ji)友(lao)。如有寫的不足的地方,請各位提出寶貴的建議哈。

微信小程式——商城篇

簡單介紹微信小程式


眾所周知,小程式是一種不需要下載安裝即可使用的應用,它實現了應用“觸手可及”的夢想,使用者掃一掃或者搜一下即可開啟應用。也體現了“用完即走”的理念,使用者不用關心是否安裝太多應用的問題,因此它的開發程度也較為簡單。

  • 開發技術: WXML(HTML5)、WXSS(CSS)、JavaScript
  • 開發工具: vscode(可以使用下列幾種框架來進行開發),微信開發者工具
  • 開發思路: MVVM,簡單來說,這就是一門把前端開發者從操作DOM的繁瑣步驟中解脫出來,讓資料自動更新介面的技術。
  • 開發流程: 這個大家可以看官方的文件,下載安裝開發工具以後使用appid就可以進行開發了。小程式簡易教程
  • 開發單位: rpx,pt,rem等,具體在這裡就不介紹了
  • 開發框架: 這裡介紹幾種小程式的框架,有weui,wepy,mpvue等,有興趣的同學可以自主去了解一下

作為一枚前端戰場的工兵,自然少不了踩雷,而且不用框架元件式開發來手動切頁面有點小心酸~~在這裡我分享幾個自己用原生微信小程式開發遇到的坑,

微信小程式——商城篇

1. 微信小程式之wx.showModal

給confirm/cancel屬性設定字型顏色的時候會有一個小坑, mode程式碼:

<view bindtap="test">
    <text>測試</text>
</view>

js程式碼:
test(e) {
    wx.showModal({
        content: '測試',
        cancelColor: 'red',
        confirmColor: 'rgb(255,0,0)'
    })
}
複製程式碼

這樣的程式碼在模擬器上顯示一切正常,兩個按鈕也的確變顏色了。可是在手機上一看,傻眼了

微信小程式——商城篇
原來這2個按鈕的顏色值只支援十六進位制的。

js程式碼:
test(e) {
    wx.showModal({
        content: '測試',
        cancelColor: '#FF0000',
        confirmColor: '#FF0000'
    })
}
複製程式碼

這樣兩個按鈕就在手機上也能出來了,並且顏色得到了改變。


2. 微信小程式之navigator跳轉

微信小程式——商城篇
在進入商品詳情頁以後,點選左下角的home圖示原應該跳轉到首頁,但是一直點也不跳,而且也不報錯。
微信小程式——商城篇

wxml程式碼:

<navigator hover-class="none"  url="/pages/index/index">
    <image src="/libs/images/home.png"></image>
</navigator>
複製程式碼

仔細檢視了路徑無誤和字母沒打錯以後,這個問題卡了我半個小時以後終於發現這裡有一個不夠細心就會踩的坑,

常用wx.switchTab 介面的同學可能沒碰到過這種情況。navigator元件裡有一個屬性是open-type,預設值是navigate,對應 wx.navigateTo 或 wx.navigateToMiniProgram 的功能。

聰明的同學應該已經看出問題所在了,是的,這裡要跳轉的首頁就是一個tabBar頁面,按照預設的跳轉方式是不能實現的。
解決方法:

<navigator hover-class="none" open-type="switchTab" url="/pages/index/index">
    <image src="/libs/images/home.png"></image>
</navigator> 
複製程式碼

加一個open-type="switchTab" 或者繫結一個點選事件用wx.switchTab介面來實現。


3. 微信小程式之scroll-x

微信小程式——商城篇
小程式的scroll-view元件還有一個橫向滑動的屬性:scroll-x
但是對於類似我這樣的新手來說,設定scroll-x的時候,會把要滑動的內容給擠成多行。
在這裡直接給出一個解決方法:

  1. 給scroll-x設定一個寬度,並設定white-space: nowrap屬性 //內容不換行
  2. 把內容view盒子設定為行內塊元素 display: inline-block

    即可解決橫向滑動內容不在一行的問題,在下面我簡單貼一下專案中我這塊內容的程式碼。

微信小程式——商城篇

微信小程式——商城篇


4. swiper元件和input元件一起用

問題:如果把一個input元件絕對定位到swiper元件上,swiper還是會覆蓋input元件,而input元件內的placeholder屬性則會透出來,雖然不影響input的功能,但是會影響到input屬性的顯示效果,也就是影響了視覺上的效果。

模擬器上的效果

需要的效果

手機上的效果

微信小程式——商城篇
程式碼:

<view class="hd"> 
    <input  class="input" placeholder="搜尋商品,共9803款好物" bindtap="entrySearch" disabled />
    <swiper class="receive">
        <swiper-item >
          <navigator url="/pages/index/receive/receive" hover-class="none">
            <image class="receive_img" src="/libs/images/index.jpg" mode="aspectFill"></image>
          </navigator>
        </swiper-item>
    </swiper>
</view> 
複製程式碼
.input {
  position: absolute;
  left: 30rpx;
  top: 10rpx;
  box-sizing: border-box;
  width: 690rpx;
  height: 56rpx;
  border-radius: 45rpx;
  border: 1rpx solid #000;   //證明自己的猜測
  background-color: #fff;
  box-shadow: 0 0 1rpx #ccc;
  text-indent: 185rpx;
  font-size: 0.8rem;
  
}
.receive {
  height: 380rpx;
}
.receive_img {
  width: 750rpx;
  height: 380rpx;  
}
複製程式碼

我們可以看到模擬器上顯示正常,但是在手機上就成了方型的框,我開始排查問題,我猜測是被覆蓋了?於是我就新增了border: 1rpx solid #000;這行程式碼,進行重新整理以後發現黑線邊框出來了一下馬上就消失了,果然!用了絕對定位都被覆蓋了。

解決方法: 給input元件加個z-index:2 。 當然,建議給input元件再套一個view盒子。
程式碼:

<view class="hd"> 
   <view class="inputSearch"> 
    <input  class="input" placeholder="搜尋商品,共9803款好物" bindtap="entrySearch" disabled />
   </view> 
  <swiper class="receive">
    <swiper-item >
      <navigator url="/pages/index/receive/receive" hover-class="none">
        <image class="receive_img" src="/libs/images/index.jpg" mode="aspectFill"></image>
      </navigator>
    </swiper-item>
  </swiper>
</view> 
.inputSearch {
   position: absolute;
  left: 30rpx;
  top: 10rpx;
  box-sizing: border-box;
  width: 690rpx;
  height: 56rpx;
  border-radius: 45rpx;
  z-index: 2;    
  background-color: #fff;
  box-shadow: 0 0 1rpx #ccc; 
}
.input {
  text-indent: 185rpx;
  font-size: 0.8rem;
  
}
.receive {
  height: 380rpx;
}
.receive_img {
  width: 750rpx;
  height: 380rpx;  
}
複製程式碼


5. 微信小程式之scroll-into-view

我在這裡就一種能實現的方法,假資料可以通過easymock造一下再wx.request引入,也可以直接放到一個js檔案裡import引入,這裡不詳細講解。

一開始我以為是用兩個scroll-view來做,通過scroll-into-view這個屬性來實現左右關聯進行滾動的效果

微信小程式——商城篇

程式碼:

<view class="main">
      <scroll-view class="menu-left" scroll-y scroll-with-animation="{{true}}">
        <view class="cate-list {{curIndex==index?'on':''}}" wx:for="{{menu}}" wx:key="{{item.id}}" data-id="{{item.id}}" data-index="{{index}}" bindtap="switchCategory">
            <text>{{item.name}}</text>
        </view>
    </scroll-view>  
     <scroll-view  scroll-y class="menu-right" scroll-into-view="{{toView}}">
      <block wx:for="{{detail}}" wx:key="{{item.id}}">
          <scroll-view class="cate-box" id="{{item.id}}" scroll-y>
              <view class="cate-banner" bindtap="bannerDetails">
                  <image src="{{item.banner}}"></image>
              </view>
              <view class="cate-title">
                  <text>{{item.title}}</text>
              </view>
              <view class="cate-product">
                  <view class="product-list" bindtap="productDetails" wx:for="{{item.productList}}" wx:key="{{index}}" wx:for-item="product">
                      <image src="{{product.thumb}}"></image>
                      <view class="product-list-name">
                          <text>{{product.name}}</text>
                      </view>
                  </view>
              </view>
          </scroll-view>
      </block>
    </scroll-view>
</view>
//css程式碼就不放了,手動擼的有點多,如有需要可以去github裡拿
//js相關程式碼
  switchCategory(e) {
    console.log(e)
    this.setData({
      toView:e.currentTarget.dataset.id
    })
  },

複製程式碼

看完這個效果以後我就覺得好low啊。。最蛋疼的是右邊竟然可以上下滾動,這樣一來,右邊的商品內容多的時候就會形成兩個scroll-view的巢狀,導致使用者體驗極不友好。

微信小程式——商城篇
於是無腦的檢視了小程式文件以後,我發現swiper元件和scroll-view一樣還有一個縱向滑動的屬性vertical,而且是有swiper的過渡效果,使得切換的時候不會太僵硬。於是我更改了部分wxml程式碼,實現了下圖中右邊不能上下滾動,只能依靠左側的nav來切換的效果

微信小程式——商城篇
程式碼:

<view class="main">
      <scroll-view class="menu-left" scroll-y scroll-with-animation="{{true}}">
        <view class="cate-list {{curIndex==index?'on':''}}" wx:for="{{menu}}" wx:key="{{item.id}}" data-id="{{item.id}}" data-index="{{index}}" bindtap="switchCategory">
            <text>{{item.name}}</text>
        </view>
    </scroll-view>  
     <swiper vertical="true" class="menu-right" current="{{toView}}" >
        <swiper-item wx:for="{{detail}}" wx:key="{{item.id}}">
            <scroll-view class="cate-box" id="{{item.id}}" scroll-y>
                <view class="cate-banner" bindtap="bannerDetails">
                    <image src="{{item.banner}}"></image>
                </view>
                <view class="cate-title">
                    <text>{{item.title}}</text>
                </view>
                <view class="cate-product">
                    <view class="product-list" bindtap="productDetails" wx:for="{{item.productList}}" wx:key="{{index}}" wx:for-item="product">
                        <image src="{{product.thumb}}"></image>
                        <view class="product-list-name">
                            <text>{{product.name}}</text>
                        </view>
                    </view>
                </view>
            </scroll-view>
        </swiper-item>
    </swiper> 
</view>
//js相關程式碼
  switchCategory(e) {
    console.log(e)
    this.setData({
      curIndex: e.currentTarget.dataset.index?e.currentTarget.dataset.index:0,
      toView:e.currentTarget.dataset.index,
    })
  },
複製程式碼

6. 微信小程式購物車商品左滑刪除功能

在這裡我給出一種實現購物車商品左滑刪除的方法,給大家參考,直接放程式碼吧 demo程式碼:

wxml:
<view class="{{item.isTouchMove ? 'touch-move-active' : ''}}" wx:for="{{lists}}" wx:key="{{index}}" data-index="{{index}}" bindtouchstart="touchstart" bindtouchmove="touchmove">
    <view class="content">{{item.tt}}</view>
    <view class="del" catchtap="del">刪除</view>
</view>
wxss:
.del {
    background-color: #b4282d;
    width: 90px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #fff;
    -webkit-transform: translateX(90px);
    transform: translateX(90px);
    -webkit-transition: all 0.4s;
    transition: all 0.4s;
  }
  .content {
    float: left;
    width: 100%;
    margin-right:0;
    -webkit-transition: all 0.4s;
    transition: all 0.4s;
    -webkit-transform: translateX(90px);
    transform: translateX(90px);
    margin-left: -90px;
    display: flex;
  }
.touch-move-active .content,
.touch-move-active .del {
    -webkit-transform: translateX(0);
    transform: translateX(0);
}

複製程式碼
js部分
  data: {
    lists: [
      {
        tt:'測試',
        isTouchMove: false
      },
      {
        tt: '測試',
        isTouchMove: false
      },
      {
        tt: '測試',
        isTouchMove: false
      },
      {
        tt: '測試',
        isTouchMove: false
      },
    ]
  },
  // 計算手滑動角度函式
  angle: function (start, end) {
    var _X = end.X - start.X,
      _Y = end.Y - start.Y
    //返回角度 /Math.atan()返回數字的反正切值
    return 360 * Math.atan(_Y / _X) / (2 * Math.PI);
  },
  touchstart(e) {
    //開始觸控時 重置所有刪除
    this.data.lists.forEach(function (v, i) {
      if (v.isTouchMove)//只操作為true的
        v.isTouchMove = false;
    })
    this.setData({
      startX: e.touches[0].clientX,
      startY: e.touches[0].clientY,
      lists: this.data.lists
    })
  },
  //滑動事件處理
  touchmove(e) {
      let index = e.currentTarget.dataset.index;//當前索引
      let startX = this.data.startX;//開始X座標
      let startY = this.data.startY;//開始Y座標
      let touchMoveX = e.touches[0].clientX;//滑動變化座標
      let touchMoveY = e.touches[0].clientY;//滑動變化座標
      //獲取滑動角度
      let angle = this.angle({ X: startX, Y: startY }, { X: touchMoveX, Y: touchMoveY });
    this.data.lists.forEach((v, i)=> {
      v.isTouchMove = false
      //滑動超過30度角 return
      if (Math.abs(angle) > 30) return;
      if (i == index) {
        if (touchMoveX > startX) //右滑
          v.isTouchMove = false
        else //左滑
          v.isTouchMove = true
      }
    })
    //更新資料
    this.setData({
      lists: this.data.lists
    })
  },
  //刪除事件
  del(e) {
    this.data.lists.splice(e.currentTarget.dataset.index, 1)
    this.setData({
      lists: this.data.lists,
      
    })
  },
複製程式碼

大家可以根據自己的需求做相應的修改。放下效果圖

微信小程式——商城篇

7. 微信小程式購物車

購物車頁面邏輯的話,要按業務需求來。我這裡簡單提供一個購物車邏輯的demo,新手可以看下 購物車功能


結語

商城類微信小程式專案學習github傳送門

筆者踩了不少的坑,這裡只寫出了幾個,如果用框架的話會更方便,作為一枚前端的工兵,還是得經常踩坑,才能得到進階的機會~
第一次寫文章,請給新手多一點鼓勵,給工兵多一點關愛,點個贊-留下您的建議再走吧~

微信小程式——商城篇

相關文章