获取商品信息
跳转过来携带商品id
<navigator:url="`/pages/goods_detail/goods_detail?goods_id=${info.goods_id}`">onLoad (options) {const goods_id = options.goods_idthis.getGoodsDetail(goods_id)},data() {return {goodsDetail: null}},methods: {async getGoodsDetail(goods_id) {const res = await this.$u.get('/goods/detail',{goods_id})console.log(res);this.goodsDetail = res.message}},
页面渲染
轮播图
轮播图 + 图片 组件 会冲突 看文档
img-mode是控制轮播图中的图片裁件bg-color控制背景颜色 十六进制
<!-- 轮播图 --><u-swiper:list="goodsDetail.pics"name="pics_big_url"img-mode="aspectFit"height="500"bg-color="#fff"></u-swiper>
点击轮播图 放大预览被点击的图片
previewImage小程序api
// 点击轮播图图片handlepreviewImage (index) {// console.log(index);const urls = this.urls // 需要预览的图片 http 链接列表const current = this.urls[index]// 当前显示图片的 http 链接// 放大预览图片uni.previewImage({current,urls})}},computed: {// 优化 计算属性有缓存 不用每次点击都重新输出新的urlsurls() {// 预览的图片数组 只能存放if (this.goodsDetail) {return this.goodsDetail.pics.map(item => item.pics_big_url)} else {return []}}},}
商品信息
直接渲染 页面有可能会出现undefined 在跟组件上加一个
v-if来做渲染
<template v-if="goodsDetail"><view><!-- 轮播图 --><u-swiper:list="goodsDetail.pics"name="pics_big_url"img-mode="aspectFit"height="500"bg-color="#fff"@click="handlepreviewImage"></u-swiper><!-- 商品信息 --><view><!-- 价格 --><view class="goods-price"><view>¥{{ goodsDetail.goods_price }}</view><!-- 分享功能 --><view class="share-container"><u-icon name="share"></u-icon><button open-type="share"></button></view></view><!-- 描述 --><view class="goods-name">{{ goodsDetail.goods_name }}</view></view></view></template>
分享功能
分享当前页面给微信好友
通过监听生命周期事件
onShareAppMessage用户分享时会执行 如果不定义 无法点击小程序右上-分享 button组件open-type="share"可以触发
<button open-type="share"></button>onShareAppMessage () {},
分享到朋友圈
通过监听生命周期事件
onShareTimeline用户分享时会执行 如果不定义 无法点击小程序右上-分享到朋友圈
onShareTimeline () {},
分享图标
利用定位让按钮脱标 宽高跟父元素一样 透明度0 点击图标 = 点击按钮
<!-- 分享功能 --><view class="share-container"><u-icon name="share"></u-icon><button open-type="share"></button></view></view><style lang="scss">.goods-price {display: flex;justify-content: space-between;color: #ea4350;padding: 10rpx;.share-container {position: relative;// 由内容撑开 icon图标display: inline-block;margin-right: 45rpx;color: #000;button {position: absolute;width: 100%;height: 100%;top: 0;left: 0;opacity: 0;}}}</style>
图文详情
由商家在商家后台自定义好,后端直接返回富文本
解析富文本
<rich-text :nodes="">原生小程序- 适合简单的场景
v-htmlvue语法<u-parse :html="">uview组件
<template><view class="navigation"><view class="left"><view class="item"><u-icon name="server-fill" :size="40" :color="$u.color['contentColor']"></u-icon><view class="text u-line-1">客服</view></view><view class="item"><u-icon name="home" :size="40" :color="$u.color['contentColor']"></u-icon><view class="text u-line-1">店铺</view></view><view class="item car"><u-badge class="car-num" :count="9" type="error" :offset="[-3, -6]"></u-badge><u-icon name="shopping-cart" :size="40" :color="$u.color['contentColor']"></u-icon><view class="text u-line-1">购物车</view></view></view><view class="right"><view class="cart btn u-line-1">加入购物车</view><view class="buy btn u-line-1">立即购买</view></view></view></template><script>export default {};</script><style lang="scss" scoped>.navigation {display: flex;margin-top: 100rpx;border: solid 2rpx #f2f2f2;background-color: #ffffff;padding: 16rpx 0;.left {display: flex;font-size: 20rpx;.item {margin: 0 30rpx;&.car {text-align: center;position: relative;.car-num {position: absolute;top: -10rpx;right: -10rpx;}}}}.right {display: flex;font-size: 28rpx;align-items: center;.btn {line-height: 66rpx;padding: 0 30rpx;border-radius: 36rpx;color: #ffffff;}.cart {background-color: #ed3f14;margin-right: 30rpx;}.buy {background-color: #ff7900;}}}</style>
封装组件 引入到页面中
<!-- 提交订单栏 --><view class="submit-bar"><SubmitBar></SubmitBar></view><script>import SubmitBar from './components/submit_bar.vue'export default {components: {SubmitBar,}}</script><style lang="scss">.submit-bar{position: fixed;bottom: 0;left: 0;// 块级元素加定位之后 变成行内块 - 宽度不是100%width: 100%;}page {padding-bottom: 102rpx;}</style>
<template><view class="navigation"><view class="left"><view class="item"><u-icon name="server-fill" :size="40" :color="$u.color['contentColor']"></u-icon><view class="text u-line-1">客服</view></view><view class="item"><u-icon name="home" :size="40" :color="$u.color['contentColor']"></u-icon><view class="text u-line-1">店铺</view></view><view class="item car"><u-badge class="car-num" :count="9" type="error" :offset="[-3, -6]"></u-badge><u-icon name="shopping-cart" :size="40" :color="$u.color['contentColor']"></u-icon><view class="text u-line-1">购物车</view></view></view><view class="right"><view class="cart btn u-line-1">加入购物车</view><view class="buy btn u-line-1">立即购买</view></view></view></template><script>export default {};</script><style lang="scss" scoped>.navigation {display: flex;// 更改布局justify-content: space-around;margin-top: 100rpx;border: solid 2rpx #f2f2f2;background-color: #ffffff;padding: 16rpx 0;.left {display: flex;font-size: 20rpx;// 位移transform: translateX(-30rpx);.item {margin: 0 30rpx;&.car {text-align: center;position: relative;.car-num {position: absolute;top: -10rpx;right: -10rpx;}}}}.right {display: flex;font-size: 28rpx;align-items: center;.btn {line-height: 66rpx;padding: 0 30rpx;border-radius: 36rpx;color: #ffffff;}.cart {background-color: #ed3f14;margin-right: 30rpx;}.buy {background-color: #ff7900;}}}</style>
使用vuex
export default {namespaced:true,state: {// 商品数组goodsArr: []}};
导入模块
import Vue from 'vue';import Vuex from 'vuex';// 引入模块import cart from './modules/cart';Vue.use(Vuex); //vue的插件机制//Vuex.Store 构造器选项const store = new Vuex.Store({modules: {cart,},});export default store;
挂载到vue实例中
import Vue from 'vue'import App from './App'import uView from "uview-ui"// 引入import store from './store';Vue.use(uView)Vue.config.productionTip = false// 挂载到原型上Vue.prototype.$store = store;App.mpType = 'app'const app = new Vue({store,...App})// http拦截器,此为需要加入的内容,如果不是写在common目录,请自行修改引入路径import httpInterceptor from '@/common/http.interceptor.js'// 这里需要写在最后,是为了等Vue创建对象完成,引入"app"对象(也即页面的"this"实例)Vue.use(httpInterceptor, app)app.$mount()
组件中的生命周期需要使用vue的语法
created () {console.log(this.$store);}
加入购物车
- 传入商品信息 到提交订单栏
- 提交订单栏 加入购物车绑定点击事件
- 获取到当前商品的信息 提交mutaions传递商品对象
- mutations业务
- 判断当前商品是否存在于购物车
- 存在 找到数组元素 执行增加计算
- 不存在 数组新增元素
```jsx
加入购物车
methods: { handleCartAdd() { // 提交mutations this.$store.commit(“cart/cartAddMutations”,{ …this.goodsDetail, count:1, checked:true }) } },
```jsxexport default {namespaced:true,state: {// 商品数组goodsArr: []},mutations: {cartAddMutations (state,goods) {const index = state.goodsArr.findIndex(item => item.goods_id === goods.goods_id)if (index !== -1) {// 存在 找到该商品修改信息state.goodsArr[index].count++// console.log('商品数量',state.goodsArr[index].count);} else {// 不存在 购物车数组加入新元素state.goodsArr.push(goods)// console.log('添加新元素',state.goodsArr);}}}};
使用vuex提供的辅助函数
mapMutations来简化代码
import {mapMutations} from 'vuex'methods: {...mapMutations('cart', ['cartAddMutations']),handleCartAdd () {this.cartAddMutations({...this.goodsDetail,count: 1,checked: true})}}
数据持久化,通过本地存储 来管理购物车数据
小程序中的本地存储,可以存储任意类型,不需要转成json
- 存
uni.setStorageSync('名称',数据)
- 取
uni.getStorageSync('名称')export default {namespaced:true,state: {// 商品数组 先取本地数据,没有才是空数组goodsArr: uni.getStorageSync('cart') ||[]},mutations: {cartAddMutations (state,goods) {const index = state.goodsArr.findIndex(item => item.goods_id === goods.goods_id)if (index !== -1) {// 存在 找到该商品修改信息state.goodsArr[index].count++console.log('商品数量',state.goodsArr[index].count);} else {// 不存在 购物车数组加入新元素state.goodsArr.push(goods)console.log('添加新元素',state.goodsArr);}// 修改数据之后都需要存储uni.setStorageSync('cart',state.goodsArr)}}};
购物车图标
商品数量显示计算属性,来计算总的购买数量
getters
getters: {// 购物车商品的总数量goodsTotalCount(state) {return state.goodsArr.reduce((sum,item) => item.count + sum,0)}}
<u-badgeclass="car-num":count="goodsTotalCount"type="error":offset="[-3, -6]"></u-badge>import { mapMutations, mapGetters } from 'vuex'computed: {...mapGetters('cart',['goodsTotalCount'])},
点击跳转
跳转到tabbar页面 需要添加
open-type=""属性
<navigatorclass="item car"url="/pages/cart/cart"open-type="switchTab"><u-badgeclass="car-num":count="goodsTotalCount"type="error":offset="[-3, -6]"></u-badge><u-iconname="shopping-cart":size="40":color="$u.color['contentColor']"></u-icon><view class="text u-line-1">购物车</view></navigator>
