vue项目实战-尚品汇(二)

day2

1:编程式路由跳转到当前路由(参数不变),多次执行会抛出NavigationDuplicated的错误警告?

路由跳转有两种形式:声明式导航,编程式导航

声明式导航没有这类问题的,因为vue-router底层已经处理好了

1.1为什么编程导航进行路由跳转的时候,就有这种警告错误那?

"vue-router":"^3.5.3":最新的vue-router引入promise

1.2通过给push方法传递相应的成功,失败的回调函数,可以捕获到当前的错误,可以解决,

1.3通过底部的代码,可以解决错误

this.$router.push({name:'search',params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}},
//成功的回调
()=>{},
//错误的回调
(error)=>{})

这种写法:治标不治本,将来在别的组件当中push|replace,编程式导航还是有类似的错误

1.4可以通过重写push|replace方法解决

this:当前组件实例(search)

this.$router属性是一个对象:当前的这个属性,属性值是VueRouter类的一个实例,当在入口文件注册路由的时候,给组件实例添加的$router|$route属性

push:VueRouter类的一个实例

 function VueRouter(){}

//原型对象的方法

 VueRouter.prototype.push = function(){

 //函数的上下文为VueRouter类的一个实例

 }

 let $router = new VueRouter()

 $router.push(xxx)
// /router/index.js
// 重写push|和replace方法
// 先把VueRouter原型对象的push方法,先保存一份
let originPush = VueRouter.prototype.push
let originReplace = VueRouter.prototype.replace
// 重写push|replace方法
// 第一个参数:告诉原来push方法,你往哪里跳转(传递哪些参数)
// 第二个参数:成功的回调
// 第三个参数:失败的回调
// call|apply区别:
        // 相同点,都可以调用函数一次,都可以篡改函数的上下文一次
        // 不同点 call与apply传递参数:call传递参数用逗号隔开,apply方法执行,传递数组
VueRouter.prototype.push = function (location, resolve, reject) {
    if (resolve && reject) {
        originPush.call(this, location, resolve, reject)
    } else {
        originPush.call(this, location, () => { }, () => { })
    }
}
VueRouter.prototype.replace= function(location,resolve,reject){
    if (resolve && reject) {
        
        originReplace.call(this, location, resolve, reject)
    } else {
        originReplace.call(this, location, () => { }, () => { })
    }
}

call() 方法是预定义的 JavaScript 方法。

它可以用来调用所有者对象作为参数的方法。

通过 call(),您能够使用属于另一个对象的方法。

本例调用 person 的 fullName 方法,并用于 person1:

var person = {
    fullName: function() {
        return this.firstName + " " + this.lastName;
    }
}
var person1 = {
    firstName:"Bill",
    lastName: "Gates",
}
var person2 = {
    firstName:"Steve",
    lastName: "Jobs",
}
person.fullName.call(person1);  // 将返回 "Bill Gates"

2.Home模块组件拆分

--先把静态页面完成

 --拆分出静态组件

 --获取服务器数据

 --动态的业务完成即可

把静态页面组件建立在Home文件夹下

3.三级联动组件完成

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

 好处:只需要注册一次,就可以在项目任意地方使用(typeNav)为三级联动

4.完成其他的静态组件

 html + CSS +图片资源  --信息 【结构 组件信息】

5.通过postman测试接口

 --经过postman工具测试,接口是没有问题的

 --如果服务器返回的数据code字段200 , 代表服务器返回数据成功

 --整个项目,接口前缀都有/api字样

 

 6.axios二次封装

 XMLhttpRequest、fetch jq、axios

 6.1 为什么需要进行二次封装axios?

 请求拦截器、相应拦截器、请求拦截器,可以再发请求之前可以处理一些业务,相应拦截器,当服务器数据返回以后,可以处理一些事情

 6.2在项目当中经常出现api【axios请求】

 接口当中:路径都带有/api

 baseURL:"/api"

 http://xxx.xxx:8080/api

请求拦截器的配置。在api文件夹下创建request.js

// 对于axios进行二次封装
import axios from 'axios'
import nprogress from 'nprogress'
// 引入进度条的样式
import  'nprogress/nprogress.css'
// start:进度条开始  done:进度条结束


