Vue CLI3搭建项目初始
1.安装Vue CLI3
1.在cmd中执行:npm install -g @vue/cli
2.安装完成后,输入命令vue --version,查看Vue CLI的版本号是否是3.0以上,是代表安装成功。
2.创建项目
1.在cmd中执行:vue create xxx, xx为项目名称
2.选择,anually select features(手动选择功能)项或者default (babel, eslint)(默认安装);这里我选择anually
3.选择的有babel、router、vuex、css.路由选择历史模式,css预处理器为less语言选择In dedicated config files,将Babel、PostCSS等配置独立在package.json文件外。是否保存本次安装配置。选择不。
3.清理初始化脚手架项目。
1.package.json文件
原本代码块:
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
改为:
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-cli-service build"
},
2.清洁public文件下的index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
</head>
<body>
<div id="app"></div>
</body>
</html>
3.清洁router.js文件
import Vue from 'vue'
import Router from 'vue-router';
Vue.use(Router)
function load(component) { (这个函数会问题可以屏蔽)
return resolve => require([`./views/${component}`], resolve);
}
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: load('home')
},
]
})
4、清洁App.vue文件
<template>
<div>
<router-view/>
</div>
</template>
5、清洁views文件夹
删除views文件夹中的About.vue和Home.vue文件,
新建home.vue文件.内容如下:
<template>
<div>
欢迎使用Vue项目
</div>
</template>
6、清洁components文件夹
删除components文件夹中的HelloWorld.vue文件。
7、清洁assets文件夹
删除assets文件夹夹中的logo.png文。
8、清洁完毕
重新执行npm run dev,执行成功后在浏览器打开 http://localhost:8080/ ,页面展示<欢迎使用vue项目>,说明Vue项目已经清洁成功。
4、配置Vue项目
1、新建api文件夹和utils文件夹
npm i axios -save
utils内的axios封装的优化
/**
* axios封装
* 请求拦截、响应拦截、错误统一处理
*/
import axios from 'axios';
import router from '../router';
import store from '../store/index';
import { Toast } from 'vant'; //不安装vant就屏蔽
/**
* 提示函数
* 禁止点击蒙层、显示一秒后关闭
*/
const tip = msg => {
Toast({
message: msg,
duration: 1000,
forbidClick: true
});
}
/**
* 跳转登录页
* 携带当前页面路由,以期在登录页面完成登录后返回当前页面
*/
const toLogin = () => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}
/**
* 请求失败后的错误统一处理
* @param {Number} status 请求失败的状态码
*/
const errorHandle = (status, other) => {
// 状态码判断
switch (status) {
// 401: 未登录状态,跳转登录页
case 401:
toLogin();
break;
// 403 token过期
// 清除token并跳转登录页
case 403:
tip('登录过期,请重新登录');
localStorage.removeItem('token');
store.commit('loginSuccess', null);
setTimeout(() => {
toLogin();
}, 1000);
break;
// 404请求不存在
case 404:
tip('请求的资源不存在');
break;
default:
console.log(other);
}}
// 创建axios实例
var instance = axios.create({ timeout: 1000 * 12});
// 设置post请求头
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
/**
* 请求拦截器
* 每次请求前,如果存在token则在请求头中携带token
*/
instance.interceptors.request.use(
config => {
// 登录流程控制中,根据本地是否存在token判断用户的登录情况
// 但是即使token存在,也有可能token是过期的,所以在每次的请求头中携带token
// 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码
// 而后我们可以在响应拦截器中,根据状态码进行一些统一的操作。
const token = store.state.token;
token && (config.headers.Authorization = token);
return config;
},
error => Promise.error(error))
// 响应拦截器
instance.interceptors.response.use(
// 请求成功
res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),
// 请求失败
error => {
const { response } = error;
if (response) {
// 请求已发出,但是不在2xx的范围
errorHandle(response.status, response.data.message);
return Promise.reject(response);
} else {
// 处理断网的情况
// eg:请求超时或断网时,更新state的network状态
// network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
// 关于断网组件中的刷新重新获取数据,会在断网组件中说明
if (!window.navigator.onLine) {
store.commit('changeNetwork', false);
} else {
return Promise.reject(error);
}
}
});
export default instance;
api文件夹的index.js
/**
* api接口的统一出口
*/
// 模块接口
import test from '@/api/test'
// 其他模块的接口……
// 导出接口
export default {
test,
// ……
}
对应test模块的接口
import axios from '@/utils/http' // 导入http中创建的axios实例
const test = {
// 新闻列表
test() {
return axios.post(`/api/demo1`).then((res) => {
return res.data
})
},
}
export default test
demo.vue
this.$api.test.test().then(res => {
console.log(res);
})
最后,为了方便api的调用,我们需要将其挂载到vue的原型上。在main.js中:
import api from './api' // 导入api接口
Vue.prototype.$api = api; // 将api挂载到vue的原型上
2、新建mixins文件夹
在src文件夹下新建mixins文件夹,主要放置Vue混入文件。
在minxins文件夹下,新建index.js文件,主要放置全局混入的内容,
import { mapGetters } from 'vuex';
export default {
data() {
return {
}
},
computed: {
...mapGetters(['tip','moduleTip'])
},
mounted(){
},
methods: {
}
}
在main.js 引入全局混入,
import mixins from './mixins';
Vue.mixin(mixins);
3、配置assets文件夹
- 在assets文件夹下新建css文件夹,主要放置样式文件;
- 在assets文件夹下新建images文件夹,主要放置可以编译的图片文件。
4、新建router文件夹
在src文件夹下新建router文件夹,
删除src文件夹下的router.js文件,
在router文件夹中,新建index.js和routes.js文件,
index.js内容:
import Vue from 'vue';
import Router from 'vue-router';
import routes from './routes';
Vue.use(Router);
// 路由配置
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;
} else {
return {x: 0, y: 0};
}
}
});
router.beforeEach((to, from, next) => {
next();
});
router.afterEach((to, from, next) => {
window.scrollTo(0, 0);
});
export default router;
routes.js内容:
function load(component) { //懒加载写到
return resolve => require([`views/${component}`], resolve);
}
const routes = [
{
path: '/',
name: 'home',
component: load('home'),
meta: {
title: '首页'
}
},
{
path: '*',
redirect: {
path: '/'
}
}
];
export default routes;
5、新建store文件夹
在src文件夹下新建store文件夹,放置Vuex的内容,
删除src文件夹下的store.js文件,
在store文件夹下新建module文件夹,
在module文件夹下新建demo.js文件,
demo.js:
const state = {
moduleTip: '欢迎使用Vuex模块',
};
const getters = {
moduleTip: state => state.moduleTip,
};
const mutations = {
SET_MODULETIP(state, data) {
state.moduleTip = data;
},
};
const actions = {};
export default {
state,
getters,
mutations,
actions
}
在store文件夹下新建index.js文件,
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production';
import demo from './module/demo';
const store = new Vuex.Store({
strict: debug,
state: {
tip: '欢迎使用Vuex',
},
getters: {
tip: state => state.tip,
},
mutations: {
SET_TIP(state, data) {
state.tip = data;
},
},
actions: {
},
modules: {
demo,
}
});
export default store;
在minxins/index.js文件写入,
import { mapGetters } from 'vuex';
export default {
data() {
return {
}
},
computed: {
...mapGetters(['tip','moduleTip'])
},
mounted(){
},
methods: {
}
}
//在view/home.uve
//引用
<template>
<div>
欢迎使用Vue项目
{{tip}}
{{moduleTip}}
</div>
</template>
页面展示 "欢迎使用Vue项目 欢迎使用Vuex 欢迎使用Vuex模块".
6、Reset CSS样式
在src/assets/css文件夹下新建reset .less文件,网上找一个初始化样式文件
在main.js文件写入
import 'css/base/reset.css';
7、配置文件别名
在vue.config.js文件中配置内容如下:
const path = require('path');
function resolve(dir) {
return path.resolve(__dirname, dir)
}
module.exports = {
configureWebpack: {
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'@': resolve('src'),
'assets': resolve('src/assets'),
'css':resolve('src/assets/css'),
'images':resolve('src/assets/images'),
'views': resolve('src/views'),
'components':resolve('src/components'),
'api':resolve('src/api'),
'mixins':resolve('src/mixins'),
'store': resolve('src/store'),
'service':resolve('src/service'),
}
}
},
}
//关闭source map有两个好处
//减少打包编译的时间;
//避免在生产环境中用F12开发者工具在Sources中看到源码。
//在vue.config.js文件中配置内容如下:
module.exports = {
productionSourceMap: false,
}
//npm i Jquery -save
const webpack = require('webpack')
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'windows.jQuery': 'jquery',
}),
],
},
}
//代理 target为接口有ip(域名),api为本地使用时候前缀。
module.exports = {
devServer: {
host: 'localhost',
port: '8083',
proxy: {
'/api': {
// /api 表示拦截以/api开头的请求路径
target:
'https://www.fastmock.site/mock/fd7892a0bc009dd928228bb6dba37099/test', // 跨域的域名
changeOrigin: true, // 是否开启跨域
secure: false, // 如果是https接口,需要配置这个参数
pathRewrite: {
// 重写路径
'^/api': '', // 把/api变为空字符
},
},
},
},
}
8.附上main.js文件
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import mixins from './mixins'
import $ from 'jquery'
import api from './api' // 导入api接口
import 'swiper/dist/css/swiper.min.css' //
import 'swiper/dist/js/swiper.min' //
Vue.mixin(mixins)
Vue.config.productionTip = false
Vue.prototype.$api = api // 将api挂载到vue的原型上
new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app')
集合了以下两篇文章的内容,
作者:红尘炼心
链接:https://juejin.cn/post/6844903912097464334
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者:格子熊
链接:https://juejin.cn/post/6844903969152565261
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。