1.警告错误
编程式路由跳转到当前路由(参数不变),多次执行会抛出NavigationDuplicated的警告错误?
----路由跳转方式:声明式导航,编程式导航
注意:编程式导航(push|replace)才会有这种情况的异常,声明式导航是没有这种问题,因为声明式导航内部已经解决这种问题。
这种异常,对于程序没有任何影响的。
1.1为什么会出现这种现象:
由于vue-router最新版本3.5.3,引入了promise,当传递参数多次且重复,会抛出异常,因此出现上面现象,
1.2第一种解决方案:
是给push函数,传入相应的成功的回调与失败的回调,可以捕获到当前的错误,可以解决
1.3通过底层的代码可以实现解决问题
this.$router.push({name:“search”,params:{keyword:this.keyword},query:{k:this.keyword.toUpperCase()}},()={},()={}})}));
function push(){
第一种解决方案可以暂时解决当前问题,但是以后再用push|replace还是会出现类似现象,编程式导航还有类似错误。
1.4重写push | replace方法
第一个参数,告诉原来的push方法,你往哪里跳转(传递哪些参数)
第二个参数:成功回调
第三个参数:失败的回调
VueRouter.prototype.push=function(location,resolve,reject){
///
}
2.Home模块组件拆分
–先把静态页面完成
–拆分静态组件
–获取服务器的数据进行展示
–动态业务
3.三级联动组件完成
—由于三级联动,在Home、Search、Detail,把三级联动注册为一个全局组件
好处:只需要注册一次,就可以在项目任意地方使用
4.完成其他静态组件
html+css+图片资源
5.postman调试接口
http://39.98.123.211/api/product/getBaseCategoryList
get请求
6.axios的二次封装
XMLHttpRequest、fetch、JQ、axios
6.1为什么需要二次封装axios
请求拦截器、响应拦截器
请求拦截器:可以在发请求之前处理一些业务
响应拦截器:当服务器返回数据后,可以处理一些事情
安装axios npm install --save axios
6.2 在项目中会出现api文件夹【axios】
接口当中,路径带有api http://xxx:8080/api
6.3axios可以参考git |npm 关于axios的文档
新建api文件夹,—>request.js
// 对于axios进行二次封装
import axios from ‘axios’
// 1.利用axios对象的方法create去创建一个axios实例
// 2.requset就是iaxios,只不过稍微配置一下
const requests = axios.create({
// 配置对象
// 基础路径,发请求的时候会自动添加api
baseURL:“/api”,
// 代表请求超时的时间
timeout:5000,
})
// 请求拦截器:
// 在发请求之前,请求拦截器可以检测,在请求发送之前做一些事情
requests.interceptors.request.use((config)=>{
// config配置对象,对象里面有个属性很重要,headers请求头
return config;
})
// 响应拦截器
requests.interceptors.response.use((res)=>{
// 成功的回调函数
// 服务器相应数据返回之后,响应拦截器可以检测到,做一些事情
return res.data;
}),(error)=>{
// 响应失败的回调函数
return Promise.reject(new Error(“faile”));
}
// 对外暴露
export default requests;
7.接口统一管理
项目很小:完全可以再组件的生命周期函数中发送请求。
项目大:axios.get(‘xxxx’)
7.1跨域问题
什么是跨域:协议、端口、域名、不同请求为跨域
http://localhost:8080/#/home -----前端项目的本地服务器
http://39.98.123.211 ----后台服务器
JSONP,CROS,代理
webpack网站----》》devServer—》》webpack.config.js
vue.config.js中配置
module.exports = {
//…
devServer: {
proxy: {
‘/api’: ‘http://localhost:3000’,
},
},
};
不想传递/api,可以重写路由
module.exports = {
//…
devServer: {
proxy: {
‘/api’: {
target: ‘http://localhost:3000’,
pathRewrite: { ‘^/api’: ‘’ },
},
},
},
};
const { defineConfig } = require(‘@vue/cli-service’)
module.exports = defineConfig({
transpileDependencies: true,
// 关闭eslint
lintOnSave:false,
// 代理跨域
devServer: {
proxy: {
‘/api’: {
target: ‘http://39.98.123.211’,
// pathRewrite: { ‘^/api’: ‘’ },
},
},
}
})
8.nprogress进度条的使用
安装:npm install --save nprogress
在请求拦截器和响应拦截器中使用。
request.js中配置
// 引入进度条
import nprogress from ‘nprogress’;
// 引入进度条样式
import ‘nprogress/nprogress.css’
console.log(nprogress);
// start:进度条开始
// done:进度条结束
requests.interceptors.request.use((config)=>{
// config配置对象,对象里面有个属性很重要,headers请求头
// 进度条开始动
nprogress.start();
return config;
})
requests.interceptors.response.use((res)=>{
// 成功的回调函数
// 服务器相应数据返回之后,响应拦截器可以检测到,做一些事情
// 进度条结束
nprogress.done();
return res.data;
}),(error)=>{
// 响应失败的回调函数
return Promise.reject(new Error(“faile”));
}
进度条可以修改样式
9.vuex状态管理库
9.1vuex是什么?
vuex是官方提供的一个插件,状态管理库,集中式管理项目中组件公用的数据。
切记,不是全部项目都需要vuex,项目小,不需要
项目很大,组件很多,数据很多,数据维护很费劲,用vuex
安装vuex:npm install --save vuex
最新版本为4,安装不上的用三版本,npm install --save vuex@3
9.2vuex基本使用
新建store文件夹,新建index.js
import Vue from “vue”;
import Vuex from ‘vuex’;
// 需要使用插件一次
Vue.use(Vuex);
// store:仓库存储数据的地方
const state = {};
// mutations:修改state的唯一手段
const mutations = {};
// actions:处理action,书写自己的业务逻辑,处理异步
const actions = {};
// getters:理解为计算属性,用于简化仓库数据,让组件获取仓库的数据更为方便
const getters = {};
// 对外暴露
export default new Vuex.Store({
state:{},
mutations:{},
actions:{},
getters:{}
})
入口文件注册仓库
// 引入仓库
import store from ‘./store’;
new Vue({
render: h => h(App),
// 注册路口,kv一致,省略v
// 注册路由信息,书写router是,组件身上拥有
r
o
u
t
e
,
route,
route,router属性
router,
// 注册仓库,组件实例的身上会多了一个属性KaTeX parse error: Expected 'EOF', got '}' at position 17: …tore属性 store }̲).mount(‘#app’)
测试:
// store:仓库存储数据的地方
// const state = {
// count:1
// };
// mutations:修改state的唯一手段
// const mutations = {
// ADD(state){
// state.count++;
// }
// };
// actions:处理action,书写自己的业务逻辑,处理异步
// const actions = {
// // 这里可以书写业务逻辑,但是不能修改state
// add({commit}){
// commit(“ADD”);
// }
// };
// getters:理解为计算属性,用于简化仓库数据,让组件获取仓库的数据更为方便
// const getters = {};
home—》》index.vue
<button @click=“add”>点击我加1
仓库数据{{count}}
<button @click=“jian”>点击我减1
import {mapState} from ‘vuex’;
export default {
name: “”,
components: {
ListContainer,
Recommend,
Rank,
Like,
Floor,
Brand,
},
computed:{
…mapState([“count”])
},
methods:{
add(){
// alert(123);
//派发action
this.$store.dispatch(“add”);
}
}
};
store----》》index.vue
import Vue from “vue”;
import Vuex from ‘vuex’;
// 需要使用插件一次
Vue.use(Vuex);
// store:仓库存储数据的地方
const state = {
count:1
};
// mutations:修改state的唯一手段
const mutations = {
ADD(state){
state.count++;
}
};
// actions:处理action,书写自己的业务逻辑,处理异步
const actions = {
// 这里可以书写业务逻辑,但是不能修改state
add({commit}){
commit(“ADD”);
}
};
// getters:理解为计算属性,用于简化仓库数据,让组件获取仓库的数据更为方便
const getters = {};
// 对外暴露
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
9.3vuex实现模块化开发
项目大:拆分成小仓库
分为小模块:
store—》》home—》》index.js
// search模块的小仓库
const state = {b:2}
const mutations = {}
const actions = {}
const getters = {}
export default{
state,
mutations,
actions,
getters
}
// home模块的小仓库
const state = {a:1}
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”;
// 对外暴露
export default new Vuex.Store({
// 实现vuex模块化仓库开发并存储数据
modules:{
home,
search
}
})
10.TypeNav三级联动展示数据业务
typeNav由子组件变成全局组件,放在components
main.js改路径
import TypeNav from ‘@/components/TypeNav’
store–>>home—》》index.js
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();
// console.log(result);
if (result.code == 200) {
commit(“CATEGORYLIST”, result.data);
}
}
}
const getters = {}
export default {
state,
mutations,
actions,
getters
}
typenav—>>index.js