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 模板 中的内容前切走,保存,此时将激活;再恢复之前的模板文件,则生效了;
标签:02,uniapp,goods,cart,js,模块,uni,黑马,store From: https://www.cnblogs.com/jieling/p/17471259.html