【vue2 项目】遇到的一些琐碎的知识点【连载中】

01 vue-router 路由

1.1 重定向

  • 配置路由时,处理 /,进行重定向

router/index.js 文件

export default new VueRouter({
  // 配置路由
  routes: [
    // 重定向,项目跑起来时,访问/,立马跳转到home页面
    {
      path: '/',
      redirect: '/home'
    }
  ]
})

1.2 $router 和 $route

  • $router:一般进行编程式路由导航【push、replace】
    • 是 VueRouter 的一个对象,通过 Vue.use(VueRouter) 和 VueRouter 构造函数得到一个 router 的实例对象,这个对象中是一个全局的对象,包含了所有的路由包含了许多关键的对象和属性
  • $route:一般获取路由信息【路径、query、params 等等】
    • 是一个跳转的路由对象,每一个路由都会有一个 route 对象,是一个局部的对象,可以获取对应的 name、path、params、query 等

1.3 路由的跳转

  • 声明式路由导航 router-link,务必有 to 属性,可以实现路由的跳转
  • 编程式路由导航,利用组件实例的 $router.push$router.replace
  • 声明式路由导航能做的编程式路由导航都能做,编程式路由导航除了可以进行路由跳转,还可以做一些其他的业务逻辑

1.4 路由元信息 meta

配置路由时添加元信息

  • meta: { show: true } 配合 v-show/v-if 控制组件是否显示
  • 【其他用途】待添加

router/index.js 文件

export default new VueRouter({
  // 配置路由
  routes: [
    {
      path: '/home',
      component: Home,
      // 路由元信息
      meta: {
        show: true
      }
    }
  ]
})

1.5 路由参数

  • params 参数:属于路径的一部分,在配置路由时需要占位
  • query 参数:不属于路径的一部分,类似 ajax 中的 queryString