// 1:利用axios对象的方法create,去创建一个axios实例
// 2:request就是axios,只不过稍微配置以下
const requests = axios.create({
    // 配置路径
    // 基础路径,发送请求的时候,路径当中会出现api
    baseURL: "/api",
    // 代表请求超时的时间5s
    timeout: 5000,
})
// 请求拦截器:发送求求之前,请求拦截器可以检测到,可以在请求发出去之前做一些事情
requests.interceptors.request.use((config) => {
    // config:配置对象,对象里面有一个属性很重要,header请求头
    // 进度条开始动
    nprogress.start();
    return config;
})
// 响应拦截器
requests.interceptors.response.use((res) => {
    // 成功的回调函数,服务器响应数据回来以后,响应拦截器可以检测到,可以做一些事情
    // 进度条结束
    nprogress.done();
    return res.data;
}, (error) => {
    // 服务器响应失败的回调函数
    return Promise.reject(new Error('faile'))
})



//  对外暴露
export default requests

 7.接口统一管理业务

 项目很小:完全可以在组件的生命周期函数中发请求

一般将所有接口请求地址都写到api文件夹下

 7.1 跨域问题

 什么是跨域:协议,域名,端口号不同请求,称之为跨域

http://localhost:8080/#/home  --前端项目本地服务器

http://39/98.123.211  --后台服务器

解决跨域的方法

 JSONP  CROS 代理服务器

这里我们使用的是代理服务器的方法,是webpack中的 devServer.proxy

在vue.config.js文件中添加

// 代理跨域
  devServer: {
    proxy: {
      "/api": {
        target: "http://39.98.123.211",
        // pathRewrite: { "^/api": "" }   这里是地址重写
      }
    }
  }

 8.nprogress进度条的使用

 安装 npm install --save nprogress

 进度条在拦截器处使用

 start:进度条开始

 done:进度条结束

在请求拦截器处使用

nprogress.start();

在响应拦截器处使用

nprogress.done()

 进度条的颜色可以修改的,需要修改css样式

 9:vuex状态管理库

 9.1vuex是什么

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

 切记,并不是全部项目都需要vuex 如果项目很小,完全不需要vuex 如果项目很大,组件很多,数据很多,数据维护很费劲,Vuex

state

mutations

acitons

getters

modules

这里由于cli版本的问题不能安装最新的vuex 只能安装3.x版本的

9.2vuex基本使用

这个是Vuex下的index.js

import Vue from 'vue'
import Vuex from 'vuex'
// 需要使用插件一次
Vue.use(Vuex);


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


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

});

9.3vuex实现模块化开发

如果项目过大,组件过多,接口也很多,数据也很多,可以让vuex实现模块化

创建Home仓库下的index.js Search模块下的仓库和home模块的仓库初始哈代码相同

// home模块的小仓库

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';
// state:仓库存储数据的地方
// const state = {}
// // mutations:修改state的唯一手段
// const mutations = {}
// // action:处理action,可以书写自己的业务逻辑,也可以处理异步
// const actions = {}
// // getters:理解为计算属性,用于简化仓库数据,让组件获取仓库的数据更加方便
// const getters = {}


// // 对外暴露Store类的一个实例
export default new Vuex.Store({
    // state,
    // mutations,
    // actions,
    // getters
    // 实现仓库模块化开发存储数据
    modules: {
        home, search
    }

});

通过api下index.js写好的调用接口的函数获取数据,并通过store仓库储存起来

// home模块的小仓库
import { reqCategoryList } from "@/api"
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)
            
        }
    }
}
const getters = {

}
export default {
    state, mutations, actions, getters
}

再通过typeNav下的mounted钩子函数,将数据导入

通过this.$store.dispatch方法调用store仓库中的action中的categoryList

 因为这里如果只用categorylist函数的化获取的是一个promise对象,获取不了数据,所以通过

async  await 获取数据

再通过commit提交到mutations里面再修改state里面的数据

 如果这里整不懂vuex的可以看我之前的文章中vuex基础的学习

这里唯一难理解的就是commit的解析,这里用了es6的解析

原本应该是

add(context){
context.commit('',data)
}

 

10:完成TypeNav三级联动展示数据业务

[

      {

            id:1

            name:'电子书'

            child:[

                  {id:2,name:"喜羊羊",child:[]}

            ]

      },

      {},

      {}

]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值