电商平台项目----三级联动

目录

三级联动

网络请求

axios的二次封装

跨域问题

模块化导入导出

vuex状态管理库

state   仓库存储数据的地方

1辅助函数映射为组件的计算属性

2计算属性

3具体的数据名称小胡子语法

mutations mutations修改state中的唯一手段 commit执行

1.直接执行

2辅助函数(也可以是对象自定义事件句柄)

actions  可以手写自己的业务处理异步 dispatch派发

1.直接派发

2辅助函数(也可以是对象自定义事件句柄)

getters 计算属性

1.直接读取

2.计算属性

3辅助函数映射为组件的计算属性

modules 模块化开发

动态添加样式或者类名

动态添加背景颜色

二三级分类的显示和隐藏、

函数的防抖和节流

自定义属性

过度动画

路由参数合并


三级联动

由于三级联动在Home Search Detail 把三级联动注册为去全局组件

只需要注册一次,就可以在项目任意地方使用

第一个参数为全局组件的名字,第二个为那个组件

Vue.component(TypeNav.name, TypeNav)

TypeNav 为全局组件不需要引入

网络请求

axios的二次封装

放置在api文件夹中 接口统一处理 挂载到原型Vue.prototype.$api = axios

请求拦截器 requests.interceptors.request.use:可以在发请求之前处理一些业务

响应拦截器 requests.interceptors.response.use:当服务器返回数据之后处理业务

baseURL: '/api' 基础路径,发送请求的时候路径中会出现api

timeout: '5000', 请求超时时间 5s

// 对axios二次封装
import axios from 'axios'


// 利用axios对象方法的created,创建一个axios实例
const requests = axios.create({
    //配置对象
    // 基础路径,发送请求的时候路径中会出现api
    baseURL: '/api',
    //请求超时时间 5s
    timeout: '5000',
})
//请求拦截器
requests.interceptors.request.use((config) => {
    // config配置对象 header请求头
    return config
})
//响应拦截器
requests.interceptors.response.use((res) => {
    //成功的回调函数
    return res.data
}, (error) => {
    //响应失败的回调函数
    return Promise.reject(new Error('false'))
})
export default requests

跨域问题

协议 域名 端口号 不一致称为跨域

jsonp ,cros, 代理

浏览器跟服务器之间才有跨域问题,服务器跟服务器之间没有

在vue.config.js中配置webpack配置项

  //代理跨域
  devServer: {
    proxy: {
      "/api": {
        target: "http://gmall-h5-api.atguigu.cn",
        pathRewrite: { "^/api": "" }
      }
    }
  }

模块化导入导出

export default{} 导出对象 导入使用 import axios from 'axios'

export const a 导出变量  导入某个变量解构赋值

export const a 导出变量  import * as axios from 'axios' 导入全部变量

vuex状态管理库

vuex是官方提供的插件 状态管理库, 集中式管理项目中的组件共用数据 多个组件依赖同一个值 

new Vuex.Store 对象暴露一个store类的一个实例

Vue.use(Vuex) 需要使用插件

state   仓库存储数据的地方

vuex  设置值 const state = {count: 1};

1辅助函数映射为组件的计算属性

  数组形式
  import { mapState } from "vuex";
  computed: {...mapState(["count"])},
  对象形式 可以指定键
  computed: { ...mapState({ n: "count"}),
  函数形式
  computed: {
    ...mapState({
      //右侧需要的是一个函数,当使用这个计算属性的时候,右侧函数会立即执行一次
      //注入一个state
      CategoryList:state=>state.home.CategoryList
    }),

2计算属性

  computed: {
    count() {
      return this.$store.state.count;
    },
  },

3具体的数据名称小胡子语法

{{this.$store.state.count}}

mutations mutations修改state中的唯一手段 commit执行

// state 仓库  payload载荷
    add(state, payload) {
        state.count++
        state.count += payload
      }

1.直接执行

this.$store.commit("add", 1);

2辅助函数(也可以是对象自定义事件句柄)


import { mapMutations } from "vuex";
  methods: {...mapMutations(["add"])},
  <button @click="add(1)">点我加一</button>

actions  可以手写自己的业务处理异步 dispatch派发

// content vuex上下文 payload 载荷
    addSync(content, payload) {
        content.commit('add', payload)
    }

1.直接派发

this.$store.dispatch("add", 1);

2辅助函数(也可以是对象自定义事件句柄)

import { mapActions } from "vuex";
methods: {...mapActions(["addSync"])},
<button @click="addSync(1)">点我加一</button>

getters 计算属性

vuex
    showNum(state) {
        return state.arr.filter(item => {
            return item > 10
        })
    }

1.直接读取

{{ this.$store.getters.showNum }}

2.计算属性

  computed: {
    arr() {
      return this.$store.getters.showNum;
    },
  },

3辅助函数映射为组件的计算属性

  数组形式

  import { mapGetters } from "vuex";

  computed: {...mapGetters(["arr"])},

  对象形式 可以指定键

  computed: { ...mapGetters({ a: "arr"}),

modules 模块化开发

// search 组件的小仓库
const state = {}
const mutations = {}
const actions = {}
const getters = {}
export default {
    state,
    mutations,
    actions,
    getters
}
vuex
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
    }
})

