了解熟悉产品需求(非常重要!!!)
之前一直做前端开发都是由后端主导推动开发和测试,甚至在产品需求的理解上我一直也是比较依赖跟后端的对接过程中才去了解的更为详细,或者和产品经理及时沟通。总体来说是比较被动的一方,然后这次开发移动端的需求时候,我明显感受到了自己对产品原型的理解不是很充分,然后直接影响到了我设计项目和代码编写的臃肿性,因为很多问题都是在写完了测试的时候才发现自己考虑的不够周全,然后会多写很多无用的东西,包括代码习惯问题。下面就记录一下需要提升的地方吧
项目代码设计
主要针对VUE2.0 因为目前项目使用的仍然是VUE2版本
- directive 注册全局钩子 v-throttle v-debouce v-lazy 等封装使用 示例:
directive/index.js
import Vue from 'vue'
import { throttle } from '@/utils'
Vue.directive('throttel', {
bind(el, binding) {
let execFunc
// 当绑定的函数带有参数,则binding.value是一个数组
if(binding.value instanceof Array) {
const [ func, time = 500] = binding.value
execFunc = throttle(binding.value, 500)
} else {
// 当仅仅绑定一个函数名,则binding.value就是一个函数名
execFunc = throttle(binding.value, 500)
}
el.addEventListener('click',execFunc)
}
})
然后在main.js 中 直接 import '@/directive'即可
使用方法 <el-button v-throttle='clickFn'></el-button>
- filters 全局过滤器注册 账号类脱敏 多使用正则 注意零宽断言不兼容IOS的问题 filter/index.js
export default {
// 手机号脱敏
phoneDesen(val) {
if(!val) return
const reg = /(\d{3})\d*{\d{4}}/
const str = val.replace(reg, '$1****$2')
return str
}
// 时间date处理 YYYYMMDD - YYYY-MM-DD
datePeriod(time) {
if(!time) return
const reg = /^(\d{4})(\d{2})(\d{2})$/
return time.replace(reg, '$1-$2-$3')
}
// 银行账户每四位显示空格
dealBankCount(val) {
if(!val) return
let str = ''
for(let i = 0; i<val.length;i++) {
if(i%4 ===0 && i>0) {
str = str + ' ' + val.charAt(i)
}else {
str = str + val.charAt(i)
}
}
return str
}
}
全局注册 main.js
import filters from '@/filter'
Object.keys(filters).forEach(k=>{
Vue.filter(k, filters[k])
})
-
mixins 使用 一般抽离公共类的接口调用 为防止生命周期顺序问题 建议mixins中仅提供methods方法 不要在创建时候调用
-
css类 一般写H5项目的时候UI设计会遵循一定的规则来设计样式文字展示等 我们需要做的就是提取相同的设计 然后在全局直接写好常用的class类名和css 特别注意在复制UI图上的css代码时候 注意删除height属性或者使用min-height。
assets/style
index.scss
@import "styles.scss" // 存放通用样式 注意使用 变量全局替换样式 scss中使用$ less中使用 @
@import "color.scss" // 存放通用color样式
@import "var.scss" // 存放scss变量类型
使用 main.js 中 import "@/assets/style/index.scss"
- vuex的使用
vuex中 modules/index.js
const state = {
key: value // 变量定义
info: null
}
// mutations变例注册更改state中key的方法 commit('setKey', payload) 注意mutations中 (state, payload)的使用
const mutations = ()=>{
const methods = {}
for(let i in state) {
const setKey = key.substring(0, 1).toLocaleUpperCase() + key.substring(1)
methods['set'+ setKey] = (state, payload) => {
state[key] = payload
}
}
}
// 等效computed
const getters = {
key: state => state.anotherKey
}
// 调用异步方法
const action = {
getInfo({commit, state}) { // const {commit, state } = context context与store具有相同的属性和实例 正常是context.commit/store.commit 解构后可以直接调用commit
return new Promise(async (resolve, reject)=>{
try {
const res = await func()
const { info } = res
commit('setKey', info)
} catch(err) {
reject()
}
})
}
}
// vue中使用
this.$store.dispatch('getInfo')
await Promise.all([store.dispatch('getInfo')])
const { info} = this.$store.state.mouduleName
export default {
state,
mutations: mutations(),
getters,
actions
}
- beforeRouteEnter的使用。对于逻辑比较复杂的跳转处理我们可以在router钩子中进行拦截跳转,然后使用mixins在相关vue页面中引用 避免页面代码过于臃肿
import { checkInfo } from "@/api"
export default {
async beforeRouteEnter(to, from, next) {
try {
const res = await checkInfo()
if(res) {
return next ('/path')
} else {
return next(false) // next中写false 可以阻止next自动往下找next出口
}
return next()
} catch(e=>{
})
}
}