如何使用vuecli3.0搭建一个完整的vue项目全过程?

2026-04-11 08:591阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1204个文字,预计阅读时间需要5分钟。

如何使用vuecli3.0搭建一个完整的vue项目全过程?

最近新写了一个项目,记录下新建项目及坑处理过程。新人查看👉1. 搭建脚手架:cnpm install @vue/cli -g vue create test 2. 添加ESLint:在package.json中添加rules,具体配置参考(https://www.)

最近新写一个项目,记录下新建项目过程及坑处理。供新人查看~

如何使用vuecli3.0搭建一个完整的vue项目全过程?

1 搭建脚手架

cnpm install @vue/cli -g vue create test 2 加入eslint

  1. package.json中加入rules,具体的rules配置从这里找(www.cnblogs.com/webhmy/p/14776124.html)适合自己项目的配置项

  2. vue.config.js中配置编译的时候lint代码

lintOnSave: true, // 编译的时候lint代码 3 加入tslint

vue项目中加入tslint

4 添加githooks

因为多人开发,很多人不会carelint的错误,因此在提交前统一自动化执行lint

cnpm install yorkie --save-dev cnpm install lint-staged --save-dev

在package.json中配置

"gitHooks": { "pre-commit": "lint-staged" }, "lint-staged": { "*.{js,vue}": [ "vue-cli-service lint", "git add" ] } 5 路由管理 vue-router

npm install vue-router

main.ts

import App from './App.vue' import router from './router' Vue.config.productionTip = false new Vue({ router, render: (h) => h(App) }).$mount('#app')

route -index.ts

import Vue from 'vue' import VueRouter, { RouteConfig } from 'vue-router' Vue.use(VueRouter) const asyncFiles = require.context('./routeModules', true, /\.ts$/) let permissionModules: Array<RouteConfig> = [] asyncFiles.keys().forEach((key) => { permissionModules = permissionModules.concat(asyncFiles(key).default) }) const routes: Array<RouteConfig> = [ { path: '/', redirect: '/home' }, ...permissionModules ] const router = new VueRouter({ routes }); export default router; 6 状态管理vuex

npm install vuex

main.ts

import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' Vue.config.productionTip = false new Vue({ router, store, render: (h) => h(App) }).$mount('#app')

store.ts

import Vue from 'vue' import Vuex from 'vuex' const states = {}; const contexts = require.context('./stateModules', true, /\.ts$/); contexts.keys().forEach(key => { let name = key.slice(2, -3); states[name] = contexts(key).default || contexts(key); }) Vue.use(Vuex) export default new Vuex.Store({ modules: { ...states } })

common.ts

const module = { state: () => ({ count: 1 }), mutations: { increment(state) { // 这里的 `state` 对象是模块的局部状态 state.count++ } }, actions: { batchincrement({commit}){ commit('someMutation') // -> 'foo/someMutation' commit('someMutation', null, { root: true }) // -> 'someMutation' } } } export default module

模块中使用

this.$store.state.common.count this.$store.commit('increment') this.$store.dispatch('batchincrement') 7 加入iview-design

cnpm install view-design --save

main.ts

import 'view-design/dist/styles/iview.css' /** * 按需引入iview * 常用的按需引入, 不常用的组件里单独引入 */ import { Button, Table } from 'view-design'; Vue.component('Button', Button); Vue.component('Table', Table);

借助插件 babel-plugin-import可以实现按需加载组件,减少文件体积。首先安装,并在文件 .babelrc 中配置:

npm install babel-plugin-import --save-dev

// .babelrc { "plugins": [["import", { "libraryName": "view-design", "libraryDirectory": "src/components" }]] } 8 配置axios

cnpm install axios --save

http index.ts

import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import { Message } from 'view-design'; import store from '../store' const $Message: any = Message; class Interceptors { public instance: any; constructor(baseURL?: string) { // 创建axios实例 this.instance = axios.create({ baseURL: baseURL ? baseURL : '/' }); // 初始化拦截器 this.initInterceptors(baseURL); } public initInterceptors(baseURL?: string): void { this.instance.defaults.withCredentials = true; // 请求拦截器 this.instance.interceptors.request.use((config: AxiosRequestConfig): AxiosRequestConfig => { const token = localStorage.userToken; if (token) { config.headers.Authorization = token; } return config; }, (error: any) => { // 关闭全局loading $Message.success(error.desc); return Promise.reject(error) }); // 响应拦截器 this.instance.interceptors.response.use((Response: AxiosResponse<any>) => { const { data } = Response; const { retcode, desc } = data; if ((retcode === '000000' || retcode === undefined) || (Response.config as any).isBolb) { return Promise.resolve(Response.data); } else if (retcode === '401' || retcode === '200008') { $Message.error('无权限,请重新登录!'); } else { // ainote token失效 if (data === 'Not Authorized') { $Message.error(data); window.open('/') } else { if (desc) $Message.error(desc); return Promise.reject(Response.data); } } }) } public getInterceptors() { return this.instance; } } interface ResponseOptions { config: object; data: { retcode: string; desc: string; [propName: string]: any; }; status: number; headers: object; [propName: string]: object | number | string | []; } interface ApiOptions { url: string; // 请求链接 params?: object; // 请求参数 method: string; // 请求方法 headers?: object; // 请求头 [keyName: string]: any;// 其他参数 } export class HttpService { public axios: any; public baseURL: any; constructor(baseURL?: string) { this.baseURL = baseURL; this.axios = new Interceptors(baseURL).getInterceptors(); } /** * 通用请求 * @param {ApiOptions} options 请求参数 */ public fetch(options: ApiOptions): Promise<object> { return new Promise((resolve, reject) => { this.axios(options).then((res: ResponseOptions) => { resolve(res); }).catch((err: ResponseOptions) => { // 请求出错处理todo if (err && err.response) { const data = (err.response as any).data || {}; switch ((err.response as any).status) { case 401: $Message.error('没有权限,请重新登录'); localStorage.clear(); break; case 400: $Message.error(data.message || data.desc || '请求出错'); break; case 404: $Message.error(data.message || '请求出错'); break; case 503: $Message.error(data.message || '服务器异常'); break; default: $Message.error(data.message || '服务器异常'); break; } } reject(err); }) }) } }

引用

/** * 首页接口请求 */ import { HttpService } from '@/http'; const $HttpService: any = new HttpService('/'); // get 请求 export const getBusinessSceneList = (params) => { return $HttpService.fetch({ url: '/api/business/scene/list', method: 'get', params }); } // post 请求 export const createBusinessScene = (data) => { return $HttpService.fetch({ url: '/api/business/scene', method: 'post', data }); }

本文共计1204个文字,预计阅读时间需要5分钟。

如何使用vuecli3.0搭建一个完整的vue项目全过程?

最近新写了一个项目,记录下新建项目及坑处理过程。新人查看👉1. 搭建脚手架:cnpm install @vue/cli -g vue create test 2. 添加ESLint:在package.json中添加rules,具体配置参考(https://www.)

最近新写一个项目,记录下新建项目过程及坑处理。供新人查看~

如何使用vuecli3.0搭建一个完整的vue项目全过程?

1 搭建脚手架

cnpm install @vue/cli -g vue create test 2 加入eslint

  1. package.json中加入rules,具体的rules配置从这里找(www.cnblogs.com/webhmy/p/14776124.html)适合自己项目的配置项

  2. vue.config.js中配置编译的时候lint代码

lintOnSave: true, // 编译的时候lint代码 3 加入tslint

vue项目中加入tslint

4 添加githooks

因为多人开发,很多人不会carelint的错误,因此在提交前统一自动化执行lint

cnpm install yorkie --save-dev cnpm install lint-staged --save-dev

在package.json中配置

"gitHooks": { "pre-commit": "lint-staged" }, "lint-staged": { "*.{js,vue}": [ "vue-cli-service lint", "git add" ] } 5 路由管理 vue-router

npm install vue-router

main.ts

import App from './App.vue' import router from './router' Vue.config.productionTip = false new Vue({ router, render: (h) => h(App) }).$mount('#app')

route -index.ts

import Vue from 'vue' import VueRouter, { RouteConfig } from 'vue-router' Vue.use(VueRouter) const asyncFiles = require.context('./routeModules', true, /\.ts$/) let permissionModules: Array<RouteConfig> = [] asyncFiles.keys().forEach((key) => { permissionModules = permissionModules.concat(asyncFiles(key).default) }) const routes: Array<RouteConfig> = [ { path: '/', redirect: '/home' }, ...permissionModules ] const router = new VueRouter({ routes }); export default router; 6 状态管理vuex

npm install vuex

main.ts

import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' Vue.config.productionTip = false new Vue({ router, store, render: (h) => h(App) }).$mount('#app')

store.ts

import Vue from 'vue' import Vuex from 'vuex' const states = {}; const contexts = require.context('./stateModules', true, /\.ts$/); contexts.keys().forEach(key => { let name = key.slice(2, -3); states[name] = contexts(key).default || contexts(key); }) Vue.use(Vuex) export default new Vuex.Store({ modules: { ...states } })

common.ts

const module = { state: () => ({ count: 1 }), mutations: { increment(state) { // 这里的 `state` 对象是模块的局部状态 state.count++ } }, actions: { batchincrement({commit}){ commit('someMutation') // -> 'foo/someMutation' commit('someMutation', null, { root: true }) // -> 'someMutation' } } } export default module

模块中使用

this.$store.state.common.count this.$store.commit('increment') this.$store.dispatch('batchincrement') 7 加入iview-design

cnpm install view-design --save

main.ts

import 'view-design/dist/styles/iview.css' /** * 按需引入iview * 常用的按需引入, 不常用的组件里单独引入 */ import { Button, Table } from 'view-design'; Vue.component('Button', Button); Vue.component('Table', Table);

借助插件 babel-plugin-import可以实现按需加载组件,减少文件体积。首先安装,并在文件 .babelrc 中配置:

npm install babel-plugin-import --save-dev

// .babelrc { "plugins": [["import", { "libraryName": "view-design", "libraryDirectory": "src/components" }]] } 8 配置axios

cnpm install axios --save

http index.ts

import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import { Message } from 'view-design'; import store from '../store' const $Message: any = Message; class Interceptors { public instance: any; constructor(baseURL?: string) { // 创建axios实例 this.instance = axios.create({ baseURL: baseURL ? baseURL : '/' }); // 初始化拦截器 this.initInterceptors(baseURL); } public initInterceptors(baseURL?: string): void { this.instance.defaults.withCredentials = true; // 请求拦截器 this.instance.interceptors.request.use((config: AxiosRequestConfig): AxiosRequestConfig => { const token = localStorage.userToken; if (token) { config.headers.Authorization = token; } return config; }, (error: any) => { // 关闭全局loading $Message.success(error.desc); return Promise.reject(error) }); // 响应拦截器 this.instance.interceptors.response.use((Response: AxiosResponse<any>) => { const { data } = Response; const { retcode, desc } = data; if ((retcode === '000000' || retcode === undefined) || (Response.config as any).isBolb) { return Promise.resolve(Response.data); } else if (retcode === '401' || retcode === '200008') { $Message.error('无权限,请重新登录!'); } else { // ainote token失效 if (data === 'Not Authorized') { $Message.error(data); window.open('/') } else { if (desc) $Message.error(desc); return Promise.reject(Response.data); } } }) } public getInterceptors() { return this.instance; } } interface ResponseOptions { config: object; data: { retcode: string; desc: string; [propName: string]: any; }; status: number; headers: object; [propName: string]: object | number | string | []; } interface ApiOptions { url: string; // 请求链接 params?: object; // 请求参数 method: string; // 请求方法 headers?: object; // 请求头 [keyName: string]: any;// 其他参数 } export class HttpService { public axios: any; public baseURL: any; constructor(baseURL?: string) { this.baseURL = baseURL; this.axios = new Interceptors(baseURL).getInterceptors(); } /** * 通用请求 * @param {ApiOptions} options 请求参数 */ public fetch(options: ApiOptions): Promise<object> { return new Promise((resolve, reject) => { this.axios(options).then((res: ResponseOptions) => { resolve(res); }).catch((err: ResponseOptions) => { // 请求出错处理todo if (err && err.response) { const data = (err.response as any).data || {}; switch ((err.response as any).status) { case 401: $Message.error('没有权限,请重新登录'); localStorage.clear(); break; case 400: $Message.error(data.message || data.desc || '请求出错'); break; case 404: $Message.error(data.message || '请求出错'); break; case 503: $Message.error(data.message || '服务器异常'); break; default: $Message.error(data.message || '服务器异常'); break; } } reject(err); }) }) } }

引用

/** * 首页接口请求 */ import { HttpService } from '@/http'; const $HttpService: any = new HttpService('/'); // get 请求 export const getBusinessSceneList = (params) => { return $HttpService.fetch({ url: '/api/business/scene/list', method: 'get', params }); } // post 请求 export const createBusinessScene = (data) => { return $HttpService.fetch({ url: '/api/business/scene', method: 'post', data }); }