>>分享Web前端开发技术,并对孙卫琴的《精通Vue.js:Web前端开发技术详解》提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 15932 个阅读者 刷新本主题
 * 贴子主题:  Thinking In Vue:vue指令的封装 回复文章 点赞(0)  收藏  
作者:flybird    发表时间:2021-02-04 01:12:53     消息  查看  搜索  好友  邮件  复制  引用

    

问题和解决

我看到项目中有一些这样的代码,在组件里给dom绑定事件:    

      dragmove = new DragMove({
       id: 'groupingeve',
       benchmark: 'right',
       dragdbclick: function() {},
       dragclick: function(e) {},
       dragend: function(e) {}
     })

  看到这样的代码很别扭,理想情况下,vue的组件里是不应该感知到dom的存在的,他能感知和操作的只有数据,数据到dom的各种绑定(事件、值)都应该通过指令。也就是说vue处理的输入和输出都是纯粹的数据,模板的输入是数据,输出是vdom。这个绑定事件的逻辑不应该放到组件里,应该移到模板中去。

                点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

    vue指令的定义是:当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。这个连带影响可能是dom结构的变更,可能是dom事件的绑定,可能是文本值的变化等。

     所以,这个数据到dom的逻辑应该封装到模板语法中的指令里。

     于是我这样封装了一下:    

import DragMove from 'drag-move';

const install = (Vue) => {
    /**
     * dragmove指令
     * 用法: <div id='ele' v-dragmove:ele="{dragend:dragendHandler}"></div>
     */

    Vue.directive('dragmove', {
        inserted: (el, binding) => {
            const options = {...binding.value, id: binding.arg};
            new DragMove(options);
        }
    });
}
module.exports = install;

  并且在入口js文件里作为全局资源引入了:    

import installDirectives from '@/common/directives';

installDirectives(Vue);

  用法是直接在需要处理的元素上加上这个指令,参数为id,值为option:    

<div id='ele' v-dragmove:ele="{dragend:dragendHandler}"></div>

  (这里的id其实我想去掉,但是DragMove本身并不支持传一个元素,所以保留了id。)

     我用在了纪律树模块里,对比一下前后的代码

之前:    

   this.dragObj = new DragMove({
     id: ele,
     dragClick: dragClickHandler,
     dragend: dragEndHandler
});

  之后:    

   <div id='lectureIceTree'
      v-dragmove:lectureIceTree="{dragClick: dragClickHandler,dragend:dragEndHandler}">
  </div>

  把和dom绑定的过程移到了模板中的指令中。这样的组件会更加的纯粹。

模板负责 数据到dom的绑定和同步,组件负责 交互、业务逻辑的各种数据处理,一前一后、一个只 处理数据、一个只 渲染视图,这样的代码,就算我把渲染层换成了原生android或ios、换成了VR,都可以适应,因为组件的纯粹。

不同的代码有不同的封装形式

之前我们讨论过为什么echarts在vue中使用要封装成组件,为什么Lottie和vue结合要封装成组件,为什么mybatis和spring整合要提供SqlSessionFactoryBean。 这些都是因为每种框架或者库都有自己对各类资源的处理思路与流程 : 就像spring对Bean的处理,支持BeanPostProcesser,支持FactoryBean等,就像Vue对模板的处理支持directive、filter、component等,就像javaweb中Servlet、Listener、Filter这些的区别一样。不同的代码应该有不同的封装形式,不同的封装形式也各自的使用方式以及可以用的资源。

     当然,如果根本没用到框架对资源的特有处理方式,那么不封装成对应的形式也是可以的。比如spring里面如果就是没有用到spring对bean的管理,那么直接手动new也无可厚非。

如果逻辑特别简单,不是特别值得封装,那么不封装也是可以的。比如有一段逻辑按照vue的思路应该作为filter而存在,但是逻辑特简单,用到的地方也不多,这样可以不封装。

Thinking in vue

在vue里,指令负责的是数据到dom的过程,所以类似的代码应该封装成指令,才能更好的和组件解耦,以及使用vue对指令提供的各种支持。除此以外,各种代码都有对应的封装形式,使用了vue,不能再用jquery的思路去使用,而应该用vue的思路。

     总之,希望可以用vue的思路去写vue,用spring的思路去写spring。

     Thinking in Vue !


----------------------------
原文链接:https://www.jianshu.com/p/5b20207be9de
作者:  凌霄光
程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2021-02-14 18:42:45 重新编辑]
网站系统异常


系统异常信息
Request URL: http://www.javathinker.net/WEB-INF/lybbs/jsp/topic.jsp?postID=3669

java.lang.NullPointerException

如果你不知道错误发生的原因,请把上面完整的信息提交给本站管理人员