首先
不知不觉,已经从事开发3年多了,从一个小白,到能自己独立做些事情。先学习了前端,一开始是html/js/css然后是jquery,再而是vue全家桶、ts等;接着公司需要,自学了Java,springboot,mysql,rabbitmq等等后端技术,然后又有做小程序和APP的需求,继而学习了uniapp。不得不说,初创小公司非常锻炼人,你得什么都要会一些才好,但风险也很大,没那么稳定。现在也考虑不了那么多,只能多做点事,希望自己能再提升一些。
这里记录自己遇到问题,总结经验,希望自己能走的更远。
问题
过去写请求相关代码的时候,总是很难受。因为我总是需要预先在data中定义一个变量,接着在methods中定义一个方法,然后在方法中写一个请求,最后来处理请求的返回值并控制加载的状态。
例如这样一个普通的定义请求的js文件
import { request } from '你封装的axios'
// 比如: user.js 文件
export const create = (data) => request({ method: 'POST', url: '/xxx/xxx', data })
以前可能是这样处理的
import { create } from 'xxx/user'
export default {
data() {
return {
value: {}
loading: false
}
},
methods: {
// 这样
fetchCreate1() {
this.loading = true
return create(param)
.then((res)=>{
// 处理返回值
})
.catch((err)=>{
// 处理异常
})
.finally(()=>{
this.loading = false
})
},
// 或者这样
async fetchCreate2() {
try {
this.loading = true
const res = await create(param)
// 处理返回值
} catch(err) {
// 处理异常
} finally {
this.loading = false
}
},
// 还写过这种
async fetchCreate3() {
this.loading = true
const [ err, res ] = await create(param)
if(err) {
// 处理异常
}
// 处理返回值
this.loading = false
}
},
mounted() {
// 调用函数
this.fetchCreate3()
}
}
解决方案
想着如果每一个函数都得自己处理异常,并且处理接口返回值,感觉太麻烦了,如果能做到声明请求,就能一次性做完,岂不美哉。所以现在写一个hook来处理一下请求
import { computed, ref } from 'vue'
import { message } from 'ant-design-vue'
import { nanoid } from 'nanoid'
export const useDynamicFetch = (fn, silent = false) => {
const data = ref()
const id = nanoid()
const loading = ref(false)
const flag = ref(false)
const run = async (...args) => {
loading.value = true
flag.value = false
try {
const response = await fn(...args)
data.value = response
flag.value = true
} catch(ex) {
const msg = ex.message ?? 'other error'
if(!silent) {
message.error({content: msg, key: id})
}
flag.value = false
} finally {
loading.value = false
}
return flag.value
}
return {
data,
run,
loading: computed(() => loading.value)
flag: computed(() => flag.value),
id
}
}
结果
现在变成了这样,感觉好多,终于看不到回调,也看不到try/catch了, nice!
import { create } from 'xxx/user'
import { useDynamicFetch } from '@/hooks/xxxxx'
export default defineComponent({
setup() {
const data = ref();
const param = {}
const { data, run, loading, id } = useDynamicFetch(create)
const initComponents = async () => {
if(await run(param)) {
// todo
message.success({ content: 'success', key: id })
}
}
onMounted(() => initComponents())
return {
data,
loading // 可以直接给一些需要加载状态的组件使用
}
}
})
大功告成!
其他
不过vue2.7以前的版本,应该是用不了。如果有勇气有时间,也可以把项目vue版本升级到2.7+,这样就可以在vue2中使用vue3的部分能力,官方也提供了一个比较好的流程, 文档地址
(如果没有历史负担,个人还是很推荐使用 vue3 + ts + vite 来开发,实在太香了)