Vue2电商前台项目(二):完成Home首页模块业务

一、项目开发的步骤

1、书写静态页面(HTML,CSS)
2、拆分组件
3、获取服务器的数据动态展示
4、完成相应的动态业务逻辑

经过分析之后,Home首页可以拆分为7个组件:TypeNav三级联动导航,ListContainer,Recommend,Rank,Like,Floor,Brand。主要得看你静态页面把谁谁写在一个结构里面了,组件就得在一个里面。

二、Home首页拆分静态组件

1.TypeNav三级联动的完成

如果有哪个组件在项目中频繁使用(三级联动在Home、Search、Detail都用到了),就把它注册成全局组件。

好处:只需要注册一次可以在项目的任意地方使用。

首先在home下新建一个三级联动组件的文件夹TypeNav,底下有一个文件叫index.vue,然后把它注册为全局组件,回到入口文件main.js,需要使用到Vue.component

//三级联动的组件——全局组件
import TypeNav from '@/pages/Home/TypeNav'
//第一个参数是全局组件的名字,第二个参数是:哪一个组件
Vue.component(TypeNav.name,TypeNav)

现在回到home组件里就可以使用TypeNav了:

<!-- 三级联动全局组件 ,它已经注册为全局组件了,不需要再引入-->
    <TypeNav/>

2.完成其余静态组件

完成轮播图和右边快报的部分

拆分组件就三步:结构、样式、图片资源

3.POSTMAN测试接口

刚刚经过postman工具测试,接口是没有问题的
如果服务器返回的数据code字段200,代表服务器返回数据成功
整个项目,接口前缀都有/api字样

三、请求服务器数据的准备工作

1.axios二次封装

向服务器发请求:XMLHttpRequest、fetch、JQ、axios

为什么需要进行二次封装axios?
请求拦截器、响应拦截器:请求拦截器,可以在发请求之前可以处理一些业务、响应拦截器,当服务器数据返回以后,可以处理一些事情

首先安装axios :npm install axios

项目当中通常放API文件夹用于放axios,src/api/request.js:

//对于axios进行二次封装
import axios from 'axios'

//利用axios对象的方法create,去创建一个axios实例
//request就是axios,只不过配置一下

const requests = axios.create({
    //配置对象
    //基础路径
    //baseURL: '/api',
    //代表请求时间超时,超过五秒还没发回来说明请求失败
    timeout: 5000,
})
//create方法里面可以写对象

//请求拦截器
requests.interceptors.request.use((config) => {
    //config是一个配置对象,里面有一个属性很重要:header请求头
    return config
})

//响应拦截器,有成功回调和失败回调
requests.interceptors.response.use((res)=>{
//成功的回调函数:服务器相应数据回来以后,响应拦截器可以检测到
return res.data
},(err)=>{
//响应失败
return Promise.reject(new Error('false'))
})
export default requests

2.api接口统一管理

项目很小:完全可以在组件的生命周期函数中发请求,在mounted或者created里发请求,存储在data当中。

项目大的话,专门建立一个index.js进行统一管理

//当前这个模块,所有API接口进行统一的管理
//发请求用到axios,引入进来
import requests from "./request";

//三级联动的接口
 export const reqcategoryList=()=>{
    //axios发请求返回promise对象
    return requests({url:'http://gmall-h5-api.atguigu.cn/api/product/getBaseCategoryList',method:'get'})
 }

main.js调用

import {reqcategoryList} from '@/api'
reqcategoryList()

但是请求错误,因为出现了跨域问题,我们所在的是本地服务器,请求的接口不在

解决跨域问题:JSONP、CROS、代理

这里我们选择代理,在vue.config.js:

//代理跨域,第三方
  devServer: {
    proxy: {
      '/api': {
        target: 'http://gmall-h5-api.atguigu.cn/api/product/getBaseCategoryList',
        //pathRewrite: { '^/api': '' },
      },
    },
  }

注意:数据请求需要服务器+接口 不要只是访问服务器这样是拿不到数据的,
比如 http://gmall-h5-api.atguigu.cn(这是服务器) /api/product/getBaseCategoryList(这是接口)把接口放在服务器后面就可以
例如:http://gmall-h5-api.atguigu.cn/api/product/getBaseCategoryList 不要只是访问服务器

