最近在写Uni,就是没有项目经验,然后摁着脑壳写的,js 学习是不可能学习的,vue 也没有看。反正就写呗,能出多大问题呢?是吧。
正文
按照之前Android 是思路,先把路由组件化,然后把路由服务化,既然这个玩意界面少,那我是不是直接一个class 就把路由跳转参数控制给约束了。于是我写了一个:
class PageRouter {
}
export default PageRouter;
类函数就是页面跳转及其控制。这很合理,这也很Android 不是吗?我还写了一个单例,把这个改造了一下,秀了一波js 的设计模式:
constructor() {
if (PageRouter.instance) {
return PageRouter.instance;
}
PageRouter.instance = this;
}
static getInstance() {
if (!PageRouter.instance) {
new PageRouter();
}
return PageRouter.instance;
}
这么写,非常符合面相对象,不是吗?写完就后悔了,一种极其恶心的感觉扑面而来,我每次路由跳转都要手动:
import PageRouter from '@/common/PageRouter.js';
不用吧,都特么写了,哭死,强行用。跳转的语法代码就及其的长:
PageRouter.getInstance().deviceShareSettingPage();
要开始长脑子了
这种代码看似简单,实则恶心,因为他不代码提示,你懂那种不提示的感受吗,我懂,我已经习惯了,我在调用uni的方法的时候,突然发现,这玩意是有提示的,为啥我的没有,为啥我的要手动导入啊!。ok,一检索,原来这个玩意是vue的特性,那么就开始改造。
01:main.js 中声明
找到main.js的时候,发现他其实是导入了vue的,所以我们只需要把PageRouter导入即可,然后设置prototype属性即可。
import PageRouter from "@/common/PageRouter.js";
Vue.prototype.$hRouter= PageRouter;
至于为什么叫hRouter,不叫router,因为叫router 应用白屏了,所以换一个名字。
02:使用
使用就简单了
this.$hRouter.getInstance().deviceShareSettingPage();
这个时候,面相class编程+单例的坏处就出现了,起码这个调用贼长,而且提示里面这个函数并不能直接识别成函数,小括号得自己加。所以,kotlin 那种面相函数编程是非常重要的,真的不建议uni 中使用类,而且js 设计模式里面全是依托于函数的demo,类demo其实不是太多。
留的坑
从上面的调用来看,其实很简单,主要是知识不够导致的。
为啥要写到main.js 中而不是 app.vue 中
我试了下都是可以的,vue对象应该属于全局的属性,所以是可以的,而且单例对象也保证了全局唯一,而main.js 是应用程序的入口,不仅导入了vue,同时也满足了先声明后使用的原则,而app.vue 也是可以的。
为啥叫router就白屏
因为有一个prototype叫router,我把原来的替换了,就不能用了。
vue 可以挂载为对象吗?
可以看到,上面写法的毒瘤在于是类+静态函数调用,所以我们能不能直接挂载一个类对象上去,而不是每次调用一次静态函数。我想这么写:
this.$hRouter.deviceShareSettingPage();
答案是可以的,我们再改动下vue挂载属性的方法:
Vue.prototype.$hRouter= PageRouter.getInstance();
所以,我写单例的意义是什么呢?当然是为了学习如何用JS写单例,而不是为了为难自己,对吧。
this.$ 可以省略不写吗?
在 Vue 中,当你使用
Vue.prototype.$hRouter
来设置全局属性时,你通常是为了在组件内部通过this.$hRouter
来访问这个属性。这里的this
关键字指的是 Vue 组件的实例。this.$hRouter
中的this
是必须的,因为它指代的是当前的 Vue 组件实例。没有this
,你就无法访问组件实例上的属性或方法。 <来源:文心一言>
可以看到,说不行,但是为啥uni 为啥可以,因为实现方式不同,uni虽然是全局对象,但是是挂载到window 上的,而我们是挂在vue 上面的,所以说挂载到vue 上是必须写的,挂载到window 上可以不写。
如何挂载到window上
那么我们在挂载vue的哪个地方继续写:
window.hRouter=PageRouter.getInstance();
使用:
hRouter.deviceShareSettingPage();
ok,贼完美,下播,下播。
结束
到这里,我们学会了如何挂载全局对象,从而避免了每次都手动写import 的烦恼,当然全局对象的缺点就是不是按需引入,对于这种工程,还是应该按需引入的,还有一个问题,为啥我自定义类的函数不提示出来,我还是得手动复制,难道得把类对象改成 函数文件才行吗,可恶。
原文链接:https://juejin.cn/post/7356860329697198143 作者:luoye呀