8

Smell jQuery like Vue, this small plugin is mgical!

 3 years ago
source link: https://dev.to/frustigor/smell-jquery-like-vue-this-small-plugin-is-mgical-58j
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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. 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.

jqvm.pnghttps://github.com/tangshuang/jqvm

A Quick Glance

I wrote a 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. Now, let's have a look into it:

<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>
Enter fullscreen modeExit fullscreen mode

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>
Enter fullscreen modeExit fullscreen mode

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.

$(...).vm(...)
  .fn('change', state => e => state.value = e.target.value)
Enter fullscreen modeExit fullscreen mode

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>
Enter fullscreen modeExit fullscreen mode

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>
Enter fullscreen modeExit fullscreen mode

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" />
Enter fullscreen modeExit fullscreen mode

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:

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

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.

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

<script>
$('#app').vm(...)
  .component('my-comp', myComp)
  .mount()
</script>
Enter fullscreen modeExit fullscreen mode

With props, you can pass and receive events:

<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>
Enter fullscreen modeExit fullscreen mode

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

Yeap! Isn't is like vue? You can explore more features here.

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.


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK