事先聲明,這是一個高仿小米Lite的微信小程序。html
我呢如今是一個大三快大四的學生,這個小程序花了我很長時間,把能寫的功能基本上都寫了。我秉着分享開源的心理,儘可能把我寫的這個小程序怎麼寫的,爲何這樣寫,詳細的告訴你們。爲何是儘可能?這是由於,我不太會說,可能說的不是很清楚,因此只能儘可能.前端
├<assets>
│ ├<images>
├<components>
│ ├<goodList>
│ ├<icon>
│ ├<tabbar>
│ ├<userList>
├<pages>
│ ├<cart>
│ ├<category>
│ ├<deleteGoods>
│ ├<find>
│ ├<goodDetails>
│ ├<index>
│ ├<selectGoods>
│ ├<user>
├<utils>
│ └util.js
├<weui>
│ └weui.wxss
├<wxapi>
│ ├Api.js
│ ├main.js
│ └mock.js
複製代碼
對於初學者來講,可能拿到設計圖就立馬寫,其實這樣很很差,寫出來的代碼會有不少重複的代碼,這樣不利於以後的維護。因此應該把一些公用的代碼封裝,以後直接調用就好了,以後維護起來也更加的方便。git
咱們前端想要獲取頁面的數據,就須要發送HTTP請求後端提供給咱們的API接口,從API接口中獲取咱們想要的數據。在微信小程序中,微信官方給咱們提供了一個方法wx.request來請求.github
一個程序,須要的HTTP請求會不少,若是咱們每一個請求都去寫一個wx.request,這樣寫出來的代碼,看起來會很冗長,他人看咱們的代碼時也會很累,也不利於咱們以後的修改。所以爲了代碼的整潔,和以後的修改方便。我就把全部的API請求請求封裝在wxapi文件目錄下。web
// Api.js
const banners = 'https://www.easy-mock.com/mock/5cf9c392006feb28c7eedf28/banners'
const navdata = 'https://www.easy-mock.com/mock/5cf9c392006feb28c7eedf28/navdata'
const goodList = 'https://www.easy-mock.com/mock/5cf9c392006feb28c7eedf28/goodList'
const category = 'https://www.easy-mock.com/mock/5cf9c392006feb28c7eedf28/category'
const findData = 'https://www.easy-mock.com/mock/5cf9c392006feb28c7eedf28/findData'
const userData = 'https://www.easy-mock.com/mock/5cf9c392006feb28c7eedf28/userData'
const goodDetail = 'https://www.easy-mock.com/mock/5cf9c392006feb28c7eedf28/goodDetail'
const QQ_MAP_KEY = 'NNFBZ-6DRCP-IRLDU-VEQ4F-TXLP2-PFBEN'
const MAPURL = 'https://apis.map.qq.com/ws/geocoder/v1/'
module.exports = {
banners,
navdata,
goodList,
category,
findData,
userData,
goodDetail,
QQ_MAP_KEY,
MAPURL
}
複製代碼
import * as MOCK from "./mock"
import * as API from "./Api"
const request = (url,mock = true,data) => {
let _url = url
return new Promise((resolve, reject) => {
if (mock) {
let res = {
statusCode: 200,
data: MOCK[_url]
}
if (res && res.statusCode === 200 && res.data) {
resolve(res.data)
} else {
reject(res)
}
} else {
wx.request({
url: url,
data,
success(request) {
resolve(request.data)
},
fail(error) {
reject(error)
}
})
}
});
}
// showLoading
const showLoading = () => {
wx.showLoading({
title: '數據加載中',
mask: true,
});
}
// 獲取地理位置
const geocoder = (lat, lon) => {
return request(API.MAPURL,false,{
location: `${lat},${lon}`,
key: API.QQ_MAP_KEY,
get_poi: 0
})
}
module.exports = {
getBanners: () => {
// return request('banners')
return request(API.banners,false) //首頁 banners
},
getNavData: () => {
// return request('navdata')
return request(API.navdata,false) //首頁 navdata
},
getGoodList: () => {
// return request('goodList')
return request(API.goodList,false) //首頁 商品列表
},
getCategroy: () => {
// return request('category')
return request(API.category,false) //分類頁面
},
getFindData: () => {
// return request('findData')
return request(API.findData,false) //發現 頁面
},
getUserData: () => {
// return request('userData')
return request(API.userData,false) // 個人 頁面
},
getGoodDetail: () => {
// return request('goodDetail')
return request(API.goodDetail,false) //商品詳情
},
showLoading,
geocoder
}
複製代碼
看到這裏,可能就會有一些疑問,爲何我在每一個請求後面都加上了一個false?面試
這是由於,我在寫這個微信小程序開始時,沒有使用easy-mock來模擬http請求數據。我是把假數據都放在mock.js文件中。而後使用 **return request('banners')**這種方式就能夠獲取我想要的數據。數據庫
API封裝完了,該怎麼調用呢?我就以首頁的banners數據爲例json
// index.js
const WXAPI = require('../../wxapi/main')
onLoad: function (options) {
WXAPI.showLoading()
this.getBanners()
},
getBanners() {
WXAPI
.getBanners()
.then(res => {
wx.hideLoading()
this.setData({
banners: res.data
})
})
},
複製代碼
記住,若是想要發送HTTP請求數據的頁面,都必須加上這一句const WXAPI = require('../../wxapi/main')小程序
開始準備OK,如今開始寫頁面。第一步要寫的是tabBar部分。後端
看起來是否是有點奇怪,爲何有點透明的感受?由於這個tabBar組件是我本身寫的。
通常來將,直接在把tabBar組件寫在app.json中,就能夠了。
可是我以爲不是那麼好看,因此就本身擼了一個tabBar組件出來。
寫完以後查文檔才發現,微信小程序官方提供了自定義tabBar組件的方法,有須要的能夠查看微信小程序文檔
寫完這個組件後我總解了一下,須要注意的問題.
選中了的當前頁面,再次點擊因該無效。
因此我在app.js中存入了一個page屬性,來存儲當前頁面,而後在點擊事件goToPage()方法中加入判斷去解決。
<!--components/tabbar/tabbar.wxml-->
<view class="tabbar">
<!-- 首頁 -->
<view class="shouye {{on === 'index' ? 'on': ''}}" data-page="index" bindtap="goToPage">
<icon type="shouye" size="42" class="icon" color="{{on === 'index' ? '#f96702': ''}}"/>
<text >首頁</text>
</view>
<!-- 分類 -->
<view class="fenlei {{on === 'category' ? 'on': ''}}" data-page="category" bindtap="goToPage">
<icon type="classify" size="42" class="icon" color="{{on === 'category' ? '#f96702': ''}}"/>
<text >分類</text>
</view>
<!-- 發現 -->
<view class="faxian {{on === 'find' ? 'on': ''}}" data-page="find" bindtap="goToPage">
<icon type="faxian" size="42" class="icon" color="{{on === 'find' ? '#f96702': ''}}"/>
<text >發現</text>
</view>
<!-- 購物車 -->
<view class="gouwuche {{on === 'cart' ? 'on': ''}}" data-page="cart" bindtap="goToPage">
<icon type="gouwuche" size="42" class="icon" color="{{on === 'cart' ? '#f96702': ''}}"/>
<text >購物車</text>
</view>
<!-- 個人 -->
<view class="wode {{on === 'user' ? 'on': ''}}" data-page="user" bindtap="goToPage">
<icon type="wode" size="42" class="icon" color="{{on === 'user' ? '#f96702': ''}}"/>
<text >個人</text>
</view>
</view>
複製代碼
// components/tabbar/tabbar.js
// 全局裏面存了一個page 表示當前 路由
const app = getApp();
Component({
/**
* 組件的屬性列表
*/
properties: {
// 是否選中
on:{
type: String,
value: ''
}
},
/**
* 組件的初始數據
*/
data: {
},
/**
* 組件的方法列表
*/
methods: {
// 跳轉到相應的頁面
// 加了一個判斷
// 由於若是如今顯示的是當前頁面就不須要再跳轉
goToPage(e) {
let page = e.currentTarget.dataset.page || 'user';
if(app.globalData.page === page) {
return ;
}
wx.redirectTo({
url: `/pages/${page}/${page}`,
});
app.globalData.page = page;
}
}
})
複製代碼
/* components/tabbar/tabbar.wxss */
.tabbar {
width: 100%;
height: 100rpx;
background-color: #ffffff;
display: flex;
position: fixed;
bottom: 0;
font-size: 26rpx;
z-index: 99;
}
.shouye,.fenlei,.faxian,.gouwuche,.wode {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
opacity: 0.5;
}
.icon {
height: 60rpx;
}
.on {
color:#f96702;
}
複製代碼
關於如何使用的問題,只須要在,須要tabBar功能的頁面底部加上就能夠.
好比index頁面
<tabbar on="index"></tabbar>
複製代碼
記得在json中引入組件
{
"usingComponents": {
"goodList": "../../components/goodList/goodList",
"tabbar": "../../components/tabbar/tabbar"
}
}
複製代碼
tabBar組件中須要圖標,我使用的是阿里的圖標庫
如何使用?
這個組件很簡單,定義出來就能夠直接使用,而且修改顏色和大小.
<!--components/icon/icon.wxml-->
<text class='iconfont icon-{{type}}' style='color:{{color}}; font-size:{{size}}rpx;'></text>
複製代碼
properties: {
type: {
type: String,
value: ''
},
color: {
type: String,
value: '#000000'
},
size: {
type: Number,
value: '45'
}
},
複製代碼
在首頁中存在不少這樣的商品列表,一個一個寫,這樣寫出來的代碼會致使首頁的代碼顯得不少,而且很差維護,因此我就封裝成了一個組件.
<!--components/goodList/goodList.wxml-->
<view class="goodList-good">
<!-- 商品的圖片 -->
<view class="goodList-good-img">
<image src="{{url}}" mode="aspectFill" />
</view>
<!-- 商品詳細的信息 -->
<view class="goodList-good_detail">
<!-- 名稱 -->
<view class="good_detail_name">
{{name}}
</view>
<!-- 信息 -->
<view class="good_detail_brief">
{{brief}}
</view>
<!-- 價格 -->
<view class="good_detail_price">
<text class="price" >¥{{price}}</text>
<text class="oldPrice" style="display:{{oldPrice == '' ? 'none': 'inline'}};">¥{{oldPrice}}</text>
</view>
</view>
</view>
複製代碼
properties: {
// 圖片連接
url: {
type: String,
value: ''
},
// 名稱
name: {
type: String,
value: ''
},
// 信息
brief: {
type: String,
value: ''
},
// 新的價格
price: {
type: String,
value: ''
},
// 舊的價格
oldPrice: {
type: String,
value: ''
}
},
複製代碼
/* components/goodList/goodList.wxss */
.goodList-good {
position: relative;
width: 100%;
height: 100%;
}
.goodList-good-img {
width: 100%;
height: 312rpx;
position: relative;
}
.goodList-good-img image {
width: 100%;
height: 100%;
}
.goodList-good_detail {
padding: 26rpx 23rpx;
}
.good_detail_name {
width:100%;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
.good_detail_brief {
width:100%;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
font-size: 25rpx;
color: #8c8c8c;
}
.good_detail_price {
display: flex;
justify-content: flex-start;
align-items: flex-end;
}
.good_detail_price .price {
color: #a36d4a;
font-size: 28rpx;
padding-right: 16rpx;
}
.good_detail_price .oldPrice {
font-size: 24rpx;
color: #8c8c8c;
text-decoration: line-through;
}
複製代碼
大家會發現,個人邊框爲何那麼細。
初學者,可能會說,0.5px邊框,不就是border: 0.5px嗎,其實這是錯的。
瀏覽器會把任何小於1px的邊框都解析成1px,因此你寫0.5px其實瀏覽器會解析成1px,這樣就實現不了效果。
其實也很簡單,使用僞類去畫。
例如,goodList組件的右部邊框.
在index頁面的html中,我在包裹goodList的view標籤的class中加上了rightBorder這個類來表示畫出上邊框。
<view class="item topBorder rightBorder" data-id="{{item.id}}" bindtap="goDetails">
<goodList url="{{item.url}}"
name="{{item.name}}"
brief="{{item.brief}}"
price="{{item.price}}"
oldPrice="{{item.oldPrice}}" ></goodList>
</view>
複製代碼
.rightBorder::after {
content: '';
position: absolute;
height: 200%;
width: 1rpx;
right: -1rpx;
top: 0;
transform-origin: 0 0;
border-right: 1rpx solid#e0e0e0;
transform: scale(.5);
z-index: 1;
}
複製代碼
其實畫0.5px邊框就記住。
其它還有一些 細節問題就按照所需寫就行。
只是個人頁面中的一個列表信息,這個很簡單
<!--components/userList/userList.wxml-->
<view class="main">
<image src="{{List.img}}" />
<view class="text" >
<text >{{List.text}}</text>
</view>
<view class="state" wx:if="{{List.state !== ''}}">
<text >({{List.state}})</text>
</view>
</view>
複製代碼
/* components/userList/userList.wxss */
.main {
width: 100%;
height: 120rpx;
display: flex;
align-items: center;
background-color: #fff;
padding: 40rpx;
box-sizing: border-box;
}
.main image {
width: 80rpx;
height: 80rpx;
}
.main .text {
font-size: 32rpx;
padding: 0 10rpx 0 5rpx;
}
.main .state {
font-size: 26rpx;
color: #8c8c8c;
}
複製代碼
properties: {
List: {
type: Object
}
},
複製代碼
我這裏引入的是weui組件的搜索樣式。如何用?
這是微信小程序提供的一個組件swiper,微信小程序開發者文檔
swiper和swiper-item組合起來就能夠實現,一些配置信息,請查看官方文檔
具體代碼
<swiper indicator-dots="{{indicatorDots}}" indicator-active-color="#ffffff" autoplay="{{autoPlay}}" interval="{{interval}}" duration="{{duration}}">
<block wx:for="{{banners}}" wx:key="index">
<swiper-item>
<image src="{{item.imgurl}}" mode="aspectFill" class="banner-image" />
</swiper-item>
</block>
</swiper>
複製代碼
data: {
banners: [],
indicatorDots: true,
autoPlay: true,
interval: 3000,
duration: 1000,
navdata: [],
goodList: [],
goodListOne: {},
name:'',
},
複製代碼
在商城小程序中常常要作一個這樣的功能.例如:
功能要求:
功能要求並不難,可是對於初學者而言,可能會有些問題。我就直接說功能該怎麼作
首先:分析一下,頁面結構是左右佈局。而且兩邊均可以滑動.因此可使用微信給咱們提供的
scroll-view組件.兩個組件就能夠採用float,分佈在左右兩邊.
<!-- miniprogram/pages/category/category.wxml -->
<view class="container">
<!-- 左邊商品的標籤信息 -->
<scroll-view scroll-y scroll-with-animation="{{true}}" class="categroy-left">
<view wx:for="{{categroy}}" wx:key="{{index}}" data-index="{{index}}" bindtap="switchTab" class="cate-list {{curIndex === index ? 'on': ''}}">
{{item[0].name}}
</view>
</scroll-view>
<!-- 右邊 標籤對應的商品信息 -->
<scroll-view scroll-y scroll-into-view="{{toView}}" scroll-with-animation="true" bindscroll="scrollContent" bindscrolltolower="scrollEnd" class="categroy-right">
<block wx:for="{{categroy}}" wx:key="inedx">
<view id="right-list" class="right-list" id="{{index}}">
<view class="right-title">
<text>{{item[0].name}}</text>
</view>
<view class="right-content">
<block wx:for="{{item}}" wx:key="idex" wx:for-item="product" wx:for-index="idex">
<view class="list-detail" wx:if="{{idex > 0}}">
<image src="{{product.picture}}" />
<view class="detail-name">
<text>{{product.desc}}</text>
</view>
</view>
</block>
</view>
</view>
</block>
</scroll-view>
</view>
<tabbar on="category"></tabbar>
複製代碼
/* miniprogram/pages/category/category.wxss */
/*定義滾動條高寬及背景 高寬分別對應橫豎滾動條的尺寸*/
::-webkit-scrollbar
{
width: 0px;
height: 0px;
background-color: pink;
}
.categroy-left {
height: 100%;
width: 150rpx;
float: left;
border-right: 1px solid #ebebeb;
box-sizing: border-box;
position: fixed;
font-size: 30rpx;
padding-bottom: 100rpx;
box-sizing: border-box;
}
.categroy-left .cate-list {
height: 90rpx;
line-height: 90rpx;
text-align: center;
border: 2px solid #fff;
}
.categroy-left .cate-list.on {
color: #ff4800;
font-size: 34rpx;
}
/* 右邊的列表 */
.categroy-right {
width: 600rpx;
float: right;
height: 1334rpx;
/* height: 100%; */
padding-bottom: 100rpx;
box-sizing: border-box;
overflow: hidden;
}
.right-title {
width: 100%;
text-align: center;
position: relative;
padding-top: 30rpx;
/* font-size: 30rpx; */
padding-bottom: 30rpx;
}
.right-title text::before, .right-title text::after {
content: '';
position: absolute;
width: 60rpx;
/* height: 1px; */
top: 50%;
border-top: 1px solid #e0e0e0;
/* transform: scale(.5); */
}
.right-title text::before {
left: 30%;
}
.right-title text::after {
right: 30%;
}
.right-list {
/* height: 100%; */
background-color: #fff;
}
.right-content {
width: 100%;
height: 100%;
display: flex;
flex-wrap: wrap;
}
.right-content .list-detail {
flex-shrink: 0;
width: 33.3%;
height: 100%;
font-size: 26rpx;
text-align: center;
}
.right-content .list-detail image {
width: 120rpx;
height: 120rpx;
padding: 10rpx;
/* background-color: pink; */
}
複製代碼
這個功能的難點就在於js邏輯
先貼出data中須要的數據
data: {
categroy:[], //商品信息
curIndex: 'A', //當前的選中的標籤
toView: 'A', //去到的標籤
// 存入每一個list的高度疊加
heightArr: [],
// 最後一個list,就是最後一個標籤的id
endActive: 'A'
},
複製代碼
這一功能很簡單就能實現
只須要在右邊scroll-view組件中添加事件scroll-into-view="{{toView}}",toView就是商品顯示的id
注意,右邊每一個商品信息,頁面渲染時必須加上id屬性
而後左邊的scroll-view組件只需添加一個點擊事件去修改toView的值就好了
// 點擊左邊標籤要修改的信息
switchTab(e) {
this.setData({
curIndex: e.target.dataset.index,
toView: e.target.dataset.index
})
},
複製代碼
首先須要計算出 右邊商品每一塊佔據的高度,而且存入數組中,能夠放入onReady生命週期中
// 計算出右邊每一個商品佔據的高度
getPageMessage() {
// console.log(4)
let self = this
let heightArr = []
let h = 0
const query = wx.createSelectorQuery()
query.selectAll('.right-list').boundingClientRect()
query.exec( res => {
res[0].forEach( item => {
h += item.height
heightArr.push(h)
})
self.setData({
heightArr: heightArr
})
})
},
複製代碼
在右邊的scroll-view組件中加上事件。bindscroll="scrollContent,這是scroll-view提供的事件,在滑動時就會觸發.
// 頁面滑動時觸發
scrollContent(e) {
const scrollTop = e.detail.scrollTop
const scrollArr = this.data.heightArr
const length = scrollArr.length - 1
let endChar = String.fromCharCode(65 + length)
let curChar = this.getCurrentIndex(scrollTop)
if(this.data.endActive != endChar) {
this.setData({
curIndex: curChar
})
} else {
this.setData({
endActive: 'A'
})
}
},
複製代碼
// 判斷curIndex應該是那個
getCurrentIndex(scrollTop) {
const scrollArr = this.data.heightArr
let find = scrollArr.findIndex(item => {
// 提早10rpx觸發效果
return scrollTop < item - 10
})
let curChar = String.fromCharCode(65 + find)
return curChar
},
複製代碼
以上就能夠實現全部的功能要求了。
可是這樣的滑動並非很完美,右邊滑動到最下面,左邊高亮卻不是最後一個
相對完美效果就是這樣
想要完美一點就要在,右邊scroll-view添加一個事件:bindscrolltolower="scrollEnd"
// 頁面滑動到底部觸發
scrollEnd() {
const scrollArr = this.data.heightArr
const length = scrollArr.length - 1
let endChar = String.fromCharCode(65 + length)
this.setData({
curIndex: endChar,
endActive: endChar
})
},
複製代碼
想要實現這樣的效果並不困難。
邏輯順序: 首頁點擊商品信息 -> 商品詳情頁面顯示對應的商品詳情信息 -> 購物車頁面顯示商品購買的商品信息. -> 修改以後,商品詳情頁面顯示修改的信息。
想要實現這樣的功能,必須有一個 id 在頁面跳轉時,傳入給跳轉的頁面,跳轉的頁面再經過id值獲取頁面所需的數據
例如:首頁 -> 商品詳情頁
這是一條商品的列表的信息,經過點擊事件bindtap="goDetails",跳到對應的頁面.
<view class="list">
<block wx:for="{{goodList}}" wx:key="{{item.id}}">
<view class="item topBorder rightBorder" data-id="{{item.id}}" bindtap="goDetails">
<goodList url="{{item.url}}"
name="{{item.name}}"
brief="{{item.brief}}"
price="{{item.price}}"
oldPrice="{{item.oldPrice}}" ></goodList>
</view>
</block>
</view>
複製代碼
goDetails(e) {
const id = e.currentTarget.dataset.id
wx.navigateTo({
url: `/pages/goodDetails/goodDetails?id=${id}`,
});
},
複製代碼
商品詳情頁:
傳入的id值能夠再onLoad生命週期的options參數上獲取
onLoad: function (options) {
WXAPI.showLoading()
// 獲取用戶的地址信息
const address = wx.getStorageSync('Address');
this.setData({
id: options.id,
address
})
this.getGoodDetail()
},
複製代碼
我是把數據直接存在本地緩存中(也能夠直接存入到雲數據庫中),使用的是 wx.setStorage()
在本地存入了兩個數據,一個是全部購買的商品信息,一個是總的商品購買數量
// 添加到購物車
toAddCart() {
let cartData = wx.getStorageSync('goods') || [];
let data = {
id: this.data.id,
name: this.data.goodData.name,
memory: this.data.memory,
color: this.data.color,
price: this.data.price,
num: this.data.selectNum,
img: this.data.imgSrc,
select: true
}
// wx.removeStorageSync('goods');
cartData.push(data)
const allNum =this.getAllNum(cartData)
wx.setStorage({
key: 'goods',
data: cartData,
success: (res) => {
console.log(res)
let pageIndex = getCurrentPages()
let backIndex = pageIndex.length - 2
wx.navigateBack({
delta: backIndex
})
},
fail: () => {},
complete: () => {}
});
// 存儲數量到storage
wx.setStorageSync('allNum', allNum);
// 寫到外面就可讓showToast 顯示在前一個頁面
setTimeout(()=>{
wx.showToast({
title: '已加入購物車',
icon: 'success',
duration: 2000
});
},500)
},
// 獲取全部的數量
getAllNum(cartData) {
return cartData.reduce((sum, item) => {
return sum + (+item.num)
},0)
},
複製代碼
實現這個功能只須要加一個狀態,點擊時就修改狀態的值,而且修改相關渲染的數據就行。
data: {
state: 'details_img', //判斷概述 參數
}
複製代碼
<view class="summarize-parameter">
<view class="title">
<view class="summarize" bindtap="changeState">
<text class="{{state === 'details_img'? 'on' : ''}}">概述</text>
</view>
<view class="parameter" bindtap="changeState">
<text class="{{state === 'param_img'? 'on' : ''}}">參數</text>
</view>
</view>
<view class="state">
<block wx:for="{{state === 'details_img'? details_img : param_img}}" wx:key="index">
<image src="{{item}}" mode="widthFix"/>
</block>
</view>
</view>
複製代碼
// 改變概述和參數
changeState() {
let state = this.data.state
if(state === 'details_img') {
state = 'param_img'
} else {
state = 'details_img'
}
this.setData({
state
})
},
複製代碼
對比一下上面兩張圖的區別.
在購物頁面中選的商品數量和具體的商品信息,以後跳轉回商品詳情頁面中,對應的數據會修改
<view class="sales" bindtap="goSelectGoods">
<text class="describe">已選</text>
<view class="detail detail-change">
{{default_change.name}}
{{default_change.memory}}
{{default_change.color}}
<text >× {{default_change.num}}</text>
</view>
<view class="right"></view>
</view>
複製代碼
<view class="shopping-img" bindtap="goCart">
<icon type="gouwuche" color="#e0e0e0" size="40"/>
<text wx:if="{{allNum != 0}}">{{allNum}}</text>
</view>
複製代碼
上面時兩塊修改的html結構
在購物頁面點擊確認以後,我默認就把商品添加到購物車中,而且位於數據的最後一條
返回商品詳情頁面時,會從新觸發onShow生命週期的函數。
因此我只須要,在onShow中觸發修改方法就行.
// 改變默認的版本數據 default_change
changeDefauleChange() {
const goods = wx.getStorageSync('goods') || [];
if(goods.length === 0) {
return
}
const id = this.data.id
const default_change = goods[goods.length - 1]
let memory = default_change.memory.toString()
memory = memory.substring(0,memory.length - 4)
default_change.memory = memory
this.setData({
default_change
})
},
複製代碼
這一個三角形是使用CSS畫出來的,並非圖標。
使用CSS畫出一個三角形,也不是那麼困難。使用的是僞類和border屬性
.right:before,
.right:after {
content: '';
position: absolute;
top: 35%;
right: 0;
border-width: 8px;
/* transform: translateY(10000rpx); */
border-color: transparent transparent transparent transparent;
border-style: solid;
transform: rotate(90deg);
}
.right:before {
border-bottom: 8px #aaaaaa solid;
}
.right:after {
right: 1px;
/*覆蓋並錯開1px*/
border-bottom: 8px #fff solid;
}
複製代碼
能夠直接使用微信小程序提供的picker組件,具體配置請查看文檔
先搜索騰訊地圖,而且註冊開發者信息,申請一個密鑰key.
// 獲取地理位置
const geocoder = (lat, lon) => {
return request(API.MAPURL,false,{
location: `${lat},${lon}`,
key: API.QQ_MAP_KEY,
get_poi: 0
})
}
複製代碼
而後把密鑰複製,由於我封裝了全部的API接口。因此使用了 API.QQ_MAP_KEY代替,這裏就填寫申請的密鑰就行.
想要獲取用戶的經緯度信息,可使用wx.getLocation(),就能夠獲取用戶的經緯度信息了.
getLocation() {
wx.getLocation({
type: 'gcj02',
success: this.getAddress,
fail: () => {
this.openLocation()
}
})
},
getAddress(res) {
let { latitude: lat, longitude: lon} = res
WXAPI.geocoder(lat, lon)
.then(res => {
if(res.status !== 0 || !res.result) {
return
}
let {address_component
} = res.result
const Address = {
city: address_component.city,
district: address_component.district
}
wx.setStorageSync("Address", Address);
})
},
複製代碼
由於我未讓用戶受權,因此直接把獲取的地理位置,保存在本地storage中.
獲取的地理位置,就能夠在商品詳情頁面的送至顯示出來
作這個項目的過程來講是快樂的,沒有使用雲函數(頁面數據並很少,我以爲不須要就能夠寫出來了),因此總共加起來寫的時間也很短,不到一個星期就寫完了。寫完以後的那一刻的成就感也很好。若是你以爲這篇文章有幫到你的地方,不妨給個贊吧!同時也很是但願在下方看到給出的建議!最後奉上源碼.若是有須要就自取吧!
最後,說點題外話,由於我是2020屆的畢業生,如今面臨實習壓力。由於須要話時間去看面試題,因此後面寫的一段文章,我只是簡要的把重要的功能邏輯寫了出來,若是寫的不清楚,請見諒。