pc 电商平台----search模块

4 阅读1分钟

pc 电商平台----search模块

目录

[TOC]

vuex中的模块化

vuex使用三部曲

写请求

页面dispatch派发actions 保存到vuex中(actions 发请求commit通知mutations ,mutations修改仓库数据)

页面捞取数据(辅助函数mapState 映射为计算属性)

大仓库

import Vue from 'vue'
import Vuex from 'vuex'
import home from './home'
import search from './search'
//需要使用插件
Vue.use(Vuex)
 
 
// 对象暴露一个store类的一个实例
export default new Vuex.Store({
    modules: {
        home,
        search
    }
})

小仓库

import axios from '@/api'
// home 组件的小仓库
const state = {
    //默认初始值要依据服务器数据格式
    CategoryList: []
}
const mutations = {
    CategoryList(state, payload) {
        state.CategoryList = payload
    }
}
const actions = {
    //通过api接口获取数据
    async AstncCategoryList({ commit }) {
        let { data, code } = await axios.CategoryList();
        if (code !== 200) return
        commit('CategoryList', data)
    }
}
const getters = {}
export default {
    state,
    mutations,
    actions,
    getters
}

挂载

//引入仓库
import store from './store'
new Vue({
  render: h => h(App),
  //组件身上会多一个store的属性
  store
}).$mount('#app')

页面

state中分模块 计算属性映射为页面变量

 import { mapState } from "vuex";
 computed: {
    ...mapState({
      //右侧需要的是一个函数,当使用这个计算属性的时候,右侧函数会立即执行一次
      //注入一个state
      CategoryList: (state) => state.home.CategoryList,
    }),
  },

actions 不分模块

  mounted() {
    //通知vuex发请求,获取数据存储于vuex中
    this.$store.dispatch("AstncCategoryList");
  },

getters用于简化数据

//计算属性 简化数据
const getters = {
    //当前仓库的state
    goodsList(state) {
        //以防网络延迟返回undefined
        return state.SearchList.goodsList || []
    }
}

Object.assign()用法

1.Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。
2.Object.assign方法实行的是浅拷贝,而不是深拷贝。目标对象拷贝得到的是这个对象的引用
3.语法:Object.assign(target, …sources)

let aaa = {
 text: 2,
 value: 11,
}
 
let bbb = {
  text: 3
}
 
let ccc = Object.assign(aaa,bbb) // aaa目标对象, bbb源对象
 
console.log(aaa) //3 11
console.log(bbb) //3
console.log(ccc) //3 11

总结:Object.assign()合并对象时,若存在键名相同,值不同,则以合并后的值(ccc)该键的值为源对象(bbb)的值,且目标对象(aaa)的值也改变了

watch监听

这就是异步请求的问题了,就比如我们异步请求一个数据,然而主线程依旧正常运行,当我们监听到数据请求过来了,有数据了,才能再去进行其他操作,这就是监听的意义

watch监听里面有几个属性:immediate,deep和handler