3.nprogress进度条的使用

安装插件:npm install nprogress

start:进度条开始

done:进度条结束

//引入进度条
import nprogress from 'nprogress'
//引入进度条的样式
import 'nprogress/nprogress.css'
//请求拦截器
requests.interceptors.request.use((config) => {
    //进度条开始动
    nprogress.start()
    //config是一个配置对象,里面有一个属性很重要:header请求头
    return config
})

//响应拦截器,有成功回调和失败回调
requests.interceptors.response.use((res) => {
    //进度条结束
    nprogress.done()
    //成功的回调函数:服务器相应数据回来以后,响应拦截器可以检测到
    return res.data
}, (err) => {
    //响应失败
    //return Promise.reject(new Error('false'))
    return err.message
})
export default requests

四、Vuex模块化开发

vuex是官方提供一个插件,状态管理库,集中式管理项目中组件共用的数据。
切记,并不是全部项目都需要Vuex,如果项目很小,完全不需要Vuex,如果项目很大,组件很多、数据很多,数据维护很费劲,Vuex几个核心概念:

state:仓库存储数据的地方
mutations:唯一修改state手段
actions:处理action,可以书写自己的业务逻辑,也可以处理异步
getters:计算属性,用于简化仓库数据,让组件获取仓库的数据更加方便
modules:模块式开发

安装vuex:npm i vuex@3

注意vue2的一定不要下错!!!!!

vuex是一个对象,store是它的一个方法,而这个方法是一个构造函数,可以初始化vue仓库

新建一个src下的store文件/index.js:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

//对外暴露store类的一个实例
export default new Vuex.Store({
    state:{},
    mutations:{},
    actions:{},
    getters:{}
})

然后到入口文件去注册一下:

//引入仓库
import store from './store' 

new Vue({
  render: h => h(App),
  router,
  //注册仓库:组件实例的身上会多一个$store的属性
  store
  //KV一致省略V
  //注册路由信息:当这里书写router的时候,组件身上都拥有$route,$router
}).$mount('#app')

如果项目过大,数据过多,可以让vuex实现模块式开发,大仓库拆分成小仓库,每一个小仓库存储相应模块的数据

比如我们现在创建home、search的小仓库,分别在store下创建两个文件夹为home、search

然后他俩下面再创建index.js

//search模块下的小仓库
const state={}
const mutations={}
const actions={}
const getters={}
export default {
    state,
    mutations,
    actions,
    getters
}

然后把两个小仓库合并到大仓库中去

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//引入小仓库
import home from './home'
import search  from './search'
//对外暴露store类的一个实例
export default new Vuex.Store({
    //实现Vuex仓库模块化开发存储数据
    modules:{
        home,
        search
    }
})

历尽千辛万苦终于知道为啥我没有vuex的数据了,下载的时候下成了最新版的vuex,得先卸载了最新的再下,卸载:npm uninstall vuex

五、TypeNav导航三级联动

1.三级联动展示数据

一个小更改,之前的三级联动我们写在了home下,以后像这种不会更改的组件都写在components里

(1)组件挂载完毕后dispatch给Vuex

//组件挂载完毕,可以向服务器发请求
  mounted(){
    this.$store.dispatch('categoryList')
  },

(2)去home仓库请求数据

code号为200时,就把数据给过去

import { reqcategoryList } from "@/api"
//home模块下的小仓库
const state = {
    //state中数据默认初始值别瞎写,服务器返回的是对象,服务器返回数组【根据接口返回初始化】
    categoryList:[]
}
const mutations = {
    CATEGORYLIST(state,categoryList){
        state.categoryList=categoryList
    }
}
const actions = {
    //通过api里面的接口函数调用,向服务器发请求,获取服务器的数据
    async categoryList({ commit }) {
        let result = await reqcategoryList();
        if (result.code == 200) {
            commit("CATEGORYLIST", result.data)
        }
    }
};

(3)TypeNav接收数据

