文章将自动保存至草稿箱
一、 区别vue-cli和webpack
vue-cli是什么:vue-cli是vue的命令行工具,只要按照官网敲几行命令就可以新建一个基本的vue项目框架。方便快捷。
vue-cli和webpack是什么关系:vue-cli 里面包含了webpack, 并且配置好了基本的webpack打包规则,
二、 使用vue-cli创建项目
1. 检查 node nvm vue-cli是否已经安装
mac nvm安装博客推荐:https://blog.csdn.net/longgege001/article/details/114067242
如若没有,安装命令为:cnpm install -g vue-cli 全局安装vue-cli
2.本地新建项目文件夹,初始化 vue init webpack create-cli(文件名)
3.等待安装完成
4.创建完成之后的文件内容
三、项目搭建完毕提前封装一些公共的方法方便后续开发;main.js引入;封装api;路由懒加载;路由首位➕拦截器;封装公共方法;
// main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import Mock from './mock'
import axios from './axios'
import './assets/css/custom.css'
import 'font-awesome/css/font-awesome.min.css'
import MyPlugin from './assets/js/plugin'
Vue.use(ElementUI)
Vue.use(MyPlugin)
Vue.config.productionTip = false
if (process.env.NODE_ENV === 'development') {
Mock.bootstrap()
}
/* eslint-disable no-new */
var vm = new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
export default vm
axios封装api及使用
const axios = window.axios
const apis: APIS = {
insetRhbt: {
url: '/mbs/add/web/bsc/rhbtList/insetRhbt',
method: post
},
doValid: {
url: '/mbs/add/web/bsc/rhbtList/doValid',
method: get
}
}
export async function insetRhbt (data) {
return axios({
url: apis.insetRhbt.url,
method: apis.insetRhbt.method,
data
})
}
export async function doValid (params) {
return axios({
url: apis.doValid.url + '/' + `${params.rhbtFilNo}`,
method: apis.doValid.method
})
}
//引入
import {doValid,insetRhbt} from '@/apis/recover'
// 项目内使用
const data = {
rhbtFilNo: this.formData1.psnNo
}
const res = await doValid(data)
// 路由懒加载
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/demo',
name: 'Demo',
meta: {
title: 'demo'
},
component: () => import('@/views/demo/index.vue') // 文件路径
},
]
// 路由守卫
import router from '@/router'
import whiteList from '@/router/whiteList'
import { getToken } from '@/utils/auth'
import { Route } from 'vue-router'
router.beforeEach(async (to: Route, from: Route, next: any) => {
// 校验是否在白名单之内
// if (whiteList.includes(to.path)) {
// next()
// } else {
// 查看是否有token
// const token: string = getToken()
// if (!token) {
// next('/login', true)
// } else {
next()
// }
// }
})
router.afterEach((to: Route) => {
document.title = to.meta.title
})
// 请求拦截器
import Vue, { PluginObject } from 'vue'
import axios, { AxiosResponse } from 'axios'
import { Message } from 'element-ui'
function errorCreate (msg:any, flag = true) {
const error = new Error(msg)
// 获取页面所有已经存在的message
const dom = document.getElementsByClassName('el-message')
// 设置值控制显示当前message
// 遍历获取到的message DOM集合
for (let i = 0; i < dom.length; i++) {
// 如果页面已存在的message中有显示文本和当前message相同的情况,flag设置为false
if (error.message === dom[i].getElementsByClassName('el-message__content')[0].innerHTML) {
flag = false
}
}
if (dom.length === 0 || flag) {
Message({
showClose: true,
message: error.message,
type: 'error',
duration: 3 * 1000
})
}
throw error
}
const config = {
// baseURL: process.env.baseURL || process.env.apiUrl || '/api',
timeout: 60 * 1000 // 请求超时
// withCredentials: true, // Check cross-site Access-Control
}
const _axios = axios.create(config)
// 请求拦截
_axios.interceptors.request.use(
(cfg: any) => {
// try {
// if (!whiteList.includes(cfg.url)) {
// const token = getToken()
// if (!token) {
// router.replace('/login')
// } else {
// // cfg.headers.Authorization = `Bearer ${token}`
// }
// }
// } catch (e) {
// }
return cfg
},
(err: Error) => {
// Do something with request error
return Promise.reject(err)
}
)
// 响应拦截
_axios.interceptors.response.use(
async (res: AxiosResponse<any>) => {
// dataAxios 是 axios 返回数据中的 data
const dataAxios = res.data
// 这个状态码是和后端约定的
const { code } = dataAxios
// 根据 code 进行判断
// 有 code 代表这是一个后端接口 可以进行进一步的判断
switch (code) {
case '0':
return dataAxios
case 0:
return dataAxios
default:
// 不是正确的 code
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return dataAxios
} else {
errorCreate(dataAxios.message)
}
break
}
},
async (error: any) => {
if (error && error.response) {
switch (error.response.status) {
case 400: error.message = '请求错误'; break
case 401: error.message = '未授权,请登录'; break
case 403: error.message = '拒绝访问'; break
case 404: error.message = `请求地址出错: ${error.response.config.url}`; break
case 408: error.message = '请求超时'; break
case 500: error.message = '服务器内部错误'; break
case 501: error.message = '服务未实现'; break
case 502: error.message = '网关错误'; break
case 503: error.message = '服务不可用'; break
case 504: error.message = '网关超时'; break
case 505: error.message = 'HTTP版本不受支持'; break
default: break
}
}
errorCreate(error)
return Promise.reject(error)
}
)
const Plugin: PluginObject<any> = {
install: (Vue) => {
Vue.$axios = _axios
}
}
Plugin.install = (Vue) => {
Vue.$axios = _axios
window.axios = _axios
Object.defineProperties(Vue.prototype, {
$axios: {
get () {
return _axios
}
}
})
}
Vue.use(Plugin)
export default Plugin
utils封装的公共方法
/**
* 防抖函数
* @param handler 处理函数
* @param wait 等待时间 number
*/
export default function (handler, wait) {
let timer: number
return () => {
if (timer) clearTimeout(timer)
timer = setTimeout(handler, wait)
}
}
// 格式化时间
/**
*
*格式化日期
* @param {Date|Number|String}time 传入的时间
* @param {String}format 日期格式,如‘yyyy-mm-dd hh:mm:ss’等
* @returns {string} 返回格式化之后的字符串
*/
export function dateFormat (time = new Date(), format = 'yyyy-MM-dd hh:mm:ss') {
if (typeof time === 'number' || typeof time === 'string') {
time = new Date(+time)
} else if (!(time instanceof Date)) {
throw new Error('第一个参数必须是Number或者Date类型')
}
// localstorage文件
const localStorage = window.localStorage
/**
* 设置或者更新Localstorage
* @param {String}name 需要设置的属性名称
* @param {any}item 需要设置的属性值
*/
export function setItem (name, item) {
if (!name) throw new Error('name属性是必须的')
if (!item) throw new Error('item属性是必须的')
localStorage.setItem(name, JSON.stringify(item))
}
/**
* 从localstorage中获取值
* @param {String}name 名称
* @returns {null|any} 返回对应值,如果没有则返回null
*/
export function getItem (name) {
if (!name) throw new Error('name属性是必须的')
const item = localStorage.getItem(name)
if (item === 'undefined') return null
return JSON.parse(item as any)
}
/**
* 删除指定localstorage
* @param {string}name storage名称
*/
export function rmItem (name) {
if (!name) throw new Error('name属性是必须的')
localStorage.removeItem(name)
}
/**
* 移除所有的localstorage
*/
export function clearAllItem () {
localStorage.clear()
}
四、各个文件夹下边的内容文字详细解释:
- node_modules
用来存放包管理工具下载的包的文件夹,当我们将项目拷贝给别人的时候,传输速度会很慢,所以传输项目一般不传输node_modules文件夹,可以根据package.json文件记录的信息通过执行npm install 下载当前依赖的第三方模块,生成node_modules文件夹
- src文件夹包含整个项目中所有需要包含的代码(脚手架生成的webpack配置项,只对src目录进行编译处理,其他目录是不处理的)
api 在开发项目时一般都是在src下创建一个文件夹api在里面对axios进行二次封装,组件化创建文件对应的页面在对应的文件下发请求,方便管理;
assets 放静态资源的比如:css文件,图片文件
components 主要存放自定义的一些组件文件
plugins 主要放配置文件,常用的放element.js
utils里面放公共方法
router 里面包含index.js文件,配置路由规则和挂载
views 项目自带的页面级组件
App.vue 当前页面的主要入口
main.js 项目入口(单页面一个入口,多页面多个入口)
3.editorconfig 格式化的配置
4.eslintrc.js 自己手动更改了一些规则,避免报错
5.babel.config.js 将高级语法转化为浏览器可以识别的低级语法
6.package-lock.json 记录本地下载依赖的版本
7.package.json项目描述文件,记录了当前项目信息,例如项目名称,版本,作者,GitHub地址;使用npm init -y 命令生成package.json
8.README.md 一些基本npm指令,可以修改
[
](https://blog.csdn.net/qq_45331969/article/details/110956989)