美文网首页让前端飞
谁说在Vue.js里不能使用jQuery?!

谁说在Vue.js里不能使用jQuery?!

作者: microkof | 来源:发表于2017-12-20 11:24 被阅读155次

    前言

    自从几年前React、Angular、Vue兴起,业界就开始有一个观点是:终于可以摆脱jQuery了!但是,其实很奇怪,一个MVVM框架能取代一个库吗?

    jQ虽然逐渐走向消亡,但是消灭jQ的绝对不会是MVVM框架,因为两者根本是两码事。

    jQ消亡的原因很多,比如原生JS的DOM标准进行了几次升级,已经跟jQ的选择器系统接近,而Ajax、异步、动画这三大块,也有很棒的原生JS支持和独立库,所以jQ的优势被消磨殆尽,但是,jQ唯独跟MVVM没一毛钱关系。

    如果说,jQ跟Vue有什么冲突,其实就是在DOM上:

    Vue有一套自己的虚拟DOM系统,因此,jQ对DOM做的任何修改,默认前提下,都不会被Vue所承认,也就是说,Vue并不知道、也不关心jQ对界面做了什么修改,等到Vue对DOM做了后续修改,这时候前面jQ做的任何修改都会被抹平。这就是Vue与jQ的冲突。

    那么,这种冲突是无法解决的么?显然不是。一个很简单的做法就是:

    将一片DOM节点划归jQ,也就是说,Vue不打算管这一片节点,交给jQ全权负责。同时,jQ需要从Vue读取数据,呈现到UI中,jQ操作DOM之后,必须将操作结果通知Vue,由Vue保存结果。看到了吧?双向绑定。

    除此之外,再结合上生命周期,后加载jQ,保证jQ始终被Vue所管理,等等,具体不多说。下面用一个例子来说明。

    全网通缉一个适用于Vue的range-slider插件

    最近在做的一个小型Vue项目,其中需要一个range-slider插件,要像这样子:

    image.png

    刚开始,我也尝试过自己写一个,但是里面要注意的细节还是很多的,所以决定搜一个。然而,我尝试搜索Vue版本的这种插件,搜了1个小时也没找到,找到的一律是jQ版本的,好消息是jQ版本的插件非常成熟,比如Ion.RangeSlider,它除了需要CSS定制一下,其他像options完全够用,可以说是想要做到,心想事成。这么OK的插件只有一个问题:它不是Vue版本。

    怎么办?

    用呗。

    安装

    官网:http://ionden.com/a/plugins/ion.rangeSlider/

    npm install jquery --save
    npm install ion-rangeslider --save
    

    编写子组件“IonRangeSlider.vue”

    为了方便管理,rangeslider写成一个vue组件,大致如下:

    <template>
      <div class="ion-range-slider">
        <input type="text" ref="range_input" value="" />
      </div>
    </template>
    
    <script>
    import jQuery from 'jquery'
    import 'ion-rangeslider'
    import 'ion-rangeslider/css/ion.rangeSlider.css'
    import 'ion-rangeslider/css/ion.rangeSlider.skinHTML5.css'
    
    export default {
      model: {
        prop: 'averagePriceRange',
        event: 'slideFinish'
      },
      props: ['averagePriceRange'],
      mounted () {
        jQuery(this.$refs.range_input).ionRangeSlider({
          type: "double",
          min: 0,
          max: 100,
          from: this.averagePriceRange.from,
          to: this.averagePriceRange.to,
          hide_min_max: true,
          prefix: '¥',
          max_postfix: '+',
          extra_classes: '',
          onFinish: (data) => {
            console.log(data)
            this.$emit('slideFinish', {from: data.from, to: data.to})
          }
        })
      }
    }
    </script>
    

    template

    template这块代码很简单,<input type="text" ref="range_input" value="" />是Ion.RangeSlider要求的,看手册即可。

    import

    import jQuery from 'jquery'
    import 'ion-rangeslider'
    import 'ion-rangeslider/css/ion.rangeSlider.css'
    import 'ion-rangeslider/css/ion.rangeSlider.skinHTML5.css'
    

    前两行不解释,但是引入css的办法,插件手册里并没有写,需要我自己看node_modules的ion-rangeslider文件夹里面的文件架构,然后引入。皮肤文件根据自己需要选一个即可。

    export

    1. mounted,这个最好理解,纯jQ和jQ插件的知识,不解释。data的内容打印了自己看即可。唯独只有一句this.$emit('slideFinish', {from: data.from, to: data.to}),后面解释。
    2. props,因为我的项目是需要价格区间,所以变量名为averagePriceRange。准备从父组件接受这个变量,它的数据架构就是{from: data.from, to: data.to}
    3. model,这个要划重点。model是一个不常用属性,手册是https://cn.vuejs.org/v2/api/#model。说白了,就是它跟$emit()配合,将数据传递给父组件。

    编写父组件

    父组件这块,我只在下方写出跟这次尝试相关的代码。

    <template>
              <div class="range-warpper">
                <ion-range-slider
                  v-model="averagePriceRange"
                ></ion-range-slider>
              </div>
    </template>
    <script>
    import IonRangeSlider from '@/components/common/IonRangeSlider.vue'
    
    export default {
      components: { IonRangeSlider },
      data () {
        return {
          averagePriceRange: {from: 0, to: 100}
        }
      }
    }
    </script>
    

    template

    template中的要点只有一个:v-model="averagePriceRange",也就是给子组件双向绑定这个变量。

    script

    script代码完全不用解释。

    效果

    效果跟插件手册的范例一模一样。

    怎么确定实现了双向绑定?

    测试父向子传值

    将父组件的data的averagePriceRange初始值改成{from: 33, to: 77},界面中会看到,左右指针的位置指向了33和77。

    测试子向父传值

    先打开浏览器的Vue.js devtools插件,调到Vue,找到我们的父组件,看到右侧数据已经是:

    image.png

    当然,此时UI中指针也是33和77。

    然后拖动指针,比如拖到24和86,然后观察Vue.js devtools插件的data,会发现也变成了24和86。我就不再截图了。

    结论

    Vue.js里使用jQuery是完全可行的,而且完全符合Vue的工作思想,本质上,将jQ视为一个对Vue适配度不高的Vue插件就行了,双向绑定工作需要你自己来完成而已。

    谢谢。

    相关文章

      网友评论

        本文标题:谁说在Vue.js里不能使用jQuery?!

        本文链接:https://www.haomeiwen.com/subject/lgqcixtx.html