前端学习篇 -- Vue 全家桶

1、Vue-Cli

1.1 常用命令

1.1.1 安装
  1. 安装 vue-cli3 以上版本

    npm i @vue/cli -g

  2. 拉取 vue-cli2 模板

    npm i @vue/cli-init

上面安装好之后,就既可以使用 vue-cli2 ,也可以使用 vue-cli3

1.1.2 创建项目
  1. vue-cli3 以上版本

    vue create my-project --> my-project 为项目名

    Please pick a preset: //配置选择
      > default  //默认
      > Manually select features //手动选择 *
        #空格选择配置项
    Where do you prefer placing...? //配置项保存选择
      > In dedicated config files //保存为独立文件 *
      > In package.json //保存到package.json
    Save this as a preset for futrue projects? (y/N) //是否保存配置项,下次创建项目时,第一项就有三个选项
    
    • 配置项选择
    Babel : 将ES6编译成ES5
    TypeScript: javascript类型的超集
    Progressive Web App (PWA) Support: 支持渐进式的网页应用程序
    Router:vue-router
    Vuex: 状态管理
    CSS Pre-processors: CSS预处理
    Linter / Formatter: 开发规范
    Unit Testing: 单元测试
    E2E Testing: 端到端测试
    
  2. vue-cli2

    vue init webpack my-project --> my-project 为项目名

    Project name my-project --> `项目名,回车
    Project description A Vue.js project --> `描述信息,回车
    Author lxc <[email protected]> --> `作者,回车
    Vue build <Use arrow keys>
      > `Runtime + Compiler --> 代码中可以有 template,回车
      > `Runtime-Only --> 项目文件比上面的轻,一般项目开发使用这个
    Install vue-router? (Y/n) --> `是否安装路由
    Use ESLint to lint your code? (Y/n) --> `是否启用代码规范
      > `Standard //标准规范
      > `Airbnb //爱彼迎规范
      > `none //自定义规范
    to invert selection >
    >(*) Lint on save // 保存就检测 (我一般选择它)
     ( ) Lint and fix on commit // fix和commit检查
    Set up unit tests (Y/n) --> `是否单元测试,n
    Setup e2e tests with Nightwatch? (Y/n) --> `是否端到端测试,n
    >>>>> 安装完毕
    

1.2 eslint 关闭

有时候,配置了 eslint 代码规范,反而给我们写代码造成了困扰

config>index.js>useEslint:false

1.3 vue-cli 3 与 2 区别

  1. 3 是基于 webpack 4 打造,2 是基于webpack 3
  2. 3 的设计原则是 “0配置”,移除根目录下的 build 和 config 等目录
  3. 3 提供了 vue ui 命令,提供了可视化配置
  4. 3 移除了 static 文件夹,新增了 public 文件夹,并将 index.html 移动到里面

1.4 修改配置

在 vue-cli 3中,webpack 相关配置都隐藏到了 node_modules 下 @vue 目录中,可以通过以下几种方案修改配置

  1. 命令 vue ui,打开图形化界面,找到项目目录修改
  2. 创建 vue.config.js文件,修改独有配置

2、Vue-Router

路由就是通过互联的网络把信息从源地址传输到目的地地址的活动

核心就是:改变 url,但是页面不进行整体刷新

