最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 用设计模式巧妙整理vue中的methods

    正文概述 掘金(bridgeToVillage)   2021-01-02   474

    用设计模式巧妙整理vue中的methods

    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指向,希望对你有用,欢迎点赞分享,谢谢鼓励!


    起源地下载网 » 用设计模式巧妙整理vue中的methods

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元