// 编程式路由导航
// 第一种:字符串形式
this.$router.push("/search/" + this.keyword + "?k=" +this.keyword.toUpperCase())
// 第二种:模板字符串
this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`)
// 第三种:对象
this.$router.push({
  name: "search",
  params:{
    keyword:this.keyword
  },
  query:{
    k:this.keyword.toUpperCase()
  }
})

1.6 路由跳转传参时 params 参数只能与 name配合使用

  • 采用对象式写法时 params 参数必须与 name 配合,不能与 path 配合!!!

1.7 如何指定 params 参数可传可不传

  • 比如:配置路由时已经占位了,但是路由跳转时不传递,此时路径会出问题
    • e.g:http://localhost:8080/?k=aaa 正确路径为 http://localhost:8080/search?k=aaa
    • 解决办法:占位时后面加一个 ?

router/index.js 文件

export default new VueRouter({
  // 配置路由
  routes: [
    {
      // 指定 params 参数可传可不传
      path: '/search/:keyword?',
      component: Search,
      name: 'search',
      meta: {
        show: true
      }
    }
  ]
})

1.8 params 参数可传可不传,如果是空串,如何解决

  • e.g:http://localhost:8080/?k=aaa 正确路径为 http://localhost:8080/search?k=aaa
  • 解决办法:使用 undefined 解决
this.$router.push({
	name: "search",
  params:{
    keyword: '' || undefined
  },
  query:{
    k:this.keyword.toUpperCase()
  }
})

1.9 路由组件传递 props 数据

router/index.js 文件

export default new VueRouter({
  // 配置路由
  routes: [
    {
      path: '/search/:keyword?',
      component: Search,
      name: 'search',
      meta: {
        show: true
      },
      // 布尔值写法:只能传递 params 参数
      props: true,
      // 对象写法:额外给路由组件传递一些 props
      props: { a:1,b:2 },
      // 函数写法:可以把params参数,query参数,通过props传递给路由组件
      props:($route) => ({ keyword: $route.params.keyword,k: $route.query.k })
    }
  ]
})

1.10 重写 push | replace 方法

  • 解决搜索按钮重复点击跳转路由时,报错:Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/search/sss?k=SSS".,通过给 push、replace 方法传递相应的成功、失败的回调函数可以捕获到当前错误,可以解决
  • push() 和 replace() 返回的是一个 Promise 对象
// 先把VueRouter原型对象的push保存一份
let originPush = VueRouter.prototype.push
// 重写 push
/**
 * 
 * @param {*} location 告诉原来的push方法往哪里传参
 * @param {*} resolve 成功的回调
 * @param {*} reject 失败的回调
 */
VueRouter.prototype.push = function(location, resolve, reject){
  if(resolve && reject){
    originPush.call(this, location, resolve, reject)
  }else{
    originPush.call(this, location, () => {}, () => {})
  }
}

// 先把VueRouter原型对象的replace保存一份
let originReplace = VueRouter.prototype.replace
// 重写 replace
/**
 * 
 * @param {*} location 告诉原来的replace方法往哪里传参
 * @param {*} resolve 成功的回调
 * @param {*} reject 失败的回调
 */
VueRouter.prototype.replace = function(location, resolve, reject){
  if(resolve && reject){
    originReplace.call(this, location, resolve, reject)
  }else{
    originReplace.call(this, location, () => {}, () => {})
  }
}

02 设置路径别名 @ 代表 src

jsconfig.json 文件夹

{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "baseUrl": "./",
    "moduleResolution": "node",
    "paths": {
      "@/*": [
        "src/*"
      ],
      "exclude": ["node_modules", "dist"]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  }
}

03 注册全局组件

  • main.js 文件里注册,使用时不需要再 import 引入

main.js 文件

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

04 请求相关

4.1 axios 二次封装

  • 请求拦截器和响应拦截器:在发请求之前和服务器数据返回以后处理一些业务

api/request.js 文件

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

// 1.利用axios对象的方法create创建一个axios实例
// 2.requests就是axios,进行配置
const requests = axios.create({
  // 配置对象
  // 基础路径
  baseURL: '/api',
  // 超时时间 5s
  timeout: 5000,
})
// 请求拦截器
requests.interceptors.request.use((config) => {
  // config:配置对象,对象里面有一个属性很重要,header请求头
  return config
})
requests.interceptors.response.use((res) => {
  // 成功的回调
  return res.data
}, (error) => {
  console.log(error.message)
  return new Promise(() => {})
})

// 对外暴露
export default requests

4.2 接口统一管理

  • 项目很小:在组件的生命周期函数中发请求
  • 项目大:axios.get('xxx')

api/index.js 文件

// 所有api进行统一管理
import requests from './request';

// 三级联动接口
// /api/product/getBaseCategoryList  GET  无参数
export const reqCategoryList = () => {
  // 发请求:axios发请求返回Promise对象
  return requests({
    url: '/product/getBaseCategoryList',
    method: 'GET'
  })
}

05 nprogress 插件

  • 控制进度条
  • nProgress.start():进度条开始
  • nProgress.done():进度条结束
  • 进入 nprogress/nprogress.css#nprogress .bar{ background: #ff0 } 里可修改进度条颜色

npm i --save nprogress

api/request.js 文件

// 对axios进行二次封装
import axios from "axios"
// 引入进度条插件
import nProgress from "nprogress"
// star:进度条开始,done:进度条结束
// 引入进度条样式
import 'nprogress/nprogress.css'

// 1.利用axios对象的方法create创建一个axios实例
// 2.requests就是axios,进行配置
const requests = axios.create({
  // 配置对象
  // 基础路径
  baseURL: '/api',
  // 超时时间 5s
  timeout: 5000,
})
// 请求拦截器
requests.interceptors.request.use((config) => {
  // 进度条开始
  nProgress.start()
  // config:配置对象,对象里面有一个属性很重要,header请求头
  return config
})
requests.interceptors.response.use((res) => {
  // 进度条结束
  nProgress.done()
  // 成功的回调
  return res.data
}, (error) => {
  console.log(error.message)
  return new Promise(() => {})
})

// 对外暴露
export default requests

06 vuex

6.1 模块开发

src/store/home/index

// home模块小仓库
// 仓库存储数据的地方
const state = {

}
// 修改state的唯一手段
const mutations = {

}
// 书写业务逻辑,也可以处理异步,但不能修改state
const action = {

}
// 类似计算属性,用于简化仓库数据,让组件获取仓库的数据更方便
const getters = {

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

src/store/search/index

// search模块小仓库
// 仓库存储数据的地方
const state = {

}
// 修改state的唯一手段
const mutations = {

}
// 书写业务逻辑,也可以处理异步,但不能修改state
const action = {

}
// 类似计算属性,用于简化仓库数据,让组件获取仓库的数据更方便
const getters = {

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

src/store/index

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

// 引入小仓库
import home from './home'
import search from './search'

export default new Vuex.Store({
  modules: {
    home,
    search
  }
})

6.2 未命名模块空间

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

dex**

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

// 引入小仓库
import home from './home'
import search from './search'

export default new Vuex.Store({
  modules: {
    home,
    search
  }
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值