使用Taro實(shí)現(xiàn)小程序商城的購(gòu)物車功能模塊的實(shí)例代碼
Taro 是一套遵循 React 語法規(guī)范的 多端開發(fā) 解決方案。
現(xiàn)如今市面上端的形態(tài)多種多樣,Web、React-Native、微信小程序等各種端大行其道,當(dāng)業(yè)務(wù)要求同時(shí)在不同的端都要求有所表現(xiàn)的時(shí)候,針對(duì)不同的端去編寫多套代碼的成本顯然非常高,這時(shí)候只編寫一套代碼就能夠適配到多端的能力就顯得極為需要。
使用 Taro,我們可以只書寫一套代碼,再通過 Taro 的編譯工具,將源代碼分別編譯出可以在不同端(微信/百度/支付寶/字節(jié)跳動(dòng)/QQ/京東小程序、快應(yīng)用、H5、React-Native 等)運(yùn)行的代碼。
官方文檔:https://nervjs.github.io/taro/
項(xiàng)目已上傳GitHub:https://github.com/LazyTraveller/Jerry-Taro-Demo/blob/master/README.md
一、使用Taro cli工具初始化項(xiàng)目
1. 安裝taro腳手架工具
首先,你需要使用 npm 或者 yarn 全局安裝@tarojs/cli,或者直接使用npx:
# 使用 npm 安裝 CLI $ npm install -g @tarojs/cli # OR 使用 yarn 安裝 CLI $ yarn global add @tarojs/cli # OR 安裝了 cnpm,使用 cnpm 安裝 CLI $ cnpm install -g @tarojs/cli
2. 初始化taro項(xiàng)目
使用命令創(chuàng)建模板項(xiàng)目 $ taro init myApp npm 5.2+ 也可在不全局安裝的情況下使用 npx 創(chuàng)建模板項(xiàng)目 $ npx @tarojs/cli init myApp
3. 進(jìn)入myApp目錄,安裝依賴
# 使用 yarn 安裝依賴 $ yarn # OR 使用 cnpm 安裝依賴 $ cnpm install # OR 使用 npm 安裝依賴 $ npm install
4. 編譯項(xiàng)目,開啟Dev模式,生成小程序 -- dist目錄
# yarn $ yarn dev:weapp $ yarn build:weapp # npm script $ npm run dev:weapp $ npm run build:weapp # 僅限全局安裝 $ taro build --type weapp --watch $ taro build --type weapp # npx 用戶也可以使用 $ npx taro build --type weapp --watch $ npx taro build --type weapp
5. 使用微信開發(fā)者工具,打開項(xiàng)目中的dist目錄

二、小程序購(gòu)物車功能的實(shí)現(xiàn)過程
效果圖:

