uniapp-黑马优选学习02
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 模板 中的内容前切走,保存,此时将激活;再恢复之前的模板文件,则生效了;

浙公网安备 33010602011771号