import{mapState} from 'vuex'
、、、
computed:{
    ...mapState({
      //右侧需要的是一个函数,当使用这个计算属性的时候,右侧函数会立即执行一次
      //注入一个参数state,其实即为大仓库中的数据
      categoryList:(state)=>{
        return state.home.categoryList
      }
    })
  }

(4)v-for去掉多余a标签

一级分类叫item,二级分类叫subitem,是一级分类中的categoryChild,还有三级分类,用em做的

<div class="item" v-for="c1 in categoryList" :key="c1.categoryId">
            <h3>
              <a href="">{{c1.categoryName}}</a>
            </h3>
            <div class="item-list clearfix">
              <div class="subitem" v-for="c2 in c1.categoryChild" :key="c2.categoryId">
                <dl class="fore">
                  <dt>
                    <a href="">{{c2.categoryName}}</a>
                  </dt>
                  <dd>
                    <em v-for="c3 in c2.categoryChild" :key="c3.categoryId">
                      <a href="">{{c3.categoryName}}</a>
                    </em>
                  </dd>
                </dl>
              </div>
            </div>
          </div>

2.一级分类动态展示背景颜色

(1)采用样式完成(hover)

         .item:hover{
                      background-color: skyblue;
                    }

(2)通过js完成

当用户鼠标移到哪个一级分类上就把它的索引值index给存起来,mouseenter事件,传参过来index,设置一个动态类名,谁被移上去谁就有那个类名

<div class="item" v-for="(c1,index) in categoryList" :key="c1.categoryId" :class="{cur:currentIndex==index}">
            <h3 @mouseenter="changeIndex(index)">
              <a href="">{{c1.categoryName}}</a>
            </h3>
data(){
    return {
      currentIndex:-1
      //用来记录鼠标在谁上,-1表示都不在
    }
  },
methods: {
    //鼠标进入修改index
    changeIndex(index){
      //index是鼠标在的一级分类
      this.currentIndex=index
    }
  },
.cur{
      background-color: skyblue;
     }

这样写实现了鼠标移上去背景颜色变蓝,但是鼠标移下来它还是蓝的(在鼠标最后待的h3)

所以还得有mouseleave事件,本来我还想着动颜色,结果发现直接index=-1更简单

<h3 @mouseenter="changeIndex(index)" @mouseleave="leaveIndex(index)">
、、、
leaveIndex(index){
      //鼠标移出的index=-1
      this.currentIndex=-1
    }

最后老师又更改了一下,当鼠标从第一个h3移到h2的时候蓝色不变,移出h2蓝色才消失,那么这个时候事件不能添加给h3了,用到了事件的委托,移出事件添加给父标签

<div @mouseleave="leaveIndex">
        <h2 class="all">全部商品分类</h2>
        <div class="sort">
          、、、、
              <h3 @mouseenter="changeIndex(index)">
                <a href="">{{ c1.categoryName }}</a>
              </h3>
              、、、

3.JS控制二、三级数据显示和隐藏

最开始是通过css样式display:none、block实现的

js实现:谁有背景颜色谁就有二三级分类

<!-- 二、三级分类 -->
<div class="item-list clearfix" :style="{display:currentIndex==index?'block':'none'}">

4.三级联动的防抖与节流

