vue组件中,methods中只能定义函数,有时在开发过程中,一个组件的功能会比较多,导致定义了一堆的函数。这种情况下,methods里堆放了多个函数,占空间不说,调试时找起某个函数也不容易。今天介绍一个技巧来整理methods中的函数,让你的代码思路清晰,整洁清爽。
归类整理
思路就是把罗列堆集的多个函数进行分组,将业务相关的函数集中在一起统一输出。函数其实也是个对象,在js里一切皆是对象。那我就可以定义一个对象,返回这一套业务相关函数就可以了。
本文的例子是一个图片播放功能,就是把一堆图片按照一定顺序播放,有播放、暂停、上一张、下一张、第一张、最后一张这些功能。每个功能都对应一个方法,常规写法就是这样:
methods: {
first(){
//dosomthing
},
pre(){
//dosomthing
},
play(){
//dosomthing
},
next(){
//dosomthing
},
end(){
//dosomthing
},
stop(){
//dosomthing
}
}
现在稍微修改一下,看下面的代码,todo函数把这些业务相关的方法全收进去了,前面这些函数都作为一个对象的属性返回。这样处理后,把todo收起来,一下子就节省了一大片空间,有没有很屌(丝)?
methods: {
todo() {
return {
first(){
//dosomthing
},
pre(){
//dosomthing
},
play(){
//dosomthing
},
next(){
//dosomthing
},
end(){
//dosomthing
},
stop(){
//dosomthing
}
}
}
}
命令模式
从设计模式角度来看有点像策略模式,其实又不是,准确说应该是命令模式,因为每个方法做的事情不一样。不过这套函数相互之间会有些关系。比如我点了播放功能,那在播放的时候我点下一张或者最后一张等,就要先停住,再根据当前图片索引走到所需要的那一步。具体逻辑你如果有兴趣,可以自己写一个图片播放功能体会下。
调用方式
在ui层的用法是这样的
<span class="btn">
<img id="first" src="@/assets/img/1.png" @click="todo().first()" />
<img id="pre" src="@/assets/img/2.png" @click="todo().pre()" />
<img id="play" src="@/assets/img/3.png" @click="todo().play()" />
<img id="next" src="@/assets/img/2-2.png" @click="todo().next()" />
<img id="end" src="@/assets/img/1-2.png" @click="todo().end()" />
</span>
在ui层调用时要注意的一点:todo这个函数是暴露在methods接口下的,所以要调用到todo方法内返回的函数集对象,就要先调用todo(),得到函数集对象后,才能调用到相应的函数。
作用域和this问题
注意了,问题来了! 如果在next方法中想要调用stop方法,怎么实现呢?这里有多个要点要注意。
看代码,在next方法里像这样"that.stop()"调用stop()方法,是无效的。因为这个that就是前面定义的todo函数内的this,而这个this指向的是组件对象。说白了此时that只能调用到todo,是无法直接调用stop。
methods: {
todo() {
var that = this
return {
first(){
//dosomthing
},
pre(){
//dosomthing
},
play(){
//dosomthing
},
next(){
//dosomthing
//如何调用stop
that.stop();//undefined
},
end(){
//dosomthing
},
stop(){
//dosomthing
console.log('stop')
}
}
}
}
如果你还没有看明白怎么回事,接下来就让我来解释几个概念,帮助你理解。
1、函数作用域
js(es6)中作用域有函数作用域、全局作用域以及块级作用域,这里只讲函数作用域。在函数内部定义的变量,其作用域范围是此函数内部。如果在函数内部用到的变量不在当前函数内定义,它就会顺着作用域链向上查找,直到全局作用域,如果在上级作用域中找到了就会正常执行。这个例子中,在todo中定义的变量,其内部对象都可以调用到,但是todo函数之外的其他函数无法调用,这个都比较熟悉了。如果你有印象的话,我们在vue组件中经常用到this,这个this大部分情况下是指向组件本身的,但有时又不是,下面要分析到。
2、函数的this指向
this在js中非常实用,经常用到,但是你可能经常搞不明白this到底是指向了谁,要真正弄明白怎么用的可能得花点功夫,这里讲几个例子来说明一下。
默认情况下的this指向
在函数里,this默认指向的是全局对象window,但是这个this的指向经常会发生变化,这取决你怎么用它。在上面的例子中可以这样调用,见代码,在todo函数下定义一个that变量,此变量指向的是todo中的this,按前面说的这个this默认指向全局,在此就是当前组件,那that.todo().stop()就可以正常执行了。
methods: {
todo() {
var that = this
return {
first(){
//dosomthing
},
pre(){
//dosomthing
},
play(){
//dosomthing
},
next(){
//dosomthing
//如何调用stop
that.todo().stop();//stop
},
end(){
//dosomthing
},
stop(){
//dosomthing
console.log('stop')
}
}
}
}
todo().netxt();
对象调用其内部方法后的this指向
还有一个情况,在这个例子中,todo函数执行后得到一个对象,然后 在todo().next()这行代码的意思是一个对象调用其内部的一个方法,此时next函数内部的 this就是指向了todo()这个对象本身,就是todo方法中return出来的那个对象,所以前面提到的在next中调用todo()中的其他方法,就可以直接这样写,见代码。你可以调试代码仔细体会下。
methods: {
todo() {
var that = this
return {
first(){
//dosomthing
},
pre(){
//dosomthing
},
play(){
//dosomthing
},
next(){
//dosomthing
//如何调用stop
that.todo().stop();//stop
this.stop();//stop
},
end(){
//dosomthing
},
stop(){
//dosomthing
console.log('stop')
}
}
}
}
todo().netxt();
3、箭头函数
箭头函数的特殊之处在于,它里面的this会往上查找它的外部函数,外部函数的this指向哪儿它就指哪儿。不过箭头函数在这里用不起来,因为这个例子中不存在嵌套函数:todo里面是个对象,对象里面是一堆并列函数集。我们可以用这个例子来说明下,把this指向讲清楚。
var test = {
name: 'jw',
todo() {
console.log(this.name);//jw
function dowhat(){
console.log(this);//Window
}
dowhat();
var dothis = ()=>{
console.log(this)//{name: "jw", todo: ƒ}
}
dothis();
}
}
test.todo();
执行这段代码,你会发现普通函数dowhat中的this指向了window,这是前面说过的,普通函数中的this默认指向当前全局对象,这是js中的一个著名的坑,记住就行了;dothis中的this是在箭头函数中,指向的是test对象本身,就跟todo函数中的this是一样的,就是前面讲的,箭头函数中的this指向的是其父函数中的this,而这个this指向了test对象,是因为test对象调用了其内部todo方法。你可以这么理解,this就是一个见钱眼开的主,而且天生反骨,谁能指挥它的领导(函数),它就认它领导的领导为亲爸。
好了,今天的vue开发技巧就分享到这里了,这显然是挂羊头卖狗肉,狗肉就是作用域、this指向,希望对你有用,欢迎点赞分享,谢谢鼓励!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!