1:综合
、2:价格
、asc:升序
、desc:降序
----------示例:“1:desc”
首先order
应该有初始值“1:desc”
第一个问题:考虑谁有价格的颜色类名 综合还是价格
通过order
属性值中的1
还是2
来确定是综合还是价格
<li :class="{active:searchParams.order.indexOf('1')!=-1}">
<a >综合a>
li>
//可以用计算属性来简化,记得加上this.searchParams.order.indexOf('1')!=-1
第二个问题:考虑谁应该有箭头
谁有类名active
谁有箭头—用v-if
或者v-show
v-show="isOne"//v-show="isTwo"
第三个问题:箭头用什么制作
阿里在线图标库–搜索图标添加购物车–创建项目–加入项目–获取在线地址–复制代码使用
用的时候先引入在线的,加上https:
<link rel="stylesheet" href="https://at.alicdn.com/t/c/font_3694696_b49vvjlz2l6.css">
组件中使用时需要类名iconfont
<li :class="{ active: 'isOne' }">
<a>综合
<span
v-show="isOne"
class="iconfont"
:class="{ 'icon-run-up': isAsc, 'icon-DOWN': isDesc }"
>span>
a>
li>
接下来给两个li标签
绑定单击事件,点击升序降序–需要传参
传进来的参数和起始searchParams
中的order
进行对比
//排序的单击事件
changeOrder(flag) {
// flag是形参 代表用户点击的是1还是2代表综合或者价格
// let originOrder = this.searchParams.order;
//获取最初始状态
let originFlag = this.searchParams.order.split(":")[0];
let originSort = this.searchParams.order.split(":")[1];
//再准备一个新的order属性值
let newOrder = "";
//这个语句确定是点击综合
if (flag == originFlag) {
newOrder = `${originFlag}:${originSort == "desc" ? "asc" : "desc"}`;
} else {
//这个确定一上来单击的不是初始状态,而是单击了价格
newOrder = `${flag}:${"desc"}`;
}
//最后 将newOrder赋予searchParams
this.searchParams.order = newOrder;
//再次发请求
this.getData();
},
//简化写法
changeOrder(flag) {
this.searchParams.order == `${flag}:desc`?
(this.searchParams.order = `${flag}:asc`) : (this.searchParams.order = `${flag}:desc`);
//再次发请求
this.getData();
},
为什么采用分页功能,因为可能一下子同时展示数据过多,加载缓慢 卡顿
重点掌握分页器的原理
分页器Pagination
作为全局组件,需要在入口文件中注册
import Pagination from '@/components/Pagination'
Vue.component('Pagination', Pagination)
接下来准备静态组件
pageNo
字段代表当前页数pageSiza
字段total
字段代表------也可以知道总共需要多少页–向上取整continues
----一般为5个或者7个自定义分页器,开发时用自己的数据进行调试,ok了再调用后台数据
先自己测试
父组件给子组件传数据—props
//search组件中---测试阶段
<Pagination :pageNo="1" :pageSize="3" :total="90" :continues="5" />
子组件收到参数之后,用props
接受–进行展示(可以适当进行计算属性)
分页器关键点在于算出连续页码的起始和结束页码,还有就是关键点在于解决不正常的现象
pageNo
为7时:5 6 7 8 9
start的情况:
当前页码为1
时,连续页为5
,应该显示:1 2 3 4 5
,而不是:-1 0 1 2 3
当前页码为2
时,连续页为5
,应该显示:1 2 3 4 5
,而不是:0 1 2 3 4
当前页码为3
时,连续页为5
,应该显示:1 2 3 4 5
正常
当前页码为4
时,连续页为5
,应该显示:1 2 3 4 5 6
,而不是:2 3 4 5 6
要带上1
end的情况:
比如总91条数据—就是总共31页
当前页码为31
时,连续页为5
,应该显示:27 28 29 30 31
,而不是:29 30 31 32 33
当前页码为30
时,连续页为5
,应该显示:27 28 29 30 31
,而不是:28 29 30 31 32
当前页码为29
时,连续页为5
,应该显示:27 28 29 30 31
,正常
当前页码为28
时,连续页为5
,应该显示:26 27 28 29 30 31
,而不是:26 27 28 29 30
,带上31
子组件中
startContinuePage() {
//解构出来,用的时候就不用.this
const { continues, pageNo, totalPage } = this;
//定义两个变量--起始--结束
let start = 0,
end = 0;
//连续页码至少是五页,如果有不正常的情况
if (continues > totalPage) {
//不正常现象 总页面少于5页
start = 1;
end = totalPage;
} else {
//正常现象 总页面大于5页
//不能直接减2,这样取整,这样写适用于任意连续页码数 5 7 9等
start = pageNo - parseInt(continues / 2);
//同理
end = pageNo + parseInt(continues / 2);
//当出现不正常现象(start出现负数或0)
if (start < 1) {
start = 1;
end = continues;
}
if (end > totalPage) {
end = totalPage;
//注意需要加1
start = totalPage - continues + 1;
}
}
return { start, end };
},
分页器动态展示
分为上中下
v-for
:可以遍历 数组
|数字
|字符串
|对象
<button>上一页button>
<button v-if="startContinuePage.start > 1">1button>
<button v-if="startContinuePage.start > 2">···button>
<button
v-for="(page, index) in startContinuePage.end"
:key="index"
v-show="page >= startContinuePage.start"
>
{{ page }}
button>
<button v-if="startContinuePage.end < totalPage - 1">···button>
<button v-if="startContinuePage.end < totalPage">{{ totalPage }}button>
<button>下一页button>
<button style="margin-left: 30px">共 {{ total }} 条button>
现在传入真数据
pageNo
和pageSize
都有,total
在search
仓库中,还没有捞
//search组件中先捞数据
import { mapGetters, mapState } from "vuex";
//search模块展示产品的总量--total
...mapState("search", ["total"]),
<Pagination
:pageNo="searchParams.pageNo"
:pageSize="searchParams.pageSize"
:total="total"
:continues="5"
/>
所以是—子给父传数据----自定义事件
//1 父组件中自定义事件
<PaginationYu :pageNo="searchParams.pageNo" :pageSize="searchParams.pageSize" :total="total" :continues="5" @getPageNo="getPageNo" />
//2 父组件中
// 自定义事件 ---- 获取当前第几页---父亲在等待儿子传数据
getPageNo(pageNo) {
//整理数据 带给服务器的参数
this.searchParams.pageNo = pageNo;
//发请求
this.getData();
},
//给父组件传递参数---当前页码给父组件
//上
<button :disabled="pageNo==1" @click="$emit('getPageNo', pageNo-1)">上一页button>
<button v-if="startNumAndEndNum.start > 1" @click="$emit('getPageNo', 1)">1button>
//中
<button v-if="page >= startNumAndEndNum.start" @click="$emit('getPageNo', page)">{{ page }}button>
//下
<button v-if="startNumAndEndNum.end < totalPage" @click="$emit('getPageNo', totalPage)">{{ totalPage }}button>
<button :disabled="pageNo==totalPage" @click="$emit('getPageNo', pageNo+1)">下一页button>
//:class="{active:pageNo==1}" 同样的上中下都需要添加
<button v-if="startNumAndEndNum.start > 1" @click="$emit('getPageNo', 1)" :class="{active:pageNo==1}">1button>
.active{
background: skyblue;
}
工作的大致顺序:
静态组件:详情页组件还未注册为路由组件
//1 在router的index中引入
import DetailYu from '@/pages/Detail'
routes: [
{
//params参数占位
path: '/detail/:skuid',
component: DetailYu,
meta: { show: true }
},
]
点击商品的时候,跳转到详情页面,路由跳转时需要带上商品
ID
给详情页–good.id
//点击搜索页中的产品列表图片进行跳转 a标签换成--声明式导航
<router-link :to="`/detail/${good.id}`"><img :src="good.defaultImg" />router-link>
可以将路由配置信息摘出来–routes.js
在index
文件中引入就可以
滚动行为,跟routes平级
//配置路由
export default new VueRouter({
//配置路由
routes: routes,
scrollBehavior(to, from, savedPosition) {
// 始终滚动到顶部
return { top: 0 }
},
})
OK到此为止静态组件已经有了,接下来:
发请求(API
):请求的接口
//api中
//获取商品详情页的信息: URL:/api/item/{ skuId } GET
export const reqGoodsInfo = (skuId) => requests({
url: `item/${skuId}`,
method: 'get',
})
vuex
:获取产品详情信息
Vuex
仓库(store
)中新增模块detail.js
const state = {}
const mutations = {}
const actions = {}
const getters = {}
export default {
state, mutations, actions, getters
}
回到大仓库中进行合并
store中
的index.js
import detail from "./detail";
发请求–捞数据–存仓库
//小仓库中
import {reqGoodsInfo} from '@/api'
const actions = {
//获取产品信息的action
async reqGoodsInfo({commit}, skuId) {
let result = await reqGoodsInfo(skuId)
if (result.code==200) {
commit('GETGOODSINFO',result.sata)
}
}
}
const mutations = {
GETGOODSINFO(state,goodInfo){
state.goodInfo = goodInfo
}
}
const state = {
//初始化 不能瞎写
goodInfo:{}
}
现在还没有信息,要派发
action
获取—在详情页中Detail
中的index.vue
mounted() {
//派发action获取产品信息
this.$store.dispatch("detail/getGoodsInfo", this.$route.params.skuid);
},
**动态展示组件:**找仓库要数据 展示
先在仓库里面的getters
中简化获取数据
//简化数据---仓库
const getters = {
categoryView(state) {
return state.goodInfo.categoryView
}
}
//注意
//这样子写初始是空对象 categoryView是undefined 里面没有categoru1Name 就会报错
//undefined点categoru1Name出来会报错 点出来是undefined没问题 至少空对象可以点categoru1Name
return state.goodInfo.categoryView || {}
捞数据
import { mapGetters } from "vuex";
computed: {
...mapGetters('detail',["categoryView"]),
},
展示数据
<div class="conPoin">
<span v-show="categoryView.category1Name">{{
categoryView.category1Name
}}span>
<span v-show="categoryView.category2Name">{{
categoryView.category2Name
}}span>
<span v-show="categoryView.category3Name">{{
categoryView.category3Name
}}span>
div>
继续获取
skuInfo(state) {
return state.goodInfo.skuInfo || {}
}
...mapGetters('detail',["categoryView", "skuInfo"]),
继续展示
//把数据搬上去就可以啦!!!!!!!!