Vue.use,Vuex,反向代理

Vue.use

所有vue后缀文件都是组件,需要在main.js中引入(import)并注册组件

自定义插件:

1
2
3
4
5
6
7
8
9
10
// 自定义插件对象
const plugin = {
// install方法会在Vue.use调用时被自动调用
install () {
// 这样一来只要Vue.use就会自动注册组件了
vue.component('my-button', {...})
}
}

export default plugin

main.js

1
2
3
import Vue from '../Vue.js'
import plugin from '../plugin.js'
Vue.use(plugin)

打包优化

vue-cli语法:yarn build

优化:

  • js文件夹中的map后缀文件是用来做浏览器兼容调试的,不需要可以删

  • ventors作为第三方包的汇总会很大

    CDN优化:CDN是部署于世界各地的服务器,服务器内有大部分常用的第三方包(将包部署于CDN需要收费,很贵,一般不会把项目部署到CDN中),引入时其实只要写上包的地址即可,不需要放在项目中

    配置方法(以Vue举例):

    1
    2
    <!-- 在打包后的index.html中引入 -->
    <script src="cdn中Vue的地址"></script>
    1
    2
    3
    4
    5
    6
    7
    8
    // 在vue.config.js中配置webpack忽视node_modules
    configurWebpack: {
    // 配置打包的排除项,从外部引入
    externals: {
    // 这样就会忽视node_modules,去导入全局的vue了
    vue: 'Vue' // 这个值需要去对应的cdn地址的文件中找export的变量名
    }
    }
  • 自己的js也打包到一个文件内了,项目页面多了会很大

    vue异步组件:需要什么加载什么

    • 第一步优化:
    1
    2
    3
    4
    5
    6
    7
    // router.js
    // 将import需要的路径放到一个返回该路径的回调函数中,不调用该函数不会加载组件

    // import Login from './components/Login.vue'
    const Login = () => import('./components/Login.vue')

    // 问题:请求次数变多了
    • 第二步优化:
    1
    2
    3
    4
    // 将引入的模块分类
    const Login = () => import(/* webpackChunkName: '模块分类名' */'./components/Login.vue')

    // 这样打包后会将同一个分类的模块打包到一起去,访问其中一个会请求所有的模块

上线前需要把main.js中配置的axios默认路径前缀修改为线上服务器路径。

Vuex

vuex时vue的状态管理工具,用于管理vue中的数据,所有组件都能访问到其中的数据,和localStorage类似。

  • 和localStoragede区别:

    localStorage中只能存字符串,而vuex可以存任意类型

  • vuex会增加项目复杂度

使用方法:

  1. 下载&引入

  2. Vue.use()使用vuex

  3. 创建仓库store

    1
    2
    3
    4
    5
    6
    const store = new Vuex.Store({
    // 状态即数据
    state: {
    msg: 'hoho'
    }
    })
  4. 和vue实例建立关联

    1
    2
    3
    4
    5
    6
    7
    const vm = new Vue({
    el: '#app',
    data: {
    msg: 'lala'
    },
    store
    })

访问vuex中的数据:

  • js中

    • store.state.msg
    • this.$store.state.msg
    • vm.$store.state.msg
  • 组件中

    • $store.state.msg

写起来很麻烦,通常使用计算属性返回

修改vuex中的值

直接修改vuex的值不会报错,需要采用严格模式(原理为深度监听,上线后需要取消):

1
2
3
4
5
6
7
const store = new Vuex.Store({
state: {
msg: 'hoho'
},
// 开启严格模式
strict: true
})

应该遵守vuex到项目的单向数据流,修改数据应该使用mutation方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const store = new Vuex.Store({
state: {
msg: 'hoho'
},
// strict: true,
mutations: {
change2(state, obj) {
// mutations中所有的方法第一个参数都是state
state.msg = obj.msg2
}
}
})

const vm = new Vue({
el: '#app',
data: {
msg: 'lala'
},
methods: {
change () {
// 修改vuex中的数据需要提交,可以传参(只能传一个参数,有多个参数就使用对象)
this.$store.commit('change2', { msg2: 'haha' })
}
}
store
})

基于vuex的派生属性(相当于计算属性的getter)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const store = new Vuex.Store({
state: {
msg: 'hoho'
},
// strict: true,
mutations: {
change2(state, obj) {
state.msg = obj.msg2
}
},
getters: {
getter1 (state) {
// 第一个参数也是state
return state.msg
}
}
})

vuex辅助函数的使用(语法糖)

  • mapGetters:是一个函数,将vuex中的getters直接映射给组件,相当于在computed中设置属性返回getters

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 组件中
    import { mapGetters } from 'vuex'// 精确导入
    export default {
    computed: {
    // 为了写自己的计算属性,使用展开运算符
    ...mapGetters([getters中的属性名]),
    // 使用对象可以自定义属性名
    ...mapGetters({
    自定义属性名: getters中的属性名
    })
    }
    }
  • mapState:用法和mapGetters一样

  • mapMutations:不好用,因为只有只进行了提交操作的mutations能使用

vuex-actions

由于异步函数是由window调用的,所以mutiation中使用异步函数会报错。事实上所有回调函数的调用都无法被追踪,所以需要用到actions

1
2
3
4
5
6
7
8
9
10
11
12
// vuex中
const store = new Vuex.Store({
// actions中不能直接操作state,只能提交mutations来操作
actions = {
// 所有actions中的第一个参数,都是context(上下文),也就是store
change (context) {
setTimeout(() => {
context.commit(mutations方法, 参数)
})
}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
// 组件中
const vm = new Vue({
el: '#app',
data: {
msg: 'lala'
},
methods: {
change () {
this.$store.dispatch(actions属性名)
}
}
store
})

module

在需要多个仓库里使用module来分模块

vue反向代理

浏览器同源策略会使浏览器与服务器之间产生跨域问题,但是服务器与服务器之间没有跨域问题,所以在vue中采用代理服务器就可以解决这一问题。

使用webpack中的配置可以进行配置(平常更多使用的是ngnix),开发的时候常会遇到跨域问题,使用的较为频繁

配置devServer.proxy

1
2
3
4
5
6
7
8
9
10
11
12
13
// vue.config.js中
export default {
devServer: {
proxy: {
// 只要请求的路径中包含/api就会被代理成 http://需要被代理的路径/api/... 。
"/api": {
target: "需要被代理的路径",
// 路径中多了个/api,需要重写
pathRewrite: {"^/api": ""}
}
}
}
}

之后再发送请求,表面上是向页面所在服务器请求,实际上则是由代理服务器向后台发送了请求,并返回了数据。