黑马优购小程序知识点总结

1.页面

1.1首页

1.2分类

1.3购物车

1.4我的

1.5搜索

1.6商品列表

1.7商品详情

1.8微信支付

2.使用组件

2.1tabBar

本程序中用到了首页、分类、购物车、我的

2.2轮播图

<!-- 轮播图区域 -->
    <swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000" :circular="true">
      <!-- 循环渲染轮播图的 item 项 -->
      <swiper-item v-for="(item, i) in swiperList" :key="i">
        <view class="swiper-item">
          <!-- 动态绑定图片的 src 属性 -->
          <image :src="item.image_src"></image>
        </view>
      </swiper-item>
    </swiper>

2.3页面跳转

<swiper-item v-for="(item, i) in swiperList" :key="i">
    <navigator class="swiper-item" :url="'/subpkg/goods_detail/goods_detail?goods_id=' + item.goods_id"> 
      <!-- 动态绑定图片的 src 属性 -->
      <image :src="item.image_src"></image>
    </navigator>
</swiper-item>

2.4图片展示

<view class="left-img-box">
    <image :src="item.product_list[0].image_src" :style="{width: item.product_list[0].image_width + 'rpx'}" mode="widthFix">			</image>
</view>

2.5滚动视图

<!-- 左侧的滚动视图区域 -->
      <scroll-view class="left-scroll-view" scroll-y :style="{height: wh + 'px'}">
        <view class="left-scroll-view-item active">xxx</view>
        <view class="left-scroll-view-item">xxx</view>
        <view class="left-scroll-view-item">xxx</view>
        <view class="left-scroll-view-item">xxx</view>
        <view class="left-scroll-view-item">xxx</view>
        <view class="left-scroll-view-item">多复制一些节点,演示纵向滚动效果...</view>
      </scroll-view>

2.6uni-icons

<!-- 使用 view 组件模拟 input 输入框的样式 -->
    <view class="my-search-box">
      <uni-icons type="search" size="17"></uni-icons>
      <text class="placeholder">搜索</text>
    </view>

2.7uni-search-bar

<view class="search-box">
  <!-- 使用 uni-ui 提供的搜索组件 -->
  <uni-search-bar @input="input" :radius="100" cancelButton="none"></uni-search-bar>
</view>    

2.8uni-tag

<!-- 标题区域 -->
  <view class="history-title">
    <text>搜索历史</text>
    <uni-icons type="trash" size="17"></uni-icons>
  </view>

2.9block 使用

<view> 
    <view class="goods-list">
      <block v-for="(goods, i) in goodsList" :key="i">
        <view class="goods-item">
          <!-- 商品左侧图片区域 -->
          <view class="goods-item-left">
            <image :src="goods.goods_small_logo || defaultPic" class="goods-pic"></image>
          </view>
          <!-- 商品右侧信息区域 -->
          <view class="goods-item-right">
            <!-- 商品标题 -->
            <view class="goods-name">{{goods.goods_name}}</view>
            <view class="goods-info-box">
              <!-- 商品价格 -->
              <view class="goods-price">¥{{goods.goods_price}}</view>
            </view>
          </view>
        </view>
      </block>
    </view>
  </view>

2.10uni-goods-nav

<!-- 商品导航组件 -->
<view class="goods_nav">
  <!-- fill 控制右侧按钮的样式 -->
  <!-- options 左侧按钮的配置项 -->
  <!-- buttonGroup 右侧按钮的配置项 -->
  <!-- click 左侧按钮的点击事件处理函数 -->
  <!-- buttonClick 右侧按钮的点击事件处理函数 -->
  <uni-goods-nav :fill="true" :options="options" :buttonGroup="buttonGroup" @click="onClick" @buttonClick="buttonClick" />
</view> 

2.11radio

<!-- 商品左侧图片区域 -->
<view class="goods-item-left">
  <!-- 存储在购物车中的商品,包含 goods_state 属性,表示商品的勾选状态 -->
  <radio :checked="goods.goods_state" color="#C00000" v-if="showRadio"></radio>
  <image :src="goods.goods_small_logo || defaultPic" class="goods-pic"></image> 
</view>

2.12uni-number-box

<view class="goods-info-box">
  <!-- 商品价格 -->
  <view class="goods-price">¥{{goods.goods_price | tofixed}}</view>
  <!-- 商品数量 -->
  <uni-number-box :min="1"></uni-number-box>
</view>

2.13uni-swipe-action 和 uni-swipe-action-item

