Smell jQuery like Vue, this small plugin is mgical!
Tags: jquery, vue
Published: 2021-06-01 03:46:36

---
title: Smell jQuery like Vue, this small plugin is mgical!
published: true
description: This article introduce a jQuery plugin which let you write a jQuery application very like Vue.
tags: jQuery, vue
cover_image: https://visyu.de/wp-content/uploads/2020/01/artikelbild_jquery_vue-750x280.jpg
---

Hi, I am back for a long time.

Today I will introduce a jQuery plugin written by me. Yes, I did not give up jQuery, because many old systems are using jQuery and not be able to refactor and even need to support IE8. It is a strong UI driven library, even though react, vue cover the sky today. I love react too, but I thought, react is a UI library too, what is the difference? **Reactive!!!** React is a reactive UI libaray, but jQuery is not. Can I make jQuery a reactive library? Here is my answer.

<center>![](https://github.com/tangshuang/jqvm/raw/master/jqvm.png)</center>

<center>https://github.com/tangshuang/jqvm</center>

## A Quick Glance

I wrote the small plugin for jQuery, which costs hundreds lines, called *jQvm* (jQuery view model) following MVVM pattern. If you are familiar with jQuery, you will use it as a jQuery plugin as your familiar way. If you need to refactor your old jQuery system, maybe jQvm is an option.

Now, let's have a look into it:

```html
<template id="app">
  <span>{{name}}</span>
  <span>{{age}}</span>
  <button jq-on="click:grow">Grow</button>
</template>

<script>
  $('#app')
      .vm({ name: 'tom', age: 10 })
      .fn('grow', state => state.age ++)
      .mount()
</script>
```

Yes, a template section and a jQuery plugin usage, done!
To import the plugin, you can use CDN:

```
<script src="https://unpkg.com/jquery/dist/jquery.min.js"></script>
<script src="https://unpkg.com/jqvm/dist/jqvm.min.js"></script>
```

You do not need to compile or build the code, it is so lightweight that you can use it in any website which even is out of date. 

(Notice, jQvm is based on jQuery 3.6.x, and use `Object.defineProperty` to implement reactive system, you may need some polyfill to resolve warnings in old browsers.)

## Features

Ok, I know you are doubt with the features in jqvm which vue provides but not in jqvm. Let's take a review:

**Mutable Reactive**

In vue, you can modify properties on `this` to trigger rerenderer, it is the same in jQvm.

```js
$(...).vm(...)
  .fn('change', state => e => state.value = e.target.value)
```

We directly change `state` to trigger rerenderer.

**Conditional Render**

In vue, you can use `v-if` to control the visibility of a node, you can use `jq-if` in jQvm.

```
<div jq-if="age > 10">I am older than 10.</div>
```

**Loop Render**

In vue, you use `v-for` to render loop set, you can use `jq-repeat` in jQvm.

```
<div jq-repeat="value,index in data traceby value.id">
  <span>{{index + 1}}</span>
  <span>{{value.name}}</span>
  <span>{{value.time}}</span>
</div>
```

**Two Way Binding**

In vue, you use `v-model` to bind a form component value with data, in jQvm you can use `jq-bind`.

```
<input jq-bind="age" />
```

**Component**

In vue, you can use another vue component in current one. However, in jQvm, it is different. There is a concept *View* in jQvm, a view is a instance created by `.vm`, for example:

```js
const myComp = $(...)
  .vm(() => ...) // notice here, you should better use a function to return initState
  .fn(...)
  .on(...)
```

Notice that, I did not call `.mount()` at the end, this `view` is an alone View which is not be used in our system. Now we can use it as a component in our current view.

```html
<div id="app">
  <my-comp></my-comp>
</div>

<script>
$('#app').vm(...)
  .component('my-comp', myComp)
  .mount()
</script>
```

With props, you can pass and receive events:

```html
<div id="app">
  <my-comp type="search" :count="count" @change="handleChange"></my-comp>
</div>

<script>
const myComp = $(`
  <template>
    <i class="icon icon-{{type}}"></i>
    <span>{{count}}</span>
    <button>plus</button>
  </template>
`)
  .vm(() => ({ count: 0, type: 'text' }))
  .on('click', 'button', function(state) {
    this.emit('change', state.count + 1)
  })
$('#app').vm({ count: 4 })
  .component('my-comp', myComp)
  .fn('handleChange', state => count => state.count = count)
  .mount()
</script>
```

The previous code give `type` `:count` and `@change` props to `my-comp`. 

## More

Yeap! Isn't is like vue? You can explore more features [here](https://github.com/tangshuang/jqvm).

Why I wrote it (why not vue directly)? Because in some case, I do not need a heavyweight library/framework to enhance my application especially the old systems which written by jquery. And in my spare time, I write some small tools and can use jQvm so quickly to implement the UI.

If you think it is a good idea, please give a star on github [here](https://github.com/tangshuang/jqvm).

Bye~