watch: {
    //监听carouselList状态发生变化
    carouselList: {
      //深度监听
      deep:true
      //立即监听
      immediate:true
      //监听到carouselList状态发生变化了
      handler((newValue, oldValue){
        //监听到数据后的下一步操作
      }
   }      
}

数组方法splice与split

splice

splice()的主要用途是向数组中部插入项,方式有以下三种:

1、删除:可以删除任意数量的项,只需要指定两个参数:要删除的第一项的位置和要删除的项数。

2、插入:可以向指定位置插入任意数量的项,只要提供三个参数:起始位置、0(要删除的项数)、和要插入的项。

3、替换:可以向指定位置插入任意数量的项,同时删除任意数量的项,指定三个参数:起始位置、要删除的项数、和要插入的任意数量的项。

splice()方法始终返回一个数组,该数组包含从原始数组中删除的项(如果没有删除任何项,返回一个空数组)

代码显示方法:

var colors =["red","green","blue"];
var removed = colors.splice(0,1);//删除第一项
console.log(colors);
console.log(removed);
 
removed = colors.splice(1,0,"yellow","blank");//从位置1插入两项
console.log(colors);
console.log(removed);
 
removed = colors.splice(1,1,"yellow","blank");//插入两项,替换一项
console.log(colors);
console.log(removed);
————————————————
[ 'red' ]
[ 'green', 'yellow', 'blank', 'blue' ]
[]
[ 'green', 'yellow', 'blank', 'blank', 'blue' ]
[ 'yellow' ]

split() 方法

split() 方法用于把一个字符串分割成字符串数组。

separator参数:必需填。字符串或正则表达式,从该参数指定的地方分割 stringObject。
howmany参数:可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度

"2:3:4:5".split(":")    
//将返回["2", "3", "4", "5"]
 
"|a|b|c".split("|") 
//将返回["", "a", "b", "c"]
"hello".split("")   
//可返回 ["h", "e", "l", "l", "o"],分割单词
 
"hello".split("", 3)    
//可返回 ["h", "e", "l"],取单词前三个字母

数组去重

利用set结构成员值唯一的特点

 var arr = [100, 20, 30, 50, 30, 100, 20, 50];//[100,20,30,50]
 var arrSet = new Set(arr);
 //arrSet即没有重复元素的数组

//遍历旧数组,然后拿着旧数组去查询新数组,如果该元素在新数组里面没有出现过,我们就添加,否则就不添加

//利用新数组indexOf(数组元素),如果返回是-1就说明新数组里没有该元素

 
	function unique(arr){
	    var newarr = [];
		for(i=0;i<arr.length;i++){
			if(newarr.indexOf(arr[i]) === -1){
			newarr.push(arr[i]);
			    }	
			}
			return newarr;	
	    }
			var arr1 =  unique(['a','v','a']);
			console.log(arr1)

自定义分页器

  • 电商平台同时展示很多数据减小服务器压力采用分页
  • 需要知道我们当前是第几个pageNo字段,代表当前页数
  • 每一个需要展示多少条数据pageSize字符
  • 一共有多少也条数据total  【可以知道分页器一共有几页】
  • 连续页码数:5|7【奇数】continues
  • @getPageNo="getPageNo" 获取当前页数

重点:计算 起始 结束连续页码数(当前页在中间加2或减2 )

<template>
  <div class="pagination">
    <button :disabled="pageNo == 1" @click="$emit('getPageNo', pageNo - 1)">
      上一页
    </button>
    <button
      v-if="statrtNumAndEndNum.start > 1"
      @click="$emit('getPageNo', 1)"
      :class="{ active: pageNo == 1 }"
    >
      1
    </button>
 
    <button v-if="statrtNumAndEndNum.start > 2">···</button>
    <!-- v-for可以遍历对象 数字 字符串 数组
    遍历结束页码数(只要大于等于开始页码数其他隐藏)
    -->
    <button
      v-for="(page, index) in statrtNumAndEndNum.end"
      :key="index"
      @click="$emit('getPageNo', page)"
      :class="{ active: pageNo == page }"
      v-if="page >= statrtNumAndEndNum.start"
    >
      {{ page }}
    </button>
 
    <button v-if="statrtNumAndEndNum.end < totalPage - 1">···</button>
    <button
      v-if="statrtNumAndEndNum.end < totalPage"
      @click="$emit('getPageNo', totalPage)"
      :class="{ active: pageNo == totalPage }"
    >
      {{ totalPage }}
    </button>
    <button
      :disabled="pageNo == totalPage"
      @click="$emit('getPageNo', pageNo + 1)"
    >
      下一页
    </button>
 
    <button style="margin-left: 30px">共 {{ total }} 条</button>
  </div>
</template>
 
<script>
//:pageNo="1" 当前第几页
//:pageSize="3" //一页多少条
//:total="91" //总共多少条
//:continues="5" //连续页码数
export default {
  name: "pagination",
  props: ["pageNo", "pageSize", "total", "continues"],
  computed: {
    //计算出多少页
    totalPage() {
      //向上取整计算多少页
      return Math.ceil(this.total / this.pageSize);
    },
    // 计算出连续页码数
    statrtNumAndEndNum() {
      const { continues, pageNo, totalPage } = this;
      // 存储开始数字与结束数字
      let start = 0,
        end = 0;
      //连续页码数至少为5(特殊情况只有4页)
      if (continues > totalPage) {
        start = 1;
        end = totalPage;
      } else {
        //总页数一定大于5
        // 比如当前为8  连续为5       // 6-7 8  9-10 5(8-5/2=8-2=6)
        // 比如当前为8  连续为7       // 5-6-7 8  9-10-11(8-3=5)
        start = pageNo - parseInt(continues / 2);
        end = pageNo + parseInt(continues / 2);
        //排除start为0或者负数
        if (start < 1) {
          start = 1;
          end = continues;
        }
        //排除超出总页数的情况
        if (end > totalPage) {
          end = totalPage;
          //假如当前是31页  (27-28-29-30  31)
          //假如当前是29页  (27-28-29  30  31)
          start = totalPage - continues + 1; //31-5+1
        }
      }
      return { start, end };
    },
  },
};
</script>
 
<style lang="less" scoped>
.pagination {
  text-align: center;
  button {
    margin: 0 5px;
    background-color: #f4f4f5;
    color: #606266;
    outline: none;
    border-radius: 2px;
    padding: 0 4px;
    vertical-align: top;
    display: inline-block;
    font-size: 13px;
    min-width: 35.5px;
    height: 28px;
    line-height: 28px;
    cursor: pointer;
    box-sizing: border-box;
    text-align: center;
    border: 0;
 
    &[disabled] {
      color: #c0c4cc;
      cursor: not-allowed;
    }
 
    &.active {
      cursor: not-allowed;
      background-color: #409eff;
      color: #fff;
    }
  }
  .active {
    background: skyblue;
  }
}
</style>