<!-- 商品列表区域 -->
<!-- uni-swipe-action 是最外层包裹性质的容器 -->
<uni-swipe-action>
  <block v-for="(goods, i) in cart" :key="i">
    <!-- uni-swipe-action-item 可以为其子节点提供滑动操作的效果。需要通过 options 属性来指定操作按钮的配置信息 -->
    <uni-swipe-action-item :options="options" @click="swipeActionClickHandler(goods)">
      <my-goods :goods="goods" :show-radio="true" :show-num="true" @radio-change="radioChangeHandler" @num-change="numberChangeHandler"></my-goods>
    </uni-swipe-action-item>
  </block>
</uni-swipe-action>

2.14button

<!-- 选择收货地址的盒子 -->
<view class="address-choose-box" v-if="JSON.stringify(address) === '{}'">
  <button type="primary" size="mini" class="btnChooseAddress" @click="chooseAddress">请选择收货地址+</button>
</view>

3.样式美化

3.1常用样式

3.1.1display
3.1.2justify-content
3.1.3flex-direction
3.1.4align-items
3.1.5display
3.1.6flex-wrap
3.1.7top
3.1.8z-index
3.1.9text-align
3.1.10line-height
3.1.11position
3.1.12transform
3.1.13text-overflow
3.1.14overflow
3.1.15white-space
3.1.16box-sizing
3.1.17flex
3.1.18&::
3.1.18border-radius
3.1.19box-shadow

3.2使用颜色

4.技术点

4.1下拉刷新

pages.json 中添加如下

{
      "path" : "pages/cate/cate", 
      "style" :{
          // "navigationBarTitleText": "",
          "enablePullDownRefresh": false
      }
    },

页面中 methods 方法增加

    onPullDownRefresh() {
      this.queryObj.pagenum = 1
      this.total = 0
      this.isloading = false
      this.goodsList = []
      this.getGoodsList(()=> uni.stopPullDownRefresh())
    }

4.2上拉加载

page.json 中添加如下

{
        "path" : "goods_list/goods_list",
        "style" :                                                                                    
    {
        // "navigationBarTitleText": "",
        "enablePullDownRefresh": true,
        "onReachBottomDistance": 150,
        "backgroundColor": "#f8f8f8"
    }

}

页面方法中增加

    onReachBottom() {
      if (this.queryObj.pagenum * this.queryObj.pagesize >= this.total) return uni.$showMsg('数据加载完毕!') 
      if(this.isloading) return
      this.queryObj.pagenum += 1
      // console.log(this.queryObj.pagenum)
      this.getGoodsList()
    },

4.3左移删除

使用组件 uni-swipe-action

<!-- 商品列表区域 -->
<!-- uni-swipe-action 是最外层包裹性质的容器 -->
<uni-swipe-action>
  <block v-for="(goods, i) in cart" :key="i">
    <!-- uni-swipe-action-item 可以为其子节点提供滑动操作的效果。需要通过 options 属性来指定操作按钮的配置信息 -->
    <uni-swipe-action-item :options="options" @click="swipeActionClickHandler(goods)">
      <my-goods :goods="goods" :show-radio="true" :show-num="true" @radio-change="radioChangeHandler" @num-change="numberChangeHandler"></my-goods>
    </uni-swipe-action-item>
  </block>
</uni-swipe-action>

methods 中实现删除功能

// 点击了滑动操作按钮
swipeActionClickHandler(goods) {
  console.log(goods)
}

4.4吸顶效果

4.5封装组件

组件的构成:页面布局;

父页面如下:

<my-goods :goods="goods" :show-radio="true" @radio-change="radioChangeHandler" :showNum="true" @num-change="numberChangeHandler"></my-goods>
      //商品的勾选状态发生了变化 
      radioChangeHandler(e){
        this.updateGoodsState(e)  
        console.log("-------")
        // console.log(e) 
      },
      
      // 商品的数量发生了变化 
      numberChangeHandler(e){
        this.updateGoodsCount(e)
        console.log(e)
      },

子页面如下:

<template>  
  <view class="goods-item">
    <view class="goods-item-left">
      <radio :checked="goods.goods_state" color="#c00" v-if="showRadio" @click="radioClickHandler"></radio> 
      <!-- <text>{{goods.goods_small_logo}}</text> -->
      <image :src="goods.goods_small_logo || defaultPic" class="goods-pic"></image> 
    </view> 
    <view class="goods-item-right"> 
      <view class="goods-name">{{goods.goods_name}}</view> 
      <view class="goods-info-box">
        <view class="goods-price">${{goods.goods_price | tofixed}}</view> 
        <uni-number-box :min="1" :value="goods.goods_count" v-if="showNum" @change="numChangeHandler"></uni-number-box>
      </view> 
    </view> 
  </view> 
</template> 

