uniapp-黑马优选学习02

发布时间 2023-06-14 23:18:27作者: 耗喜天涯

01. scroll-view 配置高度或宽度时的屏幕铺满;

  使用 uni.getSystemInfoSync() 获取设备相关信息

02. 取分类数据

  > API 接口:/api/public/v1/categories

  > 数据结构:{内容太多,请直接调用接口获取}

  >> 为元素配置 动态类 信息 (如果条件匹配则添加 active 类,否则 不添加

     <view :class="['sv-left-item',idx===active ? 'active':'']" @click="activeChange(idx)">{{item.cat_name}}</view>

  >> scroll-view 的定位;

    > 在 scroll-view 中,有属性  scroll-top  用于定位 滚动位置;

    > 可以 在 scroll-view 元素上动态配置 :scroll-top 属性为  某个属性,如:tmpTop; 每次需要重新置顶时,动态修正 tmpTop 为1或0 即可让UI重绘,完成重新置顶;

03.吸引效果配置

  

04. 搜索组件:  uni-search-bar 

  >> 自动聚焦方法:修改 uni-search-bar 的源码,将 show, showSync 全部配置为 true

             修改第三方组件源码达到效果,不是一种好的方法,待后期需处理,以便在外部可直接配置达到效果

    

 05. 防抖处理 >> 基于控制  input 事件中的 延时处理  timerout 进行配置

  

 06. 搜索建议查询

  API地址:/api/public/v1/goods/qsearch  Get    参数:query   --> 查询内容

07. 数组与集合的转换

         从数组得到集合: const set = new Set(this.searchHisList)

    从集合得到数组:this.searchHisList = Array.from(set)

08. 持久化处理

       持久化登记: uni.setStorageSync('kw',JSON.stringify(this.searchHisList))

    持久数据读取: this.searchHisList = JSON.parse( uni.getStorageSync('kw') || '[]')

09. 取商品列表(搜索方式)

  API: 

  

      >> 过滤器的配置 :保留2位小数

filters:{
     tofixed(num){
       return Number(num).toFixed(2)
     }
   }

 

   >> 通过管道符进行调用

     <view class="item-price">¥{{item.goods_price | tofixed}}</view>

10. 上拉加载更多的配置

  >> page.json 中对应的页面,配置触底距离    

{
      "path": "goods_list/goods_list",
      "style": {
        "onReachBottomDistance": 150
    }
}

 

   >> 在页面代码中,与 methods 同级,申明  onReachBottom 事件的处理函数  

    onReachBottom() {
      if(this.queryObj.pagenum*this.queryObj.pagesize>=this.total)
        return uni.showMsg('数据加载完成.')
      // 配置要加载的新的页面序号
      this.queryObj.pagenum+=1
      // 加载新的页面数据
      this.getGoodsList()
    }

 

  >> 同时修改加载成功时,赋值

    this.goodsList = [...this.goodsList,...res.message.goods]

11. 节流控制, 避免同时触发多个请求  

 onReachBottom() {
      // 节流控制
      if (this.isLoading) return
      this.isLoading = true
      try {
        if (this.queryObj.pagenum * this.queryObj.pagesize >= this.total)
          return uni.showMsg('数据加载完成.')
        // 配置要加载的新的页面序号
        this.queryObj.pagenum += 1
        // 加载新的页面数据
        this.getGoodsList()
      } finally {
        this.isLoading = false
      }
    },

 

  >> 数据加载完成的识别方式:  页号  *  每页数量 >= 总记录数  表示加载完成了

12. 下拉刷新.

   >>在 page.json 中对应的页面配置中,进行配置

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

 

  >> 监听 onPullDownRefresh 事件,配置下拉刷新事件  

    onPullDownRefresh() {
      // 重新数据加载参数
      this.queryObj.pagenum=1
      this.total=0
      this.isLoading = false
      this.goodsList = []
      //开始加载 传入回调函数
      this.getGoodsList(()=>uni.stopPullDownRefresh())
    },

 

  >> 修正取数函数,在数据加载完成后,调用回调函数

async getGoodsList(cb) {
        const {
          data: res
        } = await uni.$http.get('/api/public/v1/goods/search', this.queryObj)
        // 只要数据请求完毕了,就立即调用回调函数
        cb&&cb()
        if (res.meta.status !== 200) {
          return uni.$showMsg()
        }
        this.goodsList = [...this.goodsList, ...res.message.goods]
        this.total = res.message.total
      },

 

 

13. 点击商品,跳转到详情页

  API:  

  gotoDetail(item){
        uni.navigateTo({
          url:'/subpkg/goods_detail/goods_detail?goods_id='+item.goods_id
        })
      }

 

14. 商品详情页数据的加载  

   async getGoodsDetail(goods_id) {
        const { data: res } = await uni.$http.get('/api/public/v1/goods/detail',{goods_id})
        if (res.meta.status !== 200) {
          return uni.$showMsg()
        }
        this.goods_info = res.message
      },

 

  >> 轮播图点击后的大图预览     

  // 预览图片
        uni.previewImage({
          // 默认的预览序号
          current:idx,
          // 所有图片的地址
          urls:this.goods_info.pics.map(x=>x.pics_sma)          
        })

 

  >>  动态关联展示 HTML 文本字符串信息

    > 使用的组件: <rich-text :nodes="goods_info.goods_introduce"></rich-text>

      

  >> 解决 图片之间 的空白间隙

     > 通过正则,将HTML字符串内容中,所有的图片标签,都替换为带 display=block 

       

      

     >  变更前后效果如下:

       

    >> 关于按条件展示的控制 (防止部分数据闪烁的出现,)    

      

15. 电商底部导航栏组件的使用: uni-goods-nav  组件;

  > 使用详情:请看官方文档;

 16.  VueX 的认识

  >>  Vuex 是一个专门为 Vue.js 应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    可以理解为:将多个组件共享的变量全部存储在一个对象里面,然后将这个对象放在顶层的 Vue 实例中,让其他组件可以使用,它最大的特点是响应式

  >> 一般情况下,我们会在 Vuex 中存放一些需要在多个界面中进行共享的信息。比如用户的登录状态、用户名称、头像、地理位置信息、商品的收藏、购物车中的物品等,这些状态信息,我们可以放在统一的地方,对它进行保存和管理。

     

17. VueX 的使用

  >. 01. 项目根目录新建目录:store

  >. 02. 在store 目录下新建 js 文件: store.js

  >. 03. 编缉 sotre.js 文件如下:

//导入 Vue 和 Vuex
import Vue form 'vue'
import Vuex from 'vuex'

// 将 uvex 挂载到Vue上,做一个插件
Vue.use(Vuex)

// 创建 Store 实例对象
const store = new Vuex.Store({
  modules:{}
})

// 导出
export default store

  >. 04. 在 main.js 中导入上面的存储实例对象 store

    import store from '@/store/store.js'

    将 store 挂载到Vue实例上去

    

   >05. 配置业务需要的 vuex 模块,

     (直接在 store.js 同级目录下,新建 cart.js 文件 如下:)

export default {
  // 为当前模块开启命名空间
  namespaced:true,
  // 模块的 state 数据
  state:()=>({
    // 购物车的数组,用于存储购物车中每个商品的信息对象
    // 每个商品的信息对象,都包含如下6个属性
    // {goods_id,goods_name,goods_price,goods_count,goods_small_logo,goods_state}
    cart:[]
  })
  // 模块的 mutations 方法
  mutations:{},
  // 模块的 getter 属性
  getters:{}  
}

 

   > 06. 在 store.js 模块中,导入 cart.js 模块,并将cart.js 中导出的内容,挂载到 store 实例化函数中的 modules 中;

  // 导入购物车的 vuex 模块
  import moduleCart from './cart.js'

...

// 创建 Store 实例对象 const store = new Vuex.Store({ // 挂载 store 模块 modules:{ // 挂载购物车的 vuex 模块,模块内成员的访问路径被调整为 m_cart // 如:购物车中 cart 数组的访问路径为: m_cart/cart m_cart:moduleCart, } })

 

>> 关于 uniapp中,Vue2版本 ,只能使用 vuex 3.x 版本 ;

>> store.js 中挂载vuex 模块时,modules 中的 m_cart 可以带单引号,也可以不带;

>> cart.js 中的 state: 按上面描述的写就好;

>> 挂载位置

   

 

  >07. vuex 模块中的state 数据,只能被  mutations 中的方法访问

    >. 将商品信息添加到购物车数组中  

// 模块的 mutations 方法
  mutations:{
    // 添加商品
    addToCart(state,goods){
      // 识别是否已经存在
      const findResult = state.cart.fin((x)=>x.goods_id===goods.goods_id)
      if(!findResult){
        state.cart.push(goods)
      }else{
        findResult.goods_count++
      }
    }
  },

 

  > 映射到业务模块

              >> 映射前,需要先导入       

  // 导入vuex 模块
  import {mapState,mapMutations} from 'vuex'

 

    

    >>使用时,可以直接传递2号参数

    

     >> 在 vuex 模块中,通过 getters 中的属性配置,来获取数据

  // 模块的 getter 属性
  getters:{
    total(state){
      let c=0
      state.cart.forEach(goods=>c+=goods.goods_count)
      return c
    }
  }

 

     >> 在业务模块中,通过注册的  mapGetters 来配置计算属性

    computed:{
      // 将 m_cart 模块中的 cart 数组,映射到当前模块
      ...mapState('m_cart',[]),
      ...mapGetters('m_cart',['total'])
    },

 

    >> 如果读取的属性为计算属性,可以通过配置 watch 监听器,来监听数据的变化  (与 data 同级)

watch:{
      // 监听total值的变化
      total(newVal){
         // 遍历数组,查找 购物车
         const findResult = this.options.find((x)=>x.text==='购物车')
         if(findResult){
           // 修正购物车按钮的 info 属性
           findResult.info = newVal
         }
      }
    },

 

  >> 购物车数据的持久化存储

    >  在 mutation 中,定义函数 saveToStorage,调用uni中的方法存储数据到 storage 中;

    >  在 mutation 中,通过  this.commit('m_cart/saveToStorage') 这种方式,调用持久化存储函数;

    >  在 state 初始化时,通过 uni 中的函数 getStorageSync 读取持久化存储的信息,注意不存在时取'[]' 空数组字符串值;

  >> 关于 普通函数形式 监听器 页面首次加载不会被调用问题的处理 

    >> 普通函数形式:

      

    >> 对象形式:

      

    >> tabBar 数字角标的配置 (配置 pages/cart/cart.vue)

      

   >> 购物车 数字角标 功能的抽取 : 抽取为 mixin 对象

    >  在项目根目录新建文件夹: mixins

    > 在 mixins 文件夹内新建 tabbar-badge.js 文件 内容如下:    

// 映射购物车数量
  import {mapGetters} from 'vuex'
  export default {
    computed:{
      ...mapGetters('m_cart',['total'])
    },
    onShow(){
      // 初始化后展示时,直接设备 tabBar 页面的购物车商品数量 
      this.setBadge()
    },
    methods:{
      setBadge(){
        uni.setTabBarBadge({
          index:2,
          text:this.total+'' //text只能为字符串,不能为数字
        })
      }
    }
  }

 

    > 业务模块使用 mixins 中的内容

     

    >> 开发过程中,如果出现,部分页面可以使 mixins 内容生效,部分不生效的情况

      》  处理方式: 把 template 模板 中的内容前切走,保存,此时将激活;再恢复之前的模板文件,则生效了;