先说说写这个项目的动机。以前工做的时候,虽然作过很多项目,可是由于签了保密协议,无法把代码放出来。后来跳槽的时候,拿不出一个完整的我的项目,只能把平时写的一些小demo拿出来遛遛。因此打算写一个本身的项目。
这个项目仿的是“米丫天气”APP。也不知道会不会侵权,反正先放上来再说。功能部分其实很简单,只是通常的数据获取,还有用户管理这一块的功能。主要是经过这个项目来练习一个完整的项目所须要考虑到的地方。例如:项目文件架构,逻辑组件和公共组件应该如何安排;vuex部分该怎样划分和组合;router部分该怎样配置;前台和后台应该若是关联。
目前项目还有很多bug,先发了,后面再慢慢优化。
这篇文章将把我作这个项目的过程和一些想法描述出来,给本身总结一下。固然,若是能够帮助到也在写vue的朋友就更好了。
按字母顺序vue
这里稍微提一下css的解决方案。
以前一直都在使用sass,只是node-sass很难安装成功,因此就改用stylus。二者的差异我感受不是很大。另外是.vue
文件中的style
部分,即便添加scoped
属性,仍是会有可能发生冲突。例如父子组件的样式中都拥有同一个类名,这时就会发生冲突。目前正在打算准备使用css-modules
。
对于路由,各位写过vue的朋友应该都不陌生了。这里主要讲一下路由的结构,我把它理解为“分层”,也就是router-view
组件的位置。以前在看一个ui框架的时候(忘了是啥框架了),留意到它的页面分层的概念。大概是这样的:
1.遮罩层(loading之类的) 2.交互层(模态框什么的) 3.消息提示层(本项目中的toast组件) 4.主内容界面 5.嵌套的子路由
目前就只想到这些了。node
另外是router.js
文件的写法。在本项目中,我把全部的路由写在同一个文件,是由于路由比较少,若是在路由结构多而复杂的项目,这种写法会很头疼。建议的写法是将各个逻辑模块的路由分开,最后在主路由里引入。大概是这样的:react
// router/module-a.js const View1 = () => import('@/view/view-1') const View2 = () => import('@/view/view-2') export default [ { path: '/home/module-a/view-1', name: 'view-1', component: View1 }, { path: '/home/module-a/view-2', name: 'view-2', component: View2 } ]
// router/index.js import Vue from 'vue' import Router from 'vue-router' import ModuleA from './module-a' Vue.use(Router) const router = new Router({ routes: [ ...ModuleA ] }) export default router
噢,对了。以前还在sf
找到一个小技巧:如何在切换路由时,修改浏览器标签的标题。ios
router.beforeEach((to, from, next) => { window.document.title = to.meta.title || '米丫天气' next() })
注意:我试过把title
写在路由属性中而不是meta
里,发现是不可行(多写一层也没啥大问题)。git
在项目的store里面,只有modules
,没有根层的state,这个主要是受redux的一些影响吧。把全部须要缓存的数据放在一个store树里面,每一个模块单独控制。另外在store/index.js
里面会看到setState
这个方法。这个也是受react的影响(this.setState 方法),也是一个小技巧吧。vuex里面提到mutations
只处理同步的操做,actions
处理异步操做。那么基本上每一个action
都会commit
一个或者多个mutation
。而mutation
是应该只修改一个state
仍是多个?这个问题根据不一样的业务逻辑会有不一样的结果。因此定义了setState
这个通用的方法。至于action的写法,本项目里的写法我感受仍是有点问题的。下面是最近找到的关于async
函数的写法:web
async function getSomething() { try{ const result = await apiGetSomething() if(result.status === 'ok') { // some code } } catch(err) { console.error(err) } }
关于这种写法目前还在思考中,后续会进行修改。vue-router
上述提到的action
里使用到请求数据的api方法。api方法都会返回一个promise
对象,同时也是一个异步函数。
说到api就要提一下easy-mock。这个网站是基于mock.js
,能够很方便生成自定义接口,就算你不会后台,也能够很快速简单的编辑本身想要的接口。使用方法嘛,仍是直接看官方教程吧。
由于本项目要使用的数据比较简单,因此接口部分没有什么好说的了。vuex
assets
部分的图标会被看成依赖,引用的时候使用import
引入,而后还不能直接使用,必须放到配置项里面,通常是放在data
。
而后是style
,这里主要是配置全局样式变量,例如主题色之类的。
具体方法:
在build/utils.js的generateLoaders
中修改.
添加全局变量的文件配置redux
const stylusOptions = { import: [path.join(__dirname, '../src/assets/style/theme.styl')], paths: [path.join(__dirname, '../src/assets/style/'), path.join(__dirname, '../')] }
其中的theme.styl
定义全局变量的文件
修改stylus
的配置
stylus: generateLoaders('stylus', stylusOptions), styl: generateLoaders('stylus', stylusOptions)
基本上我把能够单独提出来的内容都写成公共组件。另外单独写了一个index.js
文件。里面将全部的公共组件引入而后打包导出,这样在使用的时候就能够少写不少代码,这个技巧是以前看vux-ui
里面的组件定义学到的。
// components/index.js const TabBar = () => import('./TabBar') const AddressBar = () => import('./AddressBar') const TmpPanel = () => import('./TmpPanel') // ... export { TabBar, AddressBar, TmpPanel //... }
// 逻辑页面引入 import { TabBar, AddressBar, TmpPanel } from '@/components'
待续。。。