Vue2项目实战--b站尚硅谷--尚品汇项目--详细笔记--day06

1 搜索页中排序操作

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();
},

2 分页功能实现

为什么采用分页功能,因为可能一下子同时展示数据过多,加载缓慢 卡顿

重点掌握分页器的原理

分页器Pagination作为全局组件,需要在入口文件中注册

import Pagination from '@/components/Pagination'
Vue.component('Pagination', Pagination)

接下来准备静态组件

2.1 分页器展示,需要哪些数据 条件

  • 当前是第几页: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

2.2 分页器中,计算连续页码的起始和结束页码是重要的 注意分页器无0和负数

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>

现在传入真数据

pageNopageSize都有,totalsearch仓库中,还没有捞

//search组件中先捞数据
import { mapGetters, mapState } from "vuex";
//search模块展示产品的总量--total
...mapState("search", ["total"]),
<Pagination
  :pageNo="searchParams.pageNo"
  :pageSize="searchParams.pageSize"
  :total="total"
  :continues="5"
/>

2.3 分页事子组件,点击按钮要告诉父亲捞第几页的数据

所以是—子给父传数据----自定义事件

//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>

2.4 分页器添加类名

//:class="{active:pageNo==1}"  同样的上中下都需要添加
<button v-if="startNumAndEndNum.start > 1" @click="$emit('getPageNo', 1)" :class="{active:pageNo==1}">1button>
.active{
    background: skyblue;
}

3 开发详情页

工作的大致顺序:

静态组件:详情页组件还未注册为路由组件

//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 || {}

Vue2项目实战--b站尚硅谷--尚品汇项目--详细笔记--day06_第1张图片

捞数据

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"]),

继续展示

//把数据搬上去就可以啦!!!!!!!!

你可能感兴趣的:(前端项目,vue.js,前端,javascript,webpack,ajax)