<script>
  export default {
    name:"my-goods",  
    props: {
      goods: {
        type: Object,
        default: {},
      },
      // 是否展示图片左侧的 radio
      showRadio: {
        type: Boolean,
        // 如果外界没有指定 show-radio 属性的值,则默认不展示 radio 组件
        default: false
      },
      // 是否显示价格右侧的 NumberBox 组件
      showNum:{
        type: Boolean,
        default: false,
      },
      
    },
    data() {
      return {
        defaultPic: 'https://img3.doubanio.com/f/movie/8dd0c794499fe925ae2ae89ee30cd225750457b4/pics/movie/celebrity-default-medium.png',
        
      };
    },
    filters: { 
      tofixed(num){
         return Number(num).toFixed(2)
      }
    },
    methods:{
      //radio 组件 的点击事件处理函数
      radioClickHandler(){
         // 通过 this.$emit() 触发外界通过@绑定的 radio-change 事件,
         //同时把商品的 id 和勾选状态作为参数传递给 radio-change 事件处理函数
         this.$emit('radio-change',{
           //商品 id
           goods_id: this.goods.goods_id, 
           //商品最新的勾选状态
           goods_state: !this.goods.goods_state 
         })
      },
      
      //NumberBox 组件的 change 事件处理函数 
      numChangeHandler(val){
        console.log(val) 
        //通过 this.$emit()触发外界通过@ 绑定 num-change 事件
        this.$emit('num-change',{
          goods_id : this.goods.goods_id, 
          goods_count: +val  
        })
      }
    }
  }
</script>

<style lang="scss"> 
  
</style>

其中:props中定义在子页面中使用的数据,方法使用 this.$emit 进行向父窗口传值。

4.6分包

分包的目的:为了小程序首次加载时速度变快

pages.json 中增加

"subPackages": [
    {
      "root": "subpkg",
      "pages": [], 
    }
  ]

在根目录下增加 subpkg 文件夹,增加新的页面

4.7mixins

抽离出一个公共的 js 文件,方法进行徽标的设置

在根目录下新建一个 mixins 文件夹,新建一个 tabbar-badge.js 文件

import {mapGetters} from 'vuex'

export default{
  
  computed: {
    //  将 m_cart 模块中的 total 映射为当前页面的计算属性
    ...mapGetters('m_cart',['total'])
  },
  watch:{
    total() {
      this.setBadge()
    }
  },
  onShow() {
    //在页面展示的时候,设置数字徽标
    this.setBadge()
  },
  methods: {
    setBadge(){
      //调用 uni.setTabBarBadger()方法,为购物车设置右上角的徽标
      uni.setTabBarBadge({
        index: 2,   //索引
        text: this.total + ''   // 注意,text 的值必须是字符串,不能是数字 
      })
    }
  },
  
}

home.vue 页面进入导入

  // 导入自己封装的 mixin 模块
  import badgeMix from '@/mixins/tabbar-badge.js'
  export default {
    //将 badgeMix 混入到当前页面中进行使用
    mixins: [badgeMix],
  }

4.8持久化

持久化数据都放在 store.js 中

import Vue from 'vue'
import Vuex from 'vuex'
import moduleCart from '@/store/cart.js'
import moduleUser from '@/store/user.js'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules:{
    'm_cart': moduleCart,
    'm_user': moduleUser
  }
})

export default store

然后在每个 js 中进行各自类型的持久化,文件的结构如下。其中包括 state,mutation 和 getters

export default {
  
  namespaced: true,
  
  state: () => ({
    cart: JSON.parse(uni.getStorageSync('cart') || '[]'),
  }),
  
  mutations: {
    // 增加商品到购物车
    addToCart(state,goods){
      const findResult = state.cart.find(x => x.goods_id === goods.goods_id)
      // console.log(findResult)
      if(!findResult){
        state.cart.push(goods)
      }else{
        findResult.goods_count++
      }
      
      // 通过 commit 方法,调用 m_cart 命名空间下 saveToStorage方法
      this.commit('m_cart/saveToStorage')
    },
    
    // 将购物车的数据持久化存储到本地
    saveToStorage(state){
      // console.log(state.cart)
      uni.setStorageSync('cart',JSON.stringify(state.cart))
    },
  },
  
  getters: {
    //  勾选的商品的总数量
    checkedCount(state){
      let checkedCount = state.cart.filter(x => x.goods_state).reduce((total,item) => total += item.goods_count,0)
      return checkedCount
    },
  }
   
}

调用如下:


import {mapState,mapMutations}  from 'vuex'
  export default {
    mixins: [badgeMix],
    computed: {
      ...mapState('m_cart',['cart'])
    },
    data() {
      return {
      }
    },
    methods:{
      ...mapMutations('m_cart',['updateGoodsState','updateGoodsCount','removeGoodsById']),
      //商品的勾选状态发生了变化 
      radioChangeHandler(e){
        this.updateGoodsState(e)
        console.log("-------")
        // console.log(e) 
      },
    }
  }

5.后端方法

6.优化点

7.注意事项

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值