三、具體實(shí)現(xiàn)代碼
src/pages/cart/cart.js
import { View, Icon, Navigator, Image, Text, } from '@tarojs/components'
import Taro from '@tarojs/taro'
import './cart.less'
class Cart extends Taro.Component {
config = {
navigationBarTitleText: '購(gòu)物車'
}
state = {
carts: [
{
id: 1,
title: '好喝⾼顏值MEOW莫斯卡托⽓泡葡萄酒甜型⾹檳少⼥粉貓起泡酒(v1)',
image:
'https://tva1.sinaimg.cn/large/00831rSTgy1gczok56tkzj30m80m8qe4.jpg',
num: 3,
price: '88.00',
selected: true
},
{
id: 2,
title: '好喝⾼顏值MEOW莫斯卡托⽓泡葡萄酒甜型⾹檳少⼥粉貓起泡酒(v2)',
image:
'https://tva1.sinaimg.cn/large/00831rSTgy1gczok56tkzj30m80m8qe4.jpg',
num: 1,
price: '188.00',
selected: true
},
{
id: 3,
title: '好喝⾼顏值MEOW莫斯卡托⽓泡葡萄酒甜型⾹檳少⼥粉貓起泡酒(v3)',
image:
'https://tva1.sinaimg.cn/large/00831rSTgy1gczok56tkzj30m80m8qe4.jpg',
num: 2,
price: '288.00',
selected: false
},
{
id: 4,
title: '好喝⾼顏值MEOW莫斯卡托⽓泡葡萄酒甜型⾹檳少⼥粉貓起泡酒(v4)',
image:
'https://tva1.sinaimg.cn/large/00831rSTgy1gczok56tkzj30m80m8qe4.jpg',
num: 2,
price: '388.00',
selected: false
}
], // 購(gòu)物車列表
hascheckList: [],
totalPrice: 0, // 總價(jià),初始為0
selectAllStatus: true // 全選狀態(tài),默認(rèn)全選
}
componentDidShow() {
const cart = [
]
this.setState({
carts: cart
})
this.getTotalPrice();
}
/**
* 計(jì)算總價(jià)
*/
getTotalPrice() {
let carts = this.state.carts // 獲取購(gòu)物車列表
let total = 0
for (let i = 0; i < carts.length; i++) {
// 循環(huán)列表得到每個(gè)數(shù)據(jù)
if (carts[i].selected) {
// 判斷選中才會(huì)計(jì)算價(jià)格
total += carts[i].num * carts[i].price // 所有價(jià)格加起來
}
}
this.setState({
// 最后賦值到data中渲染到頁面
carts: carts,
totalPrice: total.toFixed(2)
})
}
/**
* 綁定加數(shù)量事件
*/
addCount(e) {
const index = e.currentTarget.dataset.index
let carts = this.state.carts
let num = carts[index].num
num = num + 1
carts[index].num = num
this.setState({
carts: carts
})
this.getTotalPrice()
}
/**
* 綁定減數(shù)量事件
*/
minusCount(e) {
const index = e.currentTarget.dataset.index
let carts = this.state.carts
let num = carts[index].num
if (num <= 1) {
return false
}
num = num - 1
carts[index].num = num
this.setState({
carts: carts
})
this.getTotalPrice()
}
/**
* 刪除購(gòu)物車當(dāng)前商品
*/
deleteList(e) {
const index = e.currentTarget.dataset.index
let carts = this.state.carts
carts.splice(index, 1)
this.setState({
carts: carts
})
if (!carts.length) {
this.setState({
hasList: false
})
} else {
this.getTotalPrice()
}
}
/**
* 當(dāng)前商品選中事件
*/
selectList(id,e) {
const index = e.currentTarget.dataset.index
let carts = this.state.carts
// const selected = carts[index].selected
// carts[index].selected = !selected
carts.forEach(item => {
if (id == item.id) {
item.selected = !item.selected
}
})
// const checkall = this.data.selectAllStatus === true ? false : false
this.setState({
carts: carts,
// selectAllStatus: false
})
const selectAllStatus = carts.every(item => item.selected)
this.setState({
selectAllStatus: selectAllStatus
})
this.getTotalPrice()
}
/**
* 購(gòu)物車全選事件
*/
selectAll(e) {
let selectAllStatus = this.state.selectAllStatus
selectAllStatus = !selectAllStatus
let carts = this.state.carts
for (let i = 0; i < carts.length; i++) {
carts[i].selected = selectAllStatus
}
this.setState({
selectAllStatus: selectAllStatus,
carts: carts
})
this.getTotalPrice()
}
// 結(jié)算
closeFun() {
let list = []
let listTotal = []
this.state.carts.map((v, k) => {
console.log('購(gòu)物車數(shù)據(jù)', v)
if (v.select) {
list.push(v)
} else {
listTotal.push(v)
}
})
}
render() {
const { carts, selectAllStatus, totalPrice, hasList } = this.state;
let count = 0;
carts.map(it => {
if(it.selected === true) {
count++;
}
})
return (
<View className="main">
{carts.length > 0 ? (
<View>
<View className="cart-box">
{carts.map((item, index) => {
return (
<View className="cart-list" key={index}>
{item.selected ? (
<Icon
type="success"
color="#b30000"
data-index={index}
className="cart-pro-select"
onClick={this.selectList.bind(this,item.id)}
></Icon>
) : (
<Icon
type="circle"
className="cart-pro-select"
data-index={index}
onClick={this.selectList.bind(this,item.id)}
></Icon>
)}
<Navigator url={'../details/details?id=' + item.id}>
<Image className="cart-thumb" src={item.image}></Image>
</Navigator>
<Text className="cart-pro-name">{item.title}</Text>
<Text className="cart-pro-price">{'¥' + item.price}</Text>
<View className="cart-count-box">
<Text
className="cart-count-down"
onClick={this.minusCount}
data-index={index}
>
-
</Text>
<Text className="cart-count-num">{item.num}</Text>
<Text
className="cart-count-add"
onClick={this.addCount}
data-index={index}
>
+
</Text>
</View>
<Text
className="cart-del"
onClick={this.deleteList}
data-index={index}
>
刪除
</Text>
</View>
)
})}
</View>
<View className="cart-footer">
{selectAllStatus ? (
<Icon
type="success_circle"
color="#b30000"
className="total-select"
onClick={this.selectAll}
></Icon>
) : (
<Icon
type="circle"
color="#b30000"
className="total-select"
onClick={this.selectAll}
></Icon>
)}
<Navigator url="../orders/orders">
<View className="order-icon"></View>
</Navigator>
<Text >{count> 0? `已選(${count})`: '全選'}</Text>
<Text className="cart-toatl-price">{'合計(jì)¥' + totalPrice}</Text>
<Text className="pay" onClick={this.closeFun} data-index={index}>
立即下單
</Text>
</View>
</View>
) : (
<View>
<View className="cart-no-data">購(gòu)物車是空的哦~</View>
</View>
)}
</View>
)
}
}
export default Cart
src/pages/cart/cart.less
/* pages/cart/cart.wxss */
.cart-box{
padding-bottom: 100px;
margin-bottom: 10px
}
.cart-list{
position: relative;
padding: 20px 20px 20px 285px;
height: 185px;
border-bottom: 1px solid #e9e9e9;
}
.cart-list .cart-pro-select{
position: absolute;
left: 20px;
top: 90px;
width: 45px;
height: 45px;
}
.cart-list .cart-thumb{
position: absolute;
top: 20px;
left: 85px;
width: 185px;
height: 185px;
border-radius:5px;
box-shadow:5px 2px 6px #000
}
.cart-list .cart-pro-name{
display: inline-block;
// width: 500px;
height: 105px;
line-height: 50px;
overflow: hidden;
font-family: Microsoft Yahei, Cochin, Georgia, Times, 'Times New Roman', serif;
font-size:28px;
margin-right: 15px
}
.cart-list .cart-pro-price{
display: inline-block;
font-size:30px;
color: #b30000;
height: 105px;
line-height: 50px;
}
.cart-list .cart-count-box{
position: absolute;
left: 420px;
bottom: 20px;
width: 250px;
height: 80px;
}
.cart-list .cart-count-box text{
display: inline-block;
line-height: 80px;
text-align: center;
}
.cart-count-down,.cart-count-add{
font-size: 32px;
width: 60px;
height: 80px;
font-family: Microsoft Yahei, Cochin, Georgia, Times, 'Times New Roman', serif;
border: silver solid 1px;
border-radius: 10px;
}
.cart-count-num{
width: 80px;
font-size: 32px;
height: 80px;
border-radius: 10px;
border: silver solid 1px;
margin-left: 1px;
margin-right: 1px;
}
.cart-del{
position: absolute;
right: 15px;
bottom: 20px;
width: 80px;
height: 80px;
line-height: 80px;
text-align: center;
font-family: Arial,Helvetica,sans-serif;
font-size:30px;
color: #b30000;
text-shadow: black;
}
.cart-footer{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 90px;
line-height: 90px;
padding:0 100px 0 80px;
box-sizing: border-box;
background: #bfbfbf;
color: #4d4d4d;
font-family: Microsoft Yahei, Cochin, Georgia, Times, 'Times New Roman', serif;
font-size: 30px;
}
.total-select{
position: absolute;
left: 20px;
top: 25px;
width: 45px;
height: 45px;
}
.order-icon{
position: absolute;
right: 40px;
top: 25px;
width: 45px;
height: 45px;
background-size: 100%;
}
.cart-toatl-price{
/* float: right; */
margin-left:80px;
text-align: center;
width: 100px;
font-family: Microsoft Yahei, Cochin, Georgia, Times, 'Times New Roman', serif;
color: #b30000;
font-size: 30px;
}
.pay {
position: absolute;
right: 0;
background-color: #b30000;
height: 100%;
width: 200px;
text-align: center;
font-family: Microsoft Yahei, Cochin, Georgia, Times, 'Times New Roman', serif;
font-size: 26px;
color: #f2f2f2;
text-align: center
}
.cart-no-data{
padding:40px 0;
color: #999;
text-align: center;
}
注意:檢查本地電腦taro的版本,電腦需要和項(xiàng)目的taro版本號(hào)相同,否則發(fā)送編譯錯(cuò)誤,該項(xiàng)目的taro CLI版本為v2.1.1
官方提供的兩個(gè)解決方案: 1、 對(duì)電腦的taro進(jìn)行升級(jí) # taro $ taro update self [version] # npm npm i -g @tarojs/cli@[version] # yarn yarn global add @tarojs/cli@[version] 2、 對(duì)項(xiàng)目的taro進(jìn)行升級(jí) $ taro update project [version] version 為選填,如:1.x.x/latest 等,將會(huì)直接更新到指定版本
總結(jié)
到此這篇關(guān)于使用Taro實(shí)現(xiàn)的小程序商城的購(gòu)物車功能模塊的文章就介紹到這了,更多相關(guān)Taro實(shí)現(xiàn)小程序商城的購(gòu)物車內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript中:表達(dá)式和語句的區(qū)別[譯]
本文要講的是JavaScript中非常重要的兩個(gè)知識(shí)點(diǎn):表達(dá)式(expressions)和語句(statements)之間的區(qū)別2012-09-09
JavaScript 實(shí)現(xiàn)輪播圖特效的示例
這篇文章主要介紹了JavaScript 實(shí)現(xiàn)輪播圖特效,幫助大家更好的制作網(wǎng)頁,完成需求,感興趣的朋友可以了解下2020-11-11
js實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊文本框自動(dòng)選中內(nèi)容的方法
這篇文章主要介紹了js實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊文本框自動(dòng)選中內(nèi)容的方法,涉及javascript鼠標(biāo)點(diǎn)擊事件onClick及選擇事件select的使用技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-08-08
JS短路原理的應(yīng)用示例 精簡(jiǎn)代碼的途徑
正如標(biāo)題所言,js中||和&&的特性幫我們精簡(jiǎn)了代碼的同時(shí),也帶來了代碼可讀性的降低。這就需要我們自己來權(quán)衡了,下面有個(gè)不錯(cuò)的示例2013-12-12
表單input項(xiàng)使用label同時(shí)引用Bootstrap庫導(dǎo)致input點(diǎn)擊效果區(qū)增大問題
這篇文章主要介紹了表單input項(xiàng)使用label,同時(shí)引用Bootstrap庫,導(dǎo)致input點(diǎn)擊效果區(qū)增大問題的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10
JavaScript是如何實(shí)現(xiàn)繼承的(六種方式)
大多OO語言都支持兩種繼承方式: 接口繼承和實(shí)現(xiàn)繼承 ,而ECMAScript中無法實(shí)現(xiàn)接口繼承,ECMAScript只支持實(shí)現(xiàn)繼承,而且其實(shí)現(xiàn)繼承主要是依靠原型鏈來實(shí)現(xiàn),下文給大家技術(shù)js實(shí)現(xiàn)繼承的六種方式,需要的朋友參考下2016-03-03
小程序canvas實(shí)現(xiàn)畫布半圓環(huán)
這篇文章主要為大家詳細(xì)介紹了小程序canvas實(shí)現(xiàn)畫布半圓環(huán),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
jsvascript圖像處理—(計(jì)算機(jī)視覺應(yīng)用)圖像金字塔
上一篇文章,我們講解了邊緣梯度計(jì)算函數(shù),這篇文章我們來了解圖像金字塔;圖像金字塔被廣泛用于計(jì)算機(jī)視覺應(yīng)用中;圖像金字塔是一個(gè)圖像集合,集合中所有的圖像都源于同一個(gè)原始圖像,而且是通過對(duì)原始圖像連續(xù)降采樣獲得的2013-01-01

