概述
本篇文章以开发阶段为导向,对租房项目进行剖析,复盘、总结开发中的常用功能、开发思路等。
在项目初始化阶段:
-
目录是整个项目的框架结构,完整、合理、清晰的目录结构,会成为开发者的有效抓手。参考相对标准的目录结构,可以使我们的开发思路更加逻辑化、更加清晰。
-
安装包与vue2版本不适配会导致后台报错、浏览器无法正常加载页面,因此需注意版本适配性。
-
安装包的初始化配置可参考官网的快速上手进行逐步配置。
一、 项目初始化阶段
1、文件夹目录结构
以下为vue2项目中相对完成的标准化目录结构。
├── mock # 项目mock 模拟数据
├── public # 静态资源
│ │── favicon.ico # favicon图标
│ └── index.html # html模板
├── src # 源代码
│ ├── api # 所有请求
│ ├── assets # 主题 字体等静态资源
│ ├── components # 全局公用组件
│ ├── icons # 项目所有 svg icons
│ ├── layout # 全局 layout
│ ├── router # 路由
│ ├── store # 全局 store管理
│ ├── styles # 全局样式
│ ├── utils # 全局公用方法
│ ├── vendor # 公用vendor
│ ├── views # views 所有页面
│ ├── App.vue # 入口页面
│ ├── main.js # 入口文件 加载组件 初始化等
│ └── permission.js # 权限管理
│ └── settings.js # 配置文件
├── tests # 测试
├── .env.xxx # 环境变量配置
├── .eslintrc.js # eslint 配置项
├── .babelrc # babel-loader 配置
├── .travis.yml # 自动化CI配置
├── vue.config.js # vue-cli 配置
├── postcss.config.js # postcss 配置
└── package.json # package.json
1.1、package.json文件:
记录安装包的版本
1.2、public文件夹:
index.html是项目的最终入口,也是浏览器加载的页面,我们书写的所有代码,经过webpack的打包处理以后,都会被添加至本文件中。
1.3、src文件夹:
项目开发的源代码。
1.3.1、 main.js文件
webpack打包的主入口,我们一般将App.vue、css、router、store等引入该文件进行打包处理,并以script标签的形式添加至public-->index.html文件。
1.3.2、 App.vue文件
所有vue单页面组件的入口,我们在项目中书写的所有vue单页面组件,都需要被直接或者间接的引入到该文件。vue单页面组件,一般分为页面组件和功能组件。
1.3.3、views文件夹
用于存放页面组件,该类组件通常是经路由跳转的方式来实现显示或隐藏。
1.3.4、components文件夹
用于存放功能组件,该类组件通常是在文件中使用components注册为标签使用
1.3.5、store文件夹
用于存放Vuex的文件,是状态管理的核心文件,我们通过其中的modules、state、mutation、actions、getters等,实现数据的请求、存储和管理。
1.3.6、router文件夹
用于存放路由相关文件,我们通常用其对路由规则进行设置。
1.3.7、layout文件夹
用于存放项目的框架页面,通常在框架页面中设置<router-view></router-view>
标签,实现不同页面的动态切换。
1.3.8、utils文件夹
用于存放全局的公用方法,例如,我们通常对axios进行二次封装,并存放于该文件夹中。
1.3.9、api文件夹
用于存放发送Ajax请求的文件,这些方法将被导入到store-->actions中用于获取数据。
2、安装包版本与vue2适配性
本项目使用Vue2进行开发,主要依赖的安装包如下:
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@vue/devtools-api": "^6.2.0",
"axios": "^0.27.2",
"core-js": "^3.8.3",
"less": "^4.1.3",
"less-loader": "^11.0.0",
"vant": "^2.12.48",
"vue": "^2.6.14",
"vue-router": "3",
"vuex": "3",
"vuex-persist": "^3.1.3"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"babel-plugin-import": "^1.13.5",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"unplugin-vue-components": "^0.21.0",
"vue-template-compiler": "^2.6.14"
},
由于在使用 yarn add 安装包名
安装依赖包的时候,会默认安装最新版本,但是部分最新的安装包对于Vue2并不适配,因此会出现如下报错(以在Vue2中安装最新版的Vuex为例):
浏览器中报错如下
后台报错如下
在使用 yarn add vuex@3
命令,安装指定适配版本的Vuex之后,问题解决。
3、安装包的初始化配置
3.1、axios
axios是一个基于 promise 的网络请求库,可以用于浏览器和 node.js。我们在开发的时候,通常对其进行二次封装处理,并通过Vuex中的action发送数据请求。axios中文文档:
3.1.1、终端安装
在终端使用yarn的命令安装指定版本
$ yarn add axios@^0.27.2
3.1.2、二次封装
路径:src/utils/index.js文件
//引入axios模块
import axios from 'axios'
//获取token(如果没有token需求,可忽略。后续将使用其他方法进行优化)
const token = JSON.parse(window.localStorage.getItem('vuex')).token
//创建axios实体化对象
const request = axios.create({
//配置请求的基础路径(后续将优化)
baseURL: 'http://********/',
})
// 设置请求拦截器(如果没有token需求,可忽略)
request.interceptors.request.use(
function (config) {
//如果获取到token,则将其添加至请求头
if (token) {
config.headers = {
authorization:token
}
}
return config
}, function (error) {
console.log('启动拦截器');
}
)
//默认导出axios对象
export default request
3.1.3、创建请求文件
路径:src/api/login.js文件
//引入二次封装的axios请求对象
import request from '@/utils';
//创建并导出发送请求的login函数
export const login = (data) => {
return request({
url: "/user/login",
method: "POST",
data
})
}
3.1.4、统一导入、导出请求接口(便导入接口)
路径:src/api/index.js文件
//按需导入请求接口
import { login } from '@/api/login.js'
import { getUserInfo } from '@/api/my.js'
//按需导出请求接口
export const loginAPI = login
export const getUserInfoAPI = getUserInfo
3.1.5、使用axios发起请求
路径:src/view/login/index.vue文件
//此处仅在vue文件中,演示接口函数的用法,实际开发通常在store的action中发起异步请求(参照3.2.2)
<script>
//引入请求接口
import { loginAPI } from '@/api/index.js'
export default {
//创建异步函数,用于发起请求
async onSubmit (values) {
//通过async和await解决异步问题
const res = await loginAPI(values)
}
}
</script>
思路复盘
stateDiagram-v2
安装axios -->二次封装axios
二次封装axios --> 模块化请求文件中使用
模块化请求文件中使用 --> 统一导入、导出
统一导入、导出 --> 单页面中发请求
3.2、Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。Vuex中文文档(V3.x版)
3.2.1 终端安装
在终端使用yarn的命令安装指定版本
$ yarn add vuex@3
3.2.2 封装存储模块
按照功能页面,将数据封装成若干个独立模块,便于数据的管理和维护。
路径:src/store/modules/login.js文件
//引入请求接口文件
import { loginAPI } from '@/api/index.js'
//创建store对象内的state、mutations、ation
const state ={
token: '',
userID: null
}
const mutations ={
setToken (state, payLoad) {
state.token = payLoad
},
setUserID (state, payLoad) {
this.state.userID = payLoad
},
}
const action = {
async login (context,value) {
//res.data.body.token是根据拿到响应数据的结构而确定
//context相当于当前文件的父级文件
const res = await loginAPI(value)
context.commit('setToken', res.data.body.token)
}
}
// 默认导出
export default {
//开启独立的命名空间
namespaced: true,
//此处为上文中定义的数据,属性名与属性值同名,因此简写
state,
mutations,
actions
}
3.2.3 封装getters模块
通过getters将所有模块中的数据做统一的映射处理,防止不同数据模块之间命名冲突。
路径:src/store/getters.js文件
//统一按需导出getters
export const getters = {
//建立映射关系,便于在页面中使用(页面中通常搭配mapState辅助函数使用)login为模块名称
token: state => state.login.token,
userID: state => state.login.userID,
}
3.2.4 创建Store实例化对象
路径:src/store/index.js文件
//引入Vue及Vuex
import Vue from 'vue'
import Vuex from 'vuex'
//引入独立封装的存储模块(被引入的模块在3.2.2中详述)
import login from '@/store/modules/login.js'
//引入独立的getters文件(被引入的模块在3.2.3中详述)
import {getters} from '@/store/getters.js'
//注册为全局引用
Vue.use(Vuex)
//创建Store对象
const store = new Vuex.Store({
//此处getters的属性名与属性值相同,因此简写
getters,
//模块化中的属性名与属性值相同,因此简写
modules: {
login,
},
})
//默认导出store实例对象
export default store
3.2.4 将store挂载到Vue对象
路径:src/main.js文件
import Vue from 'vue'
import App from './App.vue'
//引入store实例对象
import store from '@/store/index.js'
Vue.config.productionTip = false
//将store挂载到Vue实例对象上
new Vue({
store,
render: h => h(App),
}).$mount('#app')
3.2.5 使用Vuex中的数据
路径:src/view/login/index.vue文件
<template>
//点击按钮,调用get方法,发送登录请求
<button @click="get">发起请求</button>
</template>
<script>
//引入辅助函数mapGetters
import { mapGetters } from 'vuex'
export default {
methods: {
//自定义的get方法
get () {
//调用login存储模块中名为getTokens的action发起异步登录请求
const res = this.$store.dispatch('login/getTokens')
}
},
computed: {
//在computed中解构getters或者state获取store中的数据
...mapGetters(['token'])
},
}
</script>
<style lang="css" scoped>
</style>
思路复盘
stateDiagram-v2
安装Vuex -->创建store实例
封装存储模块 --> 创建store实例
封装getters模块 --> 创建store实例
创建store实例--> 挂载到Vue实例
挂载到Vue实例-->使用数据
使用数据
3.3、vuex-persist
vuex-persist是一个支持 Typescript 的Vuex插件,使您能够将应用程序的状态保存到持久存储中,例如 Cookies 或 localStorage。npm中vuex-persist的文档:
3.3.1、终端安装
$ yarn add vuex-persist@3.1.3
3.3.1、配置参数
路径:src/store/index.js文件
import Vue from 'vue'
import Vuex from 'vuex'
//引入 VuexPersistence
import VuexPersistence from 'vuex-persist'
Vue.use(Vuex)
//创建VuexPersistence实例,配置存储方式为localStorage(后续通常使用cookie存储)
const vuexLocal = new VuexPersistence({
storage: window.localStorage
})
const store = new Vuex.Store({
state: {},
mutations: {},
getters: {},
actions: {},
modules: {},
//将vuex-persist配置到store对象内
plugins: [vuexLocal.plugin]
})
export default store
3.4、vue-router
Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。vue-router@3中文文档
3.4.1、终端安装
$ yarn add vue-router@3
3.4.2、创建路由对象
路径:src/router/index.js文件
import Vue from 'vue'
//引入vue-router
import VueRouter from 'vue-router'
// 引入组件
import Layout from '@/view/layout/index.vue'
import Main from '@/view/main/index.vue'
//将vue-router注册为全局使用
Vue.use(VueRouter)
//配置路由规则
const routes = [
//框架页面
{
path: '/',
redirect: '/main',
component: Layout,
//二级子路由
children: [
{
path: '/main',
component: Main
},
]
},
]
//创建路由对象,并采用历史模式(路径中没有'#')
const router = new VueRouter({ routes, mode: 'history' })
//此处亦可根据需要配置路由守卫
//导出路由对象
export default router
3.4.3、挂载到Vue对象
路径:src/main.js文件
import Vue from 'vue'
import App from './App.vue'
//引入路由对象
import router from '@/router/index.js'
Vue.config.productionTip = false
new Vue({
//挂载到Vue对象
router,
store,
render: h => h(App),
}).$mount('#app')
至此,我们就完成项目初始化阶段的工作,接下来我们会借助vant组件库来进行页面开发,详见下一篇文章。