# 医保网厅架构介绍
# api
在我们开发的时候按照模块或者页面来区分开调用的接口,并把他们放在一起方便管理
例如: 在@api/modules/
下创建一个setting-api.js
import axios from "../common-axios.js" // 引用axios
const pathLogin = `/pgs/gw/usc-nation/api` // 地址变量看具体项目而定
const path = `/hsa-pss-pw/web/elc` // 地址变量看具体项目而定
export const getQRCode = (params) => axios.post(`${path}/getQRCode`, {
data: params
})
export const getQRCodeStatus = (params) => axios.post(`${path}/getQRCodeStatus`, {
data: params
})
export const refresh = (params) => axios.post(`${pathLogin}/login/refresh`, {
data: params
})
推荐以下这种形式写
export const getQRCode = function(params) {
return axios({
url: `${path}/getQRCode`,
method: "post",
data: params // 如果请求方式不是post需要将data改为params
})
}
值得注意的一点是:如果请求方式不是post
需要将data
改为params
完成之后我们在index.js
中引入,再通过index.js
统一导出
import * as setting from "./modules/setting-api"
export {
setting
}
最后我们在页面上调用这里
<script>
import { setting } from "@api/index" // 引入我们需要的接口模块
export default {
created() {
// 通过链式调用接口
// params指接口参数 如: {name: "guoruliang", password: "123456"}
setting.getQRCode(params).then(res => {})
setting.getQRCodeStatus(params).then(res => {})
setting.refresh(params).then(res => {})
},
data() {
return {}
},
components: {},
methods: {}
}
</script>
# jsconfig.json
文件路径引导
我们使用vscode
的时候,如果我们使用了别名就无法联想路径了,这很可能导致我们手敲从而打错路径,这里我们需要安装一个vscode
插件
vscode插件搜索 Path Autocomplete
之后再项目的根目录创建jsconfig.json文件,并添加代码如下
{
"compilerOptions": {
"baseUrl": ".",
"paths": { // 这里的配置根据vue.config.js中的别名配置进行配置
"@/*": ["src/*"],
"@utils/*": ["src/utils/*"],
"@api/*": ["src/api/*"],
"@components/*": ["src/components/*"],
"@pic/*":["src/assets/img/*"],
"@pages/*": ["src/pages/*"]
},
"target": "ES6",
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
# Vue.config.js
# preload和 Prefetch
懒加载失效的原因:preload 和 Prefetch 链接将会消耗带宽。如果你的应用很大且有很多 async chunk,*而用户主要使用的是对带宽较敏感的移动端,*那么你可能需要关掉 prefetch 链接并手动选择要提前获取的代码区块,但是官网文档是错的要自己打印出来看看 console.log(config) 因为他改名字了
chainWebpack: config => {
config.plugins.delete("prefetch-index")
config.plugins.delete("preload-index")
}
# 打包分割splitChunks
配合懒加载使用,有兴趣的可以自己结合webpack文档看看
config.optimizationsplitChunks({
chunks: "async", // 参数 all:全部 async:异步 initial:同步 默认:async
minSize: 30000, // 最小尺寸 默认30000 单位字节 ,如果我们导入的文件小于30000就直接合并如果大于就进行文件的分割
maxSize: 50000, // 最大尺寸 单位字节,如果我们导入的包经过打包后还是大于50000则继续分割,直到小于50000为止(但是如果这个代码无法分割就不分割了)
minChunks: 1, // 引用次数超出1就分割
maxAsyncRequests: 5, // 最大的模块引用数 引入的前5个会进行分割打包,超过5不打包
maxInitialRequests: 3, // 最大的入口文件引用数,引入的前3个会进行分割打包,超过3个不会打包
automaticNameDelimiter: '~', // 名称连接符
name: true, // 默认就是true 来标明一下cacheGroups是否生效
cacheGroups: { // 这里的匹配规则是,是否满足vendors规则,满足则按照vendors的规则分割,
// 不满足就去default,还不满足就不打包,当两个规则都符合就比较priority
// 哪个大就按哪个来
vendors: { 打包组 如果是从node_modules导入就统一归类到vendors组
test: /[\\/]node_modules[\\/]/, // 匹配规则
priority: -10
},
default: { 默认打包组
minChunks: 1, // 引用次数超出1就分割
priority: -20,
reuseExistingChunk: true // 如果我们打包的文件已经被打包过了,就忽略掉,不打包第二次了
}
}
})
# Gzip
开启Gzip极大的减少包的大小,(在一个1M带宽的服务器下)原本首屏需要17s多的首屏加载,经过Gzip的优化处理只需要5s,可见这个速度
项目配置 vue.config.js
configureWebpack: (config) => {
const productionGzipExtensions = ["js", "css"]
if (isProd) {
// 生产环境
config.plugins.push(
new CompressionWebpackPlugin({
filename: "[path].gz[query]",
algorithm: "gzip",
test: new RegExp(`\\.(${productionGzipExtensions.join("|")})$`),
threshold: 20240,
minRatio: 0.8
})
);
} else {
// 开发环境
}
nginx服务器配置
#开启和关闭gzip模式(on|off),开启gzip,需设置为on
gzip on;
# vuex
vue状态管理
目录结构如下:
├── store (vuex) # vue状态管理
├── modules # 模块化vuex
│ └── common.js
└── index.js # vuex入口
# common.js
const common = {
// 存储变量的
state: {
test: "我是vuex测试"
},
// 获取变量、类似于计算属性
getters: {
test: state => state.test
},
// 对变量进行操作的 支持异步操作
actions: {
setTest: ({ commit }, val) => {
setTimeout(() => {
commit("SET_TEST", val)
}, 5000)
}
},
// 对变量进行操作的 不支持异步操作
mutations: {
SET_TEST(state, val) {
state.test = val
}
}
}
export default common
# index.js
import Vue from "vue"
import Vuex from "vuex"
import common from "./modules/common"
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
common
}
})
export default store
如何使用:
# child.vue
<template>
<div class="container">
子路由1
{{test}}/{{xx}}
</div>
</template>
<script>
import { mapGetters } from "vuex"
export default {
components: {},
name: "child1",
watch: {},
computed: {
...mapGetters([ // 方式1
"test"
])
},
props: {},
filters: {},
data() {
return {
xx: this.$store.getters.test // 方式2
}
},
created() {},
mounted() {},
methods: {
},
destroyed() {}
}
</script>
<style scoped>
</style>
# Vuex-demo.js
<template>
<div class="container">
vuex
<button @click="changeVuex">修改vuex的值</button>
<button @click="changeVuex2">修改vuex的值2</button>
</div>
</template>
<script>
import { mapMutations, mapActions } from "vuex" // 引入
export default {
components: {},
name: "vuex",
watch: {},
props: {},
filters: {},
data() {
return {
}
},
created() {},
mounted() {},
methods: {
...mapMutations(["SET_TEST"]), // 方式1 mutations
...mapActions(["setTest"]), // 方式1 actions
changeVuex() {
// 两种方式效果相同
this.SET_TEST("是我mutations改的")
// this.$store.commit("SET_TEST", "是我mutations改的") // 方式2
},
changeVuex2() {
// 两种方式效果相同
this.setTest("是我actions改的")
// this.$store.dispatch("setTest", "是我actions改的") // 方式2
}
},
destroyed() {}
}
</script>
<style scoped>
</style>
# 本地存储(websStorage和Cookie)
# localStorage和sessionStorage
localStorage长期存在,需要手动清空才会消失
sessionStorage浏览器关闭后清空
两者本质上没什么区别用法也相同
const ls = window.localStorage // 或 const ls = window.sessionStorage
// sessionStorage
// localUtil
export default {
getItem (key) {
try {
return JSON.parse(ls.getItem(key))
} catch (err) {
return err
}
},
setItem (key, val) {
try {
ls.setItem(key, JSON.stringify(val))
} catch (err) {
return err
}
},
clear () {
ls.clear()
},
keys () {
return ls.keys()
},
removeItem (key) {
ls.removeItem(key)
}
}
使用
<template>
<div class="container">
<button @click="setSessionStorage">设置sessionStorage</button>
<button @click="getSessionStorage">获取sessionStorage</button>
<button @click="removeSessionStorage">移除sessionStorage</button>
<button @click="setLocalStorage">设置localStorage</button>
<button @click="getLocalStorage">获取localStorage</button>
<button @click="removeLocalStorage">移除localStorage</button>
<button @click="setCookie">设置Cookie</button>
<button @click="getCookie">获取Cookie</button>
<button @click="removeCookie">移除Cookie</button>
</div>
</template>
<script>
import sessionStorage from "@utils/sessionStorage"
// import localStorage from "@utils/localUtil"
import cookie from "@utils/cookie"
export default {
components: {},
name: "storage",
watch: {},
props: {},
filters: {},
data() {
return {
}
},
created() {},
mounted() {},
methods: {
// 设置localStorage
setLocalStorage() {
localStorage.setItem("user", "我")
},
// 获取localStorage
getLocalStorage() {
console.log(localStorage.getItem("user"))
},
// 移除localStorage
removeLocalStorage() {
localStorage.removeItem("user")
},
// 设置sessionStorage
setSessionStorage() {
sessionStorage.setItem("user", "我")
},
// 获取sessionStorage
getSessionStorage() {
console.log(sessionStorage.getItem("user"))
},
// 移除sessionStorage
removeSessionStorage() {
sessionStorage.removeItem("user")
},
// 设置Cookie
setCookie() {
cookie.setCookie("user", "我", 24*60*60*1000) // 一天后过期
},
// 获取Cookie
getCookie() {
console.log(cookie.getCookie("user"))
},
// 移除Cookie
removeCookie() {
cookie.removeCookie("user")
}
},
destroyed() {}
}
</script>
<style scoped>
</style>
# Cookie
与webStorage的区别是Cookie可以自己设置过期时间
function setCookie(key, value, iDay) {
var oDate = new Date();
oDate.setDate(oDate.getDate() + iDay);
value = JSON.stringify(value)
document.cookie = key + '=' + value + ';expires=' + oDate + ';path=/';
}
function removeCookie(key) {
setCookie(key, '', -1); //这里只需要把Cookie保质期退回一天便可以删除
}
function getCookie(key) {
var cookieArr = document.cookie.split('; ');
for (var i = 0; i < cookieArr.length; i++) {
var arr = cookieArr[i].split('=');
if (arr[0] === key) {
try {
return JSON.parse(arr[1])
} catch (err) {
return err
}
}
}
return false;
}
function clearCookie() {
var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
if (keys) {
for (var i = keys.length; i--;)
document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
}
}
export default {
setCookie,
removeCookie,
getCookie,
clearCookie
}
# vue-router
# 路由设置
export default [
{
path: "/",
redirect: "/home" // redirecet 重定向
},
{
path: "/home",
name: "home",
meta: {
keepAlive: false,/*不需要被缓存 */
title: "首页",
icon: 'example'//展示的图标
},
redirect: '/index',
component: () => import(/* webpackChunkName: "home" */ "@/views/home.vue"),
children: [ // 路由嵌套 子路由
{
path: "child1",
name: "child1",
meta: {
title: "子页面1",
},
component: () => import(/* webpackChunkName: "home" */ "@/views/child1.vue"),
},
{
path: "child2",
name: "child2",
component: () => import(/* webpackChunkName: "home" */ "@/views/child2.vue"),
meta: {
title: "子页面2"
},
}
]
}
]
redirecet 路由重定向
children 路由嵌套
/* webpackChunkName: "home" */ 魔法注释,将webpackChunkName同名的打包成一个包,在页面没有调用
打包内容的路由时浏览器不会进行加载
效果展示:children嵌套输出类似如下开关路由导航:
# Vue-router的跳转方式
//方式一:在页面中跳转 在设置tag属性前 router-link本质上就是个a标签 tag设置成button则搭载在button标签上
//不带参数:
<router-link :to="{path:'/home'}" tag="button">vuex</router-link>
//带参数
<router-link :to="{path:'/home',query:{id:1,yourname:'myname'}}" tag="button">vuex</router-link>
//方式二: 通过浏览器地址传值,刷新浏览器 参数不会消失
this.$router.push({ path: "/storage", query: { name: "我是从home来的query" }})
路由跳转使用方式
<template>
<div class="container">
<ul>
<li>
<router-link to="/axios">axios</router-link>
</li>
<li @click="goStorage">
storage
</li>
<li>
<router-link :to="{path:'/home/child1'}">child1</router-link>
</li>
<li>
<router-link :to="{path:'/home/child2',query:{id:1,yourname:'myname'}}">child2</router-link>
</li>
</ul>
<div class="children">
<router-view></router-view>
</div>
</div>
</template>
<script>
import { setting } from "@api/index"
export default {
created() {
setting.getQRCode().then(res => {})
setting.getQRCodeStatus().then(res => {})
setting.refresh().then(res => {})
},
data() {
return {}
},
components: {},
methods: {
goStorage() {
// 函数跳转方式
this.$router.push({
path: "/storage",
query: { name: "我是从home来的query" }
})
}
}
}
</script>
<style lang="scss">
.container {
width: 100%;
ul {
overflow: hidden;
}
li {
float: left;
margin: 10px;
}
.children {
width: 500px;
height: 500px;
border: 1px solid #000;
background-color: $theme-blue;
}
}
</style>
刷新页面js调用:this.$router.go(0)
# 获取URL中的路由传参
<template>
<div class="container">
{{name}}
</div>
</template>
<script>
export default {
components: {},
name: "storage",
watch: {},
props: {},
filters: {},
data() {
return {
name: this.$route.query.name//url假设是:xxxx?name=zhangsan
}
},
created() {},
mounted() {},
methods: {
},
destroyed() {}
}
</script>
<style scoped>
</style>