(1)防抖和节流是什么(面试频率高

卡顿现象:事件触发非常频繁,而且每一次的触发,回调函数都要去执行(如果时间很短,而回调函数内部有计算,那么很可能出现浏览器卡顿)

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

防抖:前面的所有的触发都被取消,最后一次执行在规定的时间之后才会触发,也就是说如果连续快速的触发 只会执行一次

防抖:写一个简单的页面来模拟,用户在搜索input表框时,直至输入停止再过一秒之后ajax才会发请求。(强调时刻)

//防抖:前面的所有的触发都被取消,最后一次执行 在规定的时间之后才会触发,也就是说如果连续快速的触发 只会执行一次
let input = document.querySelector('input');
//文本发生变化立即执行
input.oninput=_.debounce(function(){
console.log('ajax发请求')
},1000);
//lodash插件:里面封装函数的防抖与节流的业务【闭包+延迟器】
//1:1odash函数库对外暴露_函数

lodash原生代码 得看

节流:多么频繁的点击都是五秒钟加一次(强调时间)

//计数器:在一秒以内,数字只能加上1
button.onclick =_.throttle(function(){
//节流:目前这个回调函数5S执行一次,
//加入这里面有很多的业务代码,是不是可以给浏览器很充裕的时间去解析
count++;
span.innerHTML = count
console.log('执行')
},5000);
//防抖:用户操作很频繁,但是只是执行一次
//节流:用户操作很频繁,但是把频繁的操作变为少量操作【可以给浏览器有充裕的时间解析代码】

(2)三级联动导航节流

在项目中使用一下节流技术,防止用户操作过快

项目中node_module里有lodash,不用再自己下载

//这种是把lodash全部功能引入过来了
//import _ from 'lodash'
//按需引入,默认暴露所以不用再加{}了
import throttle from 'lodash/throttle'
、、、
methods: {
    //鼠标进入修改index
    // changeIndex(index) {
    //   //index是鼠标在的一级分类
    //   this.currentIndex = index;
    // },
    changeIndex:throttle(function(index){
      this.currentIndex = index;
    },50),

注意throttle回调函数不要使用箭头函数,容易产生this指向问题

明天继续更

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/518624.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

先进电机技术 —— 无线电机

一、背景 无线电能传输电机是一种创新的电机设计&#xff0c;它结合了无线电能传输技术与传统的电机工作原理。这种电机的主要特点是通过无线方式传输电能&#xff0c;从而消除了传统电机中需要有线连接的限制&#xff0c;提高了系统的灵活性和可靠性。 无线电能传输技术主要…

C51实现每秒向电脑发送数据(UART的含义)

其实核心的问题是&#xff1a;串口的通信方式 异步串行是指UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;&#xff0c;UART包含TTL电平的串口和RS232电平的串口 UART要实现异步通信的&#xff1a; UART是异步串行接口&#xff0c;通信双方使用时…

LeetCode每日一题之专题一:双指针 ——快乐数

快乐数OJ链接&#xff1a;202. 快乐数 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 题目分析: 为了房便叙述&#xff0c;将「对于⼀个正整数&#xff0c;每⼀次将该数替换为它每个位置上的数字的平方和」这⼀个 操作记为 x 操作&#xff1b; 题目告诉我们&#…

Shell脚本之基础-2

目录 一、字符处理 cut命令 awk命令 sed命令 字符串排序 二、条件判断 文件类型判断 文件权限判断 两个文件的判断 整数比较 字符串判断 多重判断 三、流程控制 if分支 if else 双分支结构 case分支 for循环 while循环 一、字符处理 cut命令 命令格式&#x…

Python 金融数据分析工具库之zvt使用详解

​​​​​​​ 概要 Python在金融数据分析领域有着广泛的应用,而zvt库作为一款强大的金融数据分析工具,为开发者提供了丰富的功能和灵活的应用接口。本文将深入介绍zvt库的安装、特性、基本功能、高级功能、实际应用场景,并总结其在金融数据分析中的价值和优势。 安装 …

mysql故障排查

MySQL是目前企业最常见的数据库之一日常维护管理的过程中&#xff0c;会遇到很多故障汇总了常见的故障&#xff0c;MySQL默认配置无法满足高性能要求 一 MySQL逻辑架构图 客户端和连接服务核心服务功能存储擎层数据存储层 二 MySQL单实例常见故障 故障1 ERROR 2002 (HY000)…

(echarts)title和legend不重叠/legend图例滚动显示不换行

(echarts)title和legend不重叠/legend图例滚动显示不换行 title和legend都被放置在了不同的位置&#xff0c;从而避免了重叠。你可以根据实际的图表布局和需求调整left&#xff08;水平位置&#xff09;和top&#xff08;垂直位置&#xff09;等属性&#xff0c;确保它们不会相…

【SCI绘图】【箱型图系列1 python】多类对比及各类下属子类对比

SCI&#xff0c;CCF&#xff0c;EI以及核心期刊绘图宝典&#xff0c;爆款更新&#xff0c;助力科研&#xff01; 本期分享&#xff1a; 【SCI绘图】【箱型图系列1】多类对比各类下属子类对比 文末附带完整代码&#xff1a; 1.环境准备 python 3 from matplotlib import pyp…

QT-QPainter

QT-QPainter 1.QPainter画图  1.1 概述  1.1 QPainter设置  1.2 QPainter画线  1.3 QPainter画矩形  1.4 QPainter画圆  1.5 QPainter画圆弧  1.6 QPainter画扇形 2.QGradient  2.1 QLinearGradient线性渐变  2.2 QRadialGradient径向渐变  2.3 QConicalGr…

【Unity每日一记】如何从0到1将特效图集制作成一个特效

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

Prometheus+grafana环境搭建Nginx(docker+二进制两种方式安装)(六)

由于所有组件写一篇幅过长&#xff0c;所以每个组件分一篇方便查看&#xff0c;前五篇链接如下 Prometheusgrafana环境搭建方法及流程两种方式(docker和源码包)(一)-CSDN博客 Prometheusgrafana环境搭建rabbitmq(docker二进制两种方式安装)(二)-CSDN博客 Prometheusgrafana环…

数据分析python代码——数据填充

在Python中&#xff0c;我们通常使用pandas库来处理和分析数据。数据填充是数据预处理的一个重要步骤&#xff0c;用于处理数据中的缺失值。以下是使用pandas库进行数据填充的示例代码&#xff1a; 在数据分析中&#xff0c;处理缺失值&#xff08;空值&#xff09;是一个重要…

基于微信小程序的实验室预约系统的设计与开发

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

c语言文件操作(超详细)

前言 这次的博客&#xff0c;可以让大家快速掌握文件操作&#xff0c;方便大家快速找到不懂的内容 文件操作的作用以及基础 1. 为什么使用文件&#xff1f; 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&…

(arxiv2401) CrossMAE

作者团队来自加州大学伯克利分校&#xff08;UC Berkeley&#xff09;和加州大学旧金山分校&#xff08;UCSF&#xff09;。论文主要探讨了在MAE的解码中&#xff0c;图像patch之间的依赖性&#xff0c;并提出了一种新的预训练框架 CrossMAE。 论文的主要贡献包括&#xff1a; …

代码随想录-算法训练营day02【滑动窗口、螺旋矩阵】

专栏笔记&#xff1a;https://blog.csdn.net/weixin_44949135/category_10335122.html https://docs.qq.com/doc/DUGRwWXNOVEpyaVpG?uc71ed002e4554fee8c262b2a4a4935d8977.有序数组的平方 &#xff0c;209.长度最小的子数组 &#xff0c;59.螺旋矩阵II &#xff0c;总结 建议…

(源码+部署+讲解)基于Spring Boot和Vue的大学生快递代取服务平台的设计与实现

一、引言 本报告旨在详细阐述基于Spring Boot后端框架和Vue前端框架的大学生快递代取服务平台的设计与实现过程。该平台旨在为大学生提供便捷的快递代取服务&#xff0c;解决因时间冲突或距离过远而无法及时取件的问题。通过该平台&#xff0c;用户可以发布代取需求&#xff0c…

[中级]软考_软件设计_计算机组成与体系结构_07_存储系统

存储系统 层次划存储概念图局促性原理分类存储器位置存取方式按内容存储按地址存储 工作方式拓展 往年真题 高速缓存(cache)概念案例解析&#xff1a;求取平均时间 Cache与主存的地址映射映像往年真题 主存编制计算编址大小的求取编址与计算存储单元编址内容总容量求取例题解析…

java爬虫入门程序

<!--爬虫仅支持1.8版本的jdk--> <!-- 爬虫需要的依赖--> <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version> </dependency><!-- 爬虫需…

github生成新的SSH密钥

首先是参考官方文档 生成新的 SSH 密钥并将其添加到 ssh-agent述 当你在创建SSH密钥时遇到提示&#xff1a; Enter file in which to save the key (/c/Users/YOU/.ssh/id_ALGORITHM):这一步是让你选择保存生成的SSH密钥对的文件名和位置。如果你直接按回车键&#xff08;[Pr…