动态添加样式或者类名

动态添加背景颜色

第一种css :hover 伪类选择器 选择器用于选择鼠标指针浮动在上面的元素。

   .item:hover {
          background: blue;
    }

第二种:js

<h3 @mouseenter="changeIndex(index)" @mouseleave="leaveIndex"> </h3>
    动态绑定类名 移入元素索引==响应式数据添加样式
   :class="{ cur: currentIndex == index }"
     data() {
    return {
      currentIndex: -1,
    };
  },
    methods: {
    //鼠标移入改变响应式数据
    changeIndex(index) {
      //index鼠标移入的索引值
      this.currentIndex = index;
    },
    //鼠标移除的事件
    leaveIndex() {
      this.currentIndex = -1;
    },
  },

二三级分类的显示和隐藏、

css display: none; 鼠标滑过display:block

js  :style="{ display: currentIndex == index ? 'block' : 'none' }"

函数的防抖和节流

//index鼠标移入的索引值

/正确情况下每一个都会触发鼠标移入事件

// 如果很快只触发部分,由于用户操作行为过快,导致浏览器解析不过来出现卡顿

防抖:前面的所有的触发都取消,最后执行一次 在规定的时间之后才会触发,多次点击只会执行一次

节流:在规定的时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发

防抖:用户操作很频繁但 只执行一次    节流 用户操作很频繁 降低触发频率

lodash插件里面封装了函数防抖与节流【闭包+延迟器】

lodash函数库对外暴露了函数

防抖
input.oninput=_.debounce(function(){
console.log('ajax请求')
},1000)
节流
button.onclick=_.throttle(function(){
  //:节流目前这个回调函数5s执行一次,给浏览器解析时间
  count++
},5000)

 项目应用

// 全部引入
import _ from "lodash";
    changeIndex: _.throttle(function (index) {
      console.log(index);
      this.currentIndex = index;
    }, 50),

自定义属性

router-link为vue内部组件如果循环组件会出现延迟 

三级联动 最好的解决方案:编程时导航+事件委托

 通过自定义属性 :data-categoryName 区分a标签

取自定义属性值:event.target.dataset.自定义属性 对象、浏览器自动把自定义属性转为小写

event事件对象

  • 1.自定义属性 :data-自定义属性
  • 2.获取自定义属性值:event.target.dataset.自定义属性
   goSearch(event) {
      // event事件对象
      //最好的解决方案:编程时导航+事件委托
      // 通过自定义属性 :data-categoryName 区分a标签
      //获取自定义属性值:event.target.dataset.自定义属性 对象、浏览器自动把自定义属性转为小写
      let element = event.target;
      let { categoryname, category1id, category2id, category3id } =
        element.dataset;
      //如果有自定义属性 categoryname 一定是a标签
      if (categoryname) {
        let location = {
          name: "Search",
        };
        let query = { categoryName: categoryname };
        // 一级二级三级分类的a标签
        if (category1id) {
          query.category1Id = category1id;
        } else if (category2id) {
          query.category2Id = category2id;
        } else {
          query.category3Id = category3id;
        }
        //整理完整参数
        location.query = query;
        // 路由跳转
        this.$router.push(location);
      }
    },

过度动画

前提:组件,元素比需要有v-if|v-show 指令才可以进行过度动画

使用内置组件  <transition name="sort"></transition> 要有name

通过样式添加动画

  • .sort-enter     //开始状态(进入)
  • .sort-enter-to      //结束状态(移除)
  • .sort-enter-active {transition: all 0.5s linear; } //定义动画的时间 速率

路由参数合并

如果既有query参数,右有paramis参数要进行合并避免丢失

    goSearch() {
      if (this.$route.query) {
        let location = {
          name: "Search",
          params: { keyWord: this.keyWord },
        };
        location.query = this.$route.query;
        this.$router.push(location);
      }
    },

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值