2.1 方案

  1. 改变 url 的 hash

    • url 的 hash 也就是锚点(#),本质上是改变window.location的href属性

      location.hash = '/foo'
      // url/#/foo
      
  2. HTML5的history模式:pushState

    history.pushState({
          
          },'','foo')
    // url/foo
    
    // 这种可以保留历史记录,调用 history.back() 方法可以后退
    
    history.replaceState({
          
          },'','foo')
    // 这种是替换当前页面,不能前进后退
    

2.2 安装和使用

  1. 安装

    npm i vue-router
    
  2. 在模块化工程中使用它

    因为是一个插件,所以可以通过Vue.use()来安装路由功能

    第一步:导入路由对象,并且调用 Vue.use(VueRouter)

    第二步:创建路由实例,并且传入路由映射配置

    第三步:在Vue实例中挂载创建的路由实例

    router>index.js
    //1.导入路由对象
    import Router from 'vue-router'
    import Vue from 'vue'
    
    //2.通过 Vue.use(插件),安装插件
    Vue.use(Router)
    
    //3.创建 Router 对象
    const routes = [
    
    ]
    
    const router = new Router({
          
          
      //配置路由和组件
      routes,
      //将默认hash模式调成history模式
      mode: 'history'
    })
    
    index.js
    const router = new Router({
          
          
      //配置路由和组件
     routes,
      //将默认hash模式调成history模式
      mode: 'history',
      //将 router-link 的类名统一修改
      linkActiveClass: 'active'
    })
    
    //4.将 router 对象传入到 vue 实例
    export default router
    
    
    main.js
    import router from './router'
    
    new Vue({
      el: '#app',
      router,
      render: h => h(App)
    })
    
    
    

2.3 配置简单路由

  1. vue-router 里已经配置好的组件,最终被渲染成 a标签

  2. 占位,组件渲染位置

index.js
import Home from '../components/home'
import About from '../components/about'
//注册路由
const routes = [
  {
    path: '',
    //重定向,第一次显示首页
    redirect: '/home'
  },
  {
    path: '/home',
    component: Home
  },
  {
    path: '/about',
    component: About
  }
]

const router = new Router({
  routes,
  mode: 'history'
})

App.vue
//使用
<div id="app">
  <router-link to="/home">首页</router-link>
  <router-link to="/about">关于</router-link>
  <router-view/>
</div>

通过代码的方式修改路由 vue-router

<button @click="btnClick"></button>

btnClick() {
  this.$router.push('/home')
  //this.$router.replace('/home')
}

2.4 router-link 属性

  1. to 属性: 对应注册的 path 路径

  2. tag 属性: 将 router-link 渲染成对应的标签

    <router-link tag ="button"></router-link>
    //渲染成 button 标签
    
    
  3. replace 属性:换成 history. replaceState 替换当前页面,没有前进后退

  4. active-class 属性:选中的标签默认有两个 class 类名

    router-link-exact-active 和 router-link-active

    • 如果要改,直接赋值 active-class="active",项目中不建议改

    • 统一修改

2.5 动态路由

根据不同的用户信息显示不同的页面,传递参数主要有两种类型:

2.5.1 params的类型
  1. 配置路由格式:/router/:id
  2. 传递的方式:在 path后面跟上对应的值
  3. 传递后形成的路径:/router/123,/router/abc

第一步:注册组件

<router-link :to="'/user/'+userId">用户</router-link>
data() {
return {
 userId: 'lisi'
  }
}

第二步:配置路由

index.js
{
     
     
path: '/user/:userId',
component: User
}

第三步:渲染用户信息

<div class="user">我是用户{
    
    {userId}}</div>
computed: {
userId() {
 return this.$route.params.userId
  }
}

我是用户lisi

2.5.2 query的类型
  1. 配置路由格式:/router,也就是普通配置
  2. 传递的方式:对象中使用querykey作为传递方式
  3. 传递后形成的路径:/router?id=123,/router?id=abc

第一步:注册组件

<router-link :to="{path:'/profile',query:{name:'zhangsan'}}">档案</router-link>

第二步:配置路由

{
     
     
path: '/profile',
component: Profile
}

第三步:渲染用户信息

<div>
  <h2>{
    
    {$route.query.name}}</h2>
</div>

zhangsan

2.5.3 其他标签
<button @click="userClick">用户</button>
<button @click="profileClick">档案</button>

userClick() {
  this.$router.push('/user' + this.userId)
},
profileClick() {
  this.$router.push({
    path: '/profile',
    query: {
      name: 'zhangsan'
    }
  })
}

2.6 路由的懒加载(分离打包)

  1. 当打包构建应用时,JavaScript 包会变得非常大,影响页面加载
  2. 不同的组件分割成不同的代码块,当路由被访问时再加载对应的组件

方式

一:结合Vue的异步组件和Webpack的代码分析

const Home = resolve => {
     
     
 require.ensure(['../components/home.vue'],() => {
     
     
   resolve(require('../components/home.vue'))
 })
}

二:AMD写法

const Home = resolve => require(['../components/home.vue'],resolve)

三:ES6写法

const Home = () => import('../components/home.vue') *
const routes = [
 {
     
     
    path: '/home',
    component: Home
 }
]

const routes = [
 {
     
     
    path: '/home',
    component: () => import('../components/home')
 }
]

2.7 路由的嵌套

希望通过 /home/news访问一些内容

index.js
const HomeNews = () => import('../components/homeNews')
const HomeMessage = () => import('../components/homeMessage')
{
  path: '/home',
  component: Home,
  children: [
    {
      path: '',
      redirect: 'news'
    },
    {
      path: 'news',
      component: HomeNews
    },
    {
      path: 'message',
      component: HomeMessage
    }
  ]
}

home.vue
<div class="home">我是首页,哈哈</div>
    <router-link to="/home/news" tag="button">新闻</router-link>
    <router-link to="/home/message" tag="button">消息</router-link>
    <router-view></router-view>

2.8 导航守卫

在一个SPA应用中,监听路由的跳转过程,做一些操作,比如更改网页的 title标题

2.8.1 全局守卫
  • beforeEach:前置守卫(guard),路由跳转之前回调,必须要调用next()函数

    • to:即将要进入的目标路由
    • from:即将要离开的路由对象
    • next:调用该方法,才能进入下一个钩子
  • beforeResolve: 解析守卫,和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用

  • afterEach:后置钩子(hook),路由跳转之后回调,不需要再调用next()函数

    router.afterEach((to,from) => {
      ...
    })
    
    

index.js

第一步:路由文件定义函数

router.beforeEach((to,from,next) => {
     
     
 document.title = to.matched[0].meta.title
 next()
})

//或者
router.afterEach((to,from) => {
     
     
 document.title = to.matched[0].meta.title
})

第二步:定义元数据(描述数据)

{
     
     
 path: '/about',
 component: About,
 meta: {
     
     
    title: '关于'
 },
}

2.8.2 路由独享的守卫
  • 直接在某个路由配置上定义beforeEnter守卫,参数跟beforeEach一样

    • to:即将要进入的目标路由
    • from:即将要离开的路由对象
    • next:调用该方法,才能进入下一个钩子
    {
          
          
      path: '/about',
      component: About,
      meta: {
          
          
        title: '关于'
      },
      beforeEnter: (to,from,next) => {
          
          
        console.log('beforeEnter')
        next()
      }
    }
    
    
2.8.3 组件内的守卫
const Foo = {
    
    
  template: `...`,
  beforeRouteEnter (to, from, next) {
    
    
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    
    
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    
    
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

2.9 URL 的 hash 和 H5 的 history

改变 url,但是页面不进行整体刷新,vue-router 会监听路径的改变触发相应的回调函数,默认是 hash 模式

  1. URL 的 hash,本质是是改变locationhash属性

    localhost:8080
    
    location.hash = 'foo'
    localhost:8080/#/foo
    
    
  2. H5 的 history

    localhost:8080
    
    history.pushState({},'','foo')
    localhost:8080/foo
    
    

3、Vuex

一个专门为 Vue.js 应用程序开发的状态管理模式

  • 如用户的登录状态、用户信息
  • 如商品的收藏、购物车的物品等等

3.1 作用流程

组件引用(Render)vuex中的state,发出(Dispatch)一个行为(Actions),提交(Commit)到 Mutations,再来改state

Devtools可以记录修改的状态,但是必须是通过Mutations修改的,可以不经过Actions直接修改,但是必须是同步操作,Devtools只能跟踪同步,异步操作只能通过Actions,再提交到Mutations就是同步了

3.2 安装使用

  1. 安装

    npm i vuex
    
    
  2. 使用

    // store 文件夹 index.js
    
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
          
          
      state: {
          
          
      
      }
    })
    
    export default store
    
    // main.js 
    
    import store from './store'
    new Vue({
          
          
      el: '#app',
      store,
      render: h => h(App)
    })
    
    

3.3 Vuex 五个核心概念

如果状态信息是保存到多个 Store 对象中,那么之后的管理和维护都会非常困难,所以 vuex 使用了单一状态树管理应用层级的全部状态

响应式原理

Store 对象中的属性都会被加入到响应式系统中,而响应式系统会监听属性的变化,当属性发生变化时,通知所有界面用到该属性的地方发生刷新

  • 所有响应式属性必须是先在 store定义好的
  • 后面追加的属性如果要响应式,须通过 Vue.set() 方法追加
3.3.1 state

单一状态树(数据源),放状态相关的信息,在项目中任何位置可以通过$store.state访问其里面的属性

mapState 辅助函数
// store/index.js
const store = new Vuex.Store({
    
    
  state: {
    
    
    count: 10
  }
})

// App.vue
<div>{
   
   {count}}</div>

import { mapState } from 'vuex'

computed: {
  ...mapState({
    count: 'count' // 这里可以重命名
  })
  // 或者
  ...mapGetters(['count']} // 这里不能重命名
}

3.3.2 getters

类似计算属性,有时候需要获取 state编译后的状态

const store = new Vuex.Store({
    
    
  state: {
    
    
    count: 10
  },
  /**
   * getters 里的方法第一个参数指向 state 状态
   * getters 里的方法第二个参数指向 getters 状态
   */
  getters: {
    
    
    more(state) {
    
    
      return state.count * 10
    },
    moreTwo(state, getters) {
    
    
      return getters.more * 10
    },
    //可以直接返回一个函数让用户操作
    backCount(state) {
    
    
      return count => {
    
    
        state.count = count
      }
    }
  }
})

// App.vue
<p>{
    
    {
    
    $store.getters.more}}</p>
<p>{
    
    {
    
    $store.getters.moreTwo}}</p>
// 此处把 count 改成了 20
<p>{
    
    {
    
    $store.getters.backCount(20)}}</p>
// 200
// 2000
// 20

mapGetters 映射

store中的getters映射到局部计算属性

// getters.js
export default {
    
    
  cartCount(state) {
    
    
    return state.cartList.length
  }
}

// Cart.vue
<div slot="center">购物车({
    
    {
    
    cartCount}})</div>

import {
    
     mapGetters } from 'vuex'

computed: {
    
    
  ...mapGetters({
    
    
    cartCount: 'cartCount' // 这里可以重命名
  })
  // 或者
  ...mapGetters(['cartCount']} // 这里不能重命名
}

3.3.3 mutations

更新 store 状态的唯一方式:提交(commit)mutations

里面的方法必须是同步函数,同步操作可以在组件内直接 commitmutations

普通提交

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

Vue.use(Vuex)

const store = new Vuex.Store({
    
    
  state: {
    
    
    count: 0
  },
  //mutations 里的方法参数 state 指向 state 状态
  mutations: {
    
    
    increment(state) {
    
    
      state.count++
    },
    decrement(state) {
    
    
      state.count--
    }
  }
})

//3.导出
export default store

<button @click="addition">+</button>
<button @click="subtraction">-</button>
<p>{
    
    {
    
    $store.stare.count}}<p>
  
methods: {
    
    
  addition() {
    
    
    //提交一个行为到 mutations
    this.$store.commit('increment')
  },
  subtraction() {
    
    
    this.$store.commit('decrement')
  }
}

参数被称为mutation的载荷(payload),也可以是一个对象

普通传参

// App.vue
addCount(count) {
    
    
  this.$store.commit('incrementCount',count)
}

// mutations.js
incrementCount(state,count) {
    
    
  return state.count += 5
}

传对象参数

// App.vue
addCount(count) {
    
    
  this.$store.commit({
    
    
    type: 'incrementCount',
    count
  })
}

// mutations.js
incrementCount(state,payload) {
    
    
  return state.count += payload.count
}

类型常量

避免mutation中方法名出错,官方推荐使用类型常量

// store/mutation-types.js    
export const INCREMENT = 'increment'

// index.js 
import {
    
     INCREMENT } from './mutation-types'
mutations: {
    
    
  [INCREMENT](state) {
    
    
    
  }
}

// App.vue
addition() {
    
    
  this.$store.commit('increment')
}

3.3.4 actions

处理异步操作,可以接收两个参数,conrext表示上下文,payload表示接收数据,可以是一个对象

// index.js
mutations: {
    
    
  updateInfo(state) {
    
    
    return state.data = 2
  }
},
actions: {
    
    
  //context:上下文,payload:接收的参数,可以是一个对象
  aUpdateInfo(context,payload) {
    
    
    return new Promise((resolve,reject) => {
    
    
      setTimeout(() => {
    
    
        context.commit('updateInfo')
        console.log(payload);
        resolve('异步返回')
      },1000)
    })
  }
}

// App.vue
revise() {
    
    
  //dispatch 一个行为到 action,传入一个参数
  this.$store
    .dispatch('aUpdateInfo','修改完成')
    .then(res => {
    
    
      console.log(res);
    })
}

mapActions 映射
// actions.js
export default {
    
    
  addCart(context, payload) {
    
    
    return new Promise((reslove, reject) => {
    
    
      let oldProduct = context.state.cartList.find(
        (item) => item.iid === payload.iid
      )
      // 查找数组中是否有相同的商品
      if (oldProduct) {
    
    
        context.commit(ADD_COUNTER, oldProduct)
        reslove('当前商品数量+1')
      } else {
    
    
        payload.count = 1
        context.commit(ADD_TO_CART, payload)
        reslove('添加商品成功')
      }
    })
  }
}

// Detail.vue
import {
    
     mapActions } from 'vuex'

methods: {
    
    
  ...mapActions(['addCart']),
  this.addCart(product).then(res => {
    
    
    console.log(res)
  })
  // 等同于
  // this.$store.dispatch('addCart', product).then(res => console.log(res))
}

3.3.5 modules
  • Vue 使用单一状态树,那么意味着很多状态都会交给 Vuex 来管理
  • 当应用变得复杂时,stote 对象就有可能变得相当臃肿
  • 为了解决这个问题,可以将 store 分割成模块(Module),而每个模块都拥有自己的 stategettersmutationsactions
用法
const moduleA = {
    
    
  state: {
    
    
    name: 'zhangsan'
  },
  getters: {
    
    
    fullname(state) {
    
    
      return state.name + '111'
    },
    fullname2(state,getters,rootState) {
    
    
      return getters.fullname + rootState.name
    }
  },
  mutations: {
    
    },
  actions: {
    
    }
}

const moduleB = {
    
    
  state: {
    
    },
  getters: {
    
    },
  mutations: {
    
    },
  actions: {
    
    }
}

const stote = new Vuex.Stote({
    
    
  state:{
    
    
    name: 'lisi'
  },
  //默认会把 a,b 对象放入 state 中
  modules: {
    
    
    a: moduleA,
    b: moduleB
  }
})

stote.state.a // moduleA 的状态
stote.state.b // moduleB 的状态

App.vue
//访问模块中的 state
<p>{
    
    {
    
    $store.state.a.name}}</p> //zhangsan

//访问模块中的 getters ,直接访问,先去内部找,没有再去模块中找
<p>{
    
    {
    
    $store.getters.fullname}}</p> //zhangsan111

//模块中的 getters 第三个参数指向实例中的 state
<p>{
    
    {
    
    $store.getters.fullname2}}</p> //zhangsan111lisi

//actions 和 mutations 用法也是直接用

3.4 事件总线

组件发射一个事件this.$bus.$emit('aaa',参数),其他组件都可以通过this.$bus.$on('aaa',callback)监听,通过this.$bus.$off('aaa',callback)取消监事件函数(一定要传函数,不然会全局取消事件)

  • 需要在 main.js 里添加一个原型属性$bus

    // main.js
    Vue.prototype.$bus = new Vue()
    
    // GoodsItem.vue
    imgLoad() {
          
          
      this.$bus.$emit('imgLoad')
    }
    
    // Home.vue
    mounted() {
          
          
      this.itemImgListener = () => {
          
          
        ...
      }
      this.$bus.$on('imgLoad',this.itemImgListener)
    },
    deactivated() {
          
          
      this.$bus.$off('imgLoad',this.itemImgListener)
    },             
    
    

4、axios

4.1 功能特点

  • 在浏览器中发送 XMLHttpRequest 请求
  • 在 node.js 中发送 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据

4.2 请求方式

  • axios(config)
  • axios.request(config)
  • axios.get(url[,config])
  • axios.delete(url[,config])
  • axios.head(url[,config])
  • axios.post(url[,data[,config]])
  • axios.put(url[,data[,config]])
  • axios.patch(url[,data[,config]])

4.3 安装使用

4.3.1 安装
npm i axios

main.js
import axios from 'axios'

4.3.2 使用
get 请求
//method 不写默认是 get 请求
axios({
    
    
  url: '',  //地址
  params: {
    
     //get请求传参,或者直接拼在地址后也可以
    
  }    
}).then(res => {
    
       //请求成功,操作数据
  console.log(res)
})

axios.get(url, {
    
    
  params: {
    
    
    
  }
})
.then(res => {
    
    
  console.log(res);
})

post 请求
axios.post(url, {
    
    
  firstName: 'Fred',
  lastName: 'Flintstone'
})
.then(res => {
    
    
  console.log(res);
})

// 发送 POST 请求
axios({
    
    
  method: 'post',
  url: '',
  data: {
    
    
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

并发请求
axios.all([axios(),axios()])
  .then(res => {
    console.log(res) //返回的数据放在一个数组里
  })
  
//或者使用这种方法直接拿结果
axios.all([axios(),axios()])
  .then(axios.spread((res1,res2) => {
    console.log(res1)
    console.log(res2)
  }))
  

4.3.3 配置项
  • url:请求地址
  • method:请求类型
  • baseURL:请求根路径
  • transformRequest:(data) => {}:请求前的数据处理
  • transformResponse:(data) => {}:请求后的数据处理
  • headers:{'x-Requested-With'}:自定义请求头
  • params:url 查询对象,适用于 get 请求
  • data:作为请求主体被发送的数据,只适用于’PUT’, ‘POST’, 和 ‘PATCH’
  • timeout:超时设置

4.4 创建实例与模块封装

4.4.1 创建实例

如果接口有多个服务器,那么就可以通过创建实例来配置选项

const instance1 = axios.create({
    
    
  baseURL: 域名, //配置这个之后的 url 都只需输路径
  timeout: 5000//请求超过5s报错 
})

instance1({
    
    
  url: 路径,
  methos: 'get',
  params: {
    
    
    
  }
})

4.4.2 模块封装

避免第三方库与组件发生强藕性,建议封装个 axios 使用

  1. 创建文件夹 network ,下面创建个 request.js

    import axios from "axios";
    
    export function request(config) {
      const instance = axios.create({
        baseURL: "http://152.136.185.210:8000/api/z8",
        timeout: 5000,
      });
    
      return instance(config);
    }
    
    
  2. 其他文件引入就可以直接使用

    import {request} from './network/request'
    
    request({
      url: 路径,
      methos: 'get',
      params: {
        
      }
    })
    
    

4.5 拦截器

4.5.1 请求拦截

请求成功拦截,请求失败拦截

适用场景:

  1. 比如config中的一些信息不符合服务器的要求,需要添加一些信息
  2. 每次发送请求时,希望在界面显示一个正在请求的动画图标
  3. 某些网络请求(比如登录(token)),必须携带一些特殊的信息
import axios from 'axios'

export function request(config) {
  //1.创建axios实例
  const instance = axios.create({
    baseURL: 域名 //配置这个之后的 url 都只需输路径
    timeout: 5000//请求超过5s报错 
  })
  
  //2.axios 拦截器
  instance.interceptors.request.use(config => {
    console.log(config)
    //注意:拦截之后一定要把结果返回出去
    return config
  },err => {
    console.log(err)
  })
  
  //3.发送真正的网络请求
  return instance(config)
}

4.5.2 响应拦截

响应成功拦截,响应失败拦截

服务器响应回来的数据,axios会自动加一些东西,但是我们只需要data里的东西,所以可以做一层拦截

import axios from 'axios'

export function request(config) {
  //1.创建axios实例
  const instance = axios.create({
    baseURL: 域名 //配置这个之后的 url 都只需输路径
    timeout: 5000//请求超过5s报错 
  })
  
  //2.axios 拦截器
  //请求拦截
  instance.interceptors.request.use(config => {
    //console.log(config)
    //注意:拦截之后一定要把结果返回出去
    return config
  },err => {
    console.log(err)
  })
  
  //响应拦截
  instance.interceptors.response.use(res => {
    //注意:拦截之后一定要把结果返回出去
    return res.data
  },err => {
    console.log(err)
  })
  
  //3.发送真正的网络请求
  return instance(config)
}

5、环境变量配置

  1. 设置开发环境的环境变量

    • 在根目录创建一个.env.development的文件

    • 设置开发环境变量 (注意点:以VUE_APP_变量名开头)

      VUE_APP_BASEURL = http://127.0.0.1/heimamm/public
      
    • 访问:process.env.VUE_APP_变量名

      alert(process.env.VUE_APP_BASEURL)
      
  2. 设置生产环境的环境变量

    • 在根目录创建一个.env.production的文件

    • 设置开发环境变量 (注意点:以VUE_APP_变量名开头)

      VUE_APP_BASEURL = http://autumnfish.cn/heimamm/public
      
    • 访问:process.env.VUE_APP_变量名

      alert(process.env.VUE_APP_BASEURL)
      

    注意:设置完成后,需要重新启动脚手架

猜你喜欢

转载自blog.csdn.net/weixin_44257930/article/details/109068571