电商平台项目 Vue day2

1、注意点:

    编程式导航路由跳转到当前路由(参数不变), 多次执行会抛出NavigationDuplicated的警告错误? [ 即电商平台多次点击搜索,但搜索内容不变时,控制台会报错 ]

 这种异常,对于程序没有任何影响的

为什么会出现这种现象:

由于vue-router最新版本3.5.2,引入了promise,当传递参数多次且重复,会抛出异常,因此出现上面现象,

第一种解决方案:是给push函数,传入相应的成功的回调与失败的回调

goSearch() {
      // 常用:对象传参
      this.$router.push(
        {
          name: "xiangqing",
          params: { keyword: this.keyword },
          query: { id: this.keyword.toUpperCase() },
        },
        //添加下面的成功失败回调(治标不治本方法)
        () => {},
        () => {}
      );
    },

第二种解决方案:直接在router组件里修改push参数,在这个根文件里添加成功失败回调

// 解决header里重复点击push上传时控制面板会飘红的问题,治本
// 直接把header里的修改放到push里,当然,先备份一份先
let originPush = VueRouter.prototype.push

// 重写push
// location告诉原来的push往哪跳, resolve成功时, reject失败时
VueRouter.prototype.push = function(location, resolve, reject) {
    // 如果有成功和失败的返回函数,则使用正常push备份的originPush,
    // 如果没有,则在push备份的originPush上面添加resolve和reject
    if (resolve && reject) {
        originPush.call(this, location, resolve, reject)
    } else {
        originPush.call(this, location, () => {}, () => {})
    }
}

言归正传,day1的时候已经把header和footer两个非路由组件搞定,并实现了组件间的跳转,接下来进行home路由组件的制作。

1、将Home组件的静态组件拆分(拆分成7个组件)

总体步骤:

1.1静态页面(样式)

1.2拆分静态组件

1.3发请求获取服务器数据进行展示

1.4开发动态业务

拆分组件:结构+样式+图片资源

 

(1)、1号组件是三级联动,在多个模块(Home、Search、Detail)中都需要使用,所以把它设成全局组件

  ---全局组件好处:只需要在 main.js注册一次,可以在项目的任意地方使用

1.1、在Home组件里新建TypeNav文件夹存放‘’商品分类导航的对应文件(html、css/less、img)

1.2、注册全局组件

// main.js中,三级联动组件--因为很多组件都用,所以设置成全局组件
import TypeNav from '@/pages/Home/TypeNav'

// 使用三级联动组件 TypeNav. 2个参数(全局组件的名字,哪一个组件)
Vue.component(TypeNav.name, TypeNav)

1.3、注册好了在home组件中使用

<template>
  <div>
    <!-- 使用三级联动全局组件 -->
    <TypeNav></TypeNav>
  </div>
</template>

(2)、相同步骤在Home里拆分其它组件,注意(html、css/less、img)的区分

  ---注意:有的图片地址不对,用Ctrl+h全局替换

overflow:hidden作用是当元素内的内容溢出的时候使它隐藏溢出的部分,

可用于:超出部分隐藏、清除浮动、解决外边距塌陷(父级元素内部有子元素,如果给子元素添加margin-top样式,那么父级元素也会跟着下来,造成外边距塌陷)

(3)、引入、注册、使用(三件套)其余组件【TypeNav在全局引入了,这些则是局部引入】

商品的内容需要从后台获取,可以用PostMan软件测试一下接口能不能连接后台服务器

  ---如果服务器返回200,则代表成功,反之失败

二、axios二次封装(静态页面已经搞好,接下来利用axios向服务器发请求获取数据) 

使用前先在控制台安装axios:

cnpm install --save axios

2.1:在src下创建api文件夹存放axios,src->api->request.js

request.js是创造axios的实例和axios的拦截器以及发送真正的网络请求的地方

axios具体内容可以查看: axios中文文档

import axios from "axios";
//1、对axios二次封装
const requests = axios.create({
    //基础路径,requests发出的请求在端口号后面会跟改baseURl
    //baseURL设置为api,所以所有的请求端口后都会携带/api
    baseURL:'/api',
    //发一个请求如果5s内没响应,那么就请求失败
    timeout: 5000,
})
//2、配置请求拦截器, request就是axios
requests.interceptors.request.use(config => {
    //config内主要是对请求头Header配置
    //比如添加token
    
    return config;
})
//3、配置响应拦截器
requests.interceptors.response.use((res) => {
    //成功的回调函数
    return  res.data;
},(error) => {
    //失败的回调函数
    console.log("响应失败"+error)
    return Promise.reject(new Error('fail'))
})
//4、对外暴露
export default requests;

2.2:接口统一管理

当项目很小时,接口可以放在组件的生命周期中发送请求

当项目很大时,有很多接口,可以把接口放到一起统一管理:

 在api文件夹内创建index.js组件,用于存放所有接口,统一管理

//当前模块,API进行统一管理,即对请求接口统一管理
import requests from "@/api/request";

//首页三级分类接口
export const reqCateGoryList = () => {
    return  requests({
        //因为baseURL里自动携带了/api,所以这里不用加上/api。如果那边没有这边就要加上
        //method指什么请求
        url: '/product/getBaseCategoryList',
        method: 'GET'
    })
}

在main.js里测试一下是否能够成功请求后台数据:

import {reqCateGoryList} from './api'
//发起请求
reqCateGoryList();

404请求失败,跨域了。 

三、跨域问题

两个服务器相互请求,协议、域名、端口号必须一致,不然就是跨域,无法找到对方

 解决方法:cors、jsonp、代理(常用)

 这里使用代理服务器的方法:(在vue.config.js配置,配置完要重启代码)

module.exports = {
    //关闭eslint
    lintOnSave: false,
    devServer: { 
        // development server port 8000
        //port: 8001,
        //代理服务器解决跨域
        proxy: {
            //但在请求路径中发现/api时跳转到后面的代理服务器
            '/api': {
                //提供数据的服务器地址
                target: 'http://gmall-h5-api.atguigu.cn',

            }
        },
    }
}

代理相关看:  webpack官网相关知识解读
网站中的webpack.config.js就是vue.config.js文件。

 四、页面加载进度条

 可以使用nprogress插件来完成,安装完后可以去package.json里确认

cnpm install -save nprogress

安装好后再api的request的响应拦截器使用。先引入,

//---------------无关的代码这里会先去除--------------

//引入进度条
import nprogress from 'nprogress';
//引入进度条样式,想要修改进度条默认样式可以去下面的css里改
import "nprogress/nprogress.css";
//这里使用进度条插件的2个方法,1、start(进度条开始)  2、done(进度条结束)

//2、配置请求拦截器:在发请求前执行
requests.interceptors.request.use(config => {
    //在发请求前开启进度条,的start方法
    nprogress.start();

    return config;
})

//3、配置相应拦截器:在发请求侯执行
requests.interceptors.response.use((res) => {
    //成功的回调函数

    //响应成功,关闭进度条,使用done方法
    nprogress.done()

    return  res.data;
},(error) => {
    //失败的回调函数
    console.log("响应失败"+error)
    return Promise.reject(new Error('fail'))
})

//4、对外暴露
export default requests;

简单来说,先导入进度条插件,在页面加载前使用start方法,结束后使用done方法

五、使用Vuex集中式管理数据 

cnpm install --save vuex@3.6.2                    Vue2要用3版本的,不指定默认安4版本

创建文件夹store -> index.js存放Vuex    【2种形式】(这里不用这种)

//引入
import Vue from 'vue'
import Vuex from 'vuex'
//使用
Vue.use(Vuex)

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

如果模块很多就要用到模块化开发,把每个模块的数据单独放一个小仓库,再由store引入

结构
小仓库
小仓库
store大仓库

 设置好Vuex之后需要引入,到mian.js引入和使用,和router步骤一样

//引入Vuex
import store from './store';

new Vue({
    render: h => h(App),
    router,
    //使用Vuex
    store,
}).$mount('#app')

六、动态展示三级联动组件

1、像这种多个地方都需要用到的组件,把它放到components里面(就是那个存放静态组件的那里)

2、在三级联动组件TypeNav里:

export default {
  name:'TypeNav',
  // 组件挂载,向服务器发送请求获取数据
  mounted(){
    //通知Vuex发请求,获取数据,并存储于仓库当中,
    //这里actions取名叫做categorylist,然后去Vuex里配置actions
    this.$store.dispatch('categorylist')
  }

 3、接收TypeNav的请求,并引入之前封装的api

在store文件夹(Vuex)的小仓库home里引入api接口reqCateGoryList,然后在actions里书写业务

//引入api接口
import { reqCateGoryList } from '@/api/index'

//处理actions的地方,可以书写业务逻辑、处理异步
const actions = {
    categorylist() {
        let result = reqCateGoryList()
        console.log(result);
    }
};

 

 咱们这里使用异步来进行,也就是async await

//处理actions的地方,可以书写业务逻辑、处理异步
const actions = {
    async categorylist() {
        let result = await reqCateGoryList()
        console.log(result);
    }
};

通过Vuex原理处理数据

 

//引入api接口
import { reqCateGoryList } from '@/api'
//处理actions的地方,可以书写业务逻辑、处理异步
const actions = {
    // {commit} 是结构赋值
    async categorylist({ commit }) {
        let result = await reqCateGoryList()
        if (result.code == 200) {
            commit('CATEGORYLIST', result.data);
        }
    }
};
//修改数据的地方
const mutations = {
    CATEGORYLIST(state, categorylist) {
        state.categorylist = categorylist
    }
};
//存储数据的地方
const state = {
    categorylist: []
};

4、到TypeNav接收数据

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

5、数据有了,把html中的静态内容删掉,用v-for生成

 

至此,动态三级分类搞定 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值