尚硅谷VUE项目-前端项目问题总结02

1 编程式导航,会报错

在这里插入图片描述
在这里插入图片描述

push是VueRouter类的一个原型方法
$router是VueRouter类的实例
类的实例可以直接调用类的原型方法
所以对原型方法push进行修改,修改结果就会作用于组件实例的$router实例。

解决方法:在router路由配置里重写push(用到原型p10)

///解决编程导航多次点击报错的方法
//先把VueRouter原型对象的push,replace保存一份
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace;

//重写push|replace
//第一个参数:告诉原来push方法,你往哪里跳转(传递哪些参数);第二个参数:成功的回调;第三个参数:失败的回调
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, () => { }, () => { })
    }
}

2 组件编写

如果一个组件在很多地方都用到,可以注册一个全局组件。
在任何地方都可用,不需要引入!!!!
下面注册一个三级联动的全局组件

全局组件编写
在这里插入图片描述

注册全局组件
在这里插入图片描述

调用这个全局组件
在这里插入图片描述
调用普通组件
在这里插入图片描述

3 postman,airpost可以测试接口

airpost在线:https://beta.apipost.cn

4 二次封装axios

安装:

cnpm install --save axios

视频axios版本 “axios”: “^0.24.0”
我安装的 “axios”: “^0.26.0”,

二次封装axios
在src下新建api–>request.js

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

//利用axios对象的方法create,去创建一个axios实例
//requests就是axios,只不过稍微配置了一下
const requests=axios.create({
    baseURL:'/api',
    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('faile'))
})

//对外暴露
export default requests

api中index文件

//当前模块:API进行同一管理
import requests from "./request";

//axios发送请求,返回的是Promise对象

//三级联动  /api/product/getBaseCategoryList   get
export const reqCategoryList = () => requests({ url: "/product/getBaseCategoryList", method: "get" });

5 跨域:JSONP,CROS,代理

webpack–》中文文档–》配置–》开发中 Server(devServer)–》devServer.proxy

在vue-config-js中配置

module.exports={
    //关闭eslint
    lintOnSave:false,

    //代理跨域
    devServer:{
        proxy: {
            "/api": {//服务器之间没有跨域,浏览器之间有,如果前台项目发请求,请求路径中含有/api,代理服务器会找真实的服务器要数据
              target: "http://39.98.123.211",//获取数据的后台服务器
            //   pathRewrite: {"^/api" : ""}    //路径重写  因为真实的请求都带/api
            }
          }

    },

}

测试接口是否返回数据:在main.js中,

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

注意:配置文件改动,需要重启服务器

6 进度条nprogress

安装:“nprogress”: “^0.2.0”,

npm install --save nprogress

在拦截器中引用个设置api->request

//引入进度条及样式
import nprogress from 'nprogress';
import 'nprogress/nprogress.css'
//请求拦截器
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'))
})

7 vuex

安装:
视频版本3.6.2

npm install --save vuex
npm install --save vuex@3.6.2

store–>index

//vuex
import Vue from 'vue'
import Vuex from 'vuex'
//使用插件
Vue.use(Vuex)

const state={};
const mutations={};
const actions={};
const getters={};
const modules={};

export default new Vuex.Store({
    state,
    mutations,
    actions,
    getters,
    modules,

})

main.js引入

//vuex  引入仓库
import store from '@/store'

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

vuex基本使用:一个计算器加减的例子,应用action,mutation

在home组件的index.vue中

    <button @click="add">+</button>
    <span>等于{{count}}</span>
    <button @click="del">-</button>

且store的state中定义count=1

const state = {
    count:1
};

home组件内引入

import {mapState} from 'vuex'

  computed:{
    ...mapState(['count'])
  },

  methods:{
    add(){
      //派发action
      this.$store.dispatch('add')
    },
    del(){
      this.$store.dispatch('del')
    },
  },

store中

const state = {
    count:1
};
const mutations = {
    ADD(state){
        state.count++
    },
    DEL(state){
        state.count--
    },
    
};
const actions = {
    add({commit}){
        commit('ADD')
    },
    del({commit}){
        commit('DEL')
    },
};

vuex模块式开发

新建home和search组件的小仓库,自己管理
在store中建home和search文件夹,各自有index.js

//home组件模块的小仓库
const state={};
const mutations={};
const actions={};
const getters={};

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

store ->index.js中引入各个小仓库

//vuex
import Vue from 'vue'
import Vuex from 'vuex'

//使用插件
Vue.use(Vuex)
// const state = {};
// const mutations = {};
// const actions = {};
// const getters = {};

//引入小仓库
import home from './home'
import search from './search'
export default new Vuex.Store({
    // state,
    // mutations,
    // actions,
    // getters,
    // modules,

    //实现Vuex仓库模式开发存储数据
    modules:{
        home,
        search,
    }

})

命名空间(不是必须的)

参考:https://blog.csdn.net/weixin_42566993/article/details/107594847
vuex模块命名空间的使用,主要加入namespaced:true到各个模块中。使用时,通过**…mapGetters(‘模块名’,[‘msg’])**来使用即可。

//article模块
export default {
  namespaced:true,
  state:{
    msg:'我是article中的msg'
  },
  getters:{
    msg:state=>state.msg
  },
  mutations:{},
  actions:{}
};

//category.vue
<script>
import { mapGetters,mapMutations } from 'vuex'
export default {
  computed: {
    ...mapGetters('categoryStore',['msg','num']),
  },
  methods: {
    ...mapMutations('categoryStore',['ADD_FUN'])
  },
}
</script>

版权声明:本文为hnn567原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。