DEV Community

Sadick
Sadick

Posted on • Originally published at Medium on

2

Creating a Vuejs Plugin

Plugin to help us work with PouchDB in a Vuejs application

awesome vuejs image

This post assumes that you at least have some working knowledge of Vuejs and PouchDB.

Don’t worry i'm not going to tell you to install 1000 things before you get started. All you need is Vuejs and PouchDB.

Plugins provides a way for you to add global-level functionality to Vue. For example Vue by itself doesn’t have a built-in routing system. Vue-router plugin adds a routing functionality to Vue. There are very few resources on how to create a vuejs plugin, so i hope this will help.

Before diving into the details of building, have a look at how you will be able to use this plugin we are about to make.

var app = new Vue({
el:"#app",
data: {
text:''
},
pouchdb:{
todos: new PouchDB("todos") // this will be reactive
},
methods: {
addTodo: function(){
var todo = {
_id: new Date().toIsoString(),
item: this.text
}
this.$pouchdbRefs.todos.put(todo)
}
}
})
view raw vuepouchuse.js hosted with ❤ by GitHub

Initializing a plugin

A Vue.js plugin should expose an install method. The method will be called with the Vueconstructor as the first argument, along with possible options.

function install(Vue,options){
}
view raw vuepouchdb1.js hosted with ❤ by GitHub

Defining a Mixin

Mixins are a flexible way to distribute reusable functionalities for Vue components.

var PouchMixin = {
beforeCreate: init
}
view raw pouchMixin.js hosted with ❤ by GitHub

Note the beforeCreate property. This is an event that gets emitted by vuejs before the initialization of the vue instance properties and methods. The init is a function which you will be creating next.

function init(){
var bindings = this.options.pouchdb
ensureRef(this)
for(var key in bindings){
bind(this,key,bindings[key])
}
}
view raw pouchinit.js hosted with ❤ by GitHub

In the init function we get the pouchdb option that is set in a vue instance. You will use the ensureRef function to set the $pouchdbRefs property which will hold a reference to the PouchDB object.

function ensureRef (vm) {
if (!vm.$pouchdbRefs) {
vm.$pouchdbRefs = Object.create(null)
}
}
view raw ensureRef.js hosted with ❤ by GitHub

Now the interesting part. You will create the bind function which its main responsibility will be to make the data from PouchDB reactive.

function bind(vm,key,source){
var array = []
defineReactive(vm,key,array)
vm.$pouchdbRefs[key] = source // set the refs to refrence the new PouchDB('') passed
// PouchDB events
source.changes({
since:'now',
live: true,
include_docs: true
}).on('complete',function(info){
}).on('change',function(change){
vm[key].push(change.doc) // this is just an example of how the change can be used.
}).on('err',function(err){
})
// end of PouchDB events
//Obtaining data from PouchDB
source.allDocs({
include_docs: true,
descending: true
}).then(function(doc){
var docs = doc.rows.map(function(obj){
return obj.doc
})
defineReactive(vm,key,docs)
}).catch(function(err){
})
}
view raw bind.js hosted with ❤ by GitHub

One last thing you need to do is notify Vue that it should track changes made on the PouchDB data. The defineReactive function will be responsible for that part. You will use the util from vue to define the reactivity.

function defineReactive(vm,key,val){
// first check if it is present on the vue instance
if(key in vm){
vm[key] = val
} else {
Vue.util.defineReactive(vm,key,val)
}
}

Bringin it all together

var init = function(){
var bindings = this.$options.pouchdb
ensureRef(this)
for(var key in bindings) {
bind(this,key,bindings[key])
}
}
function ensureRef (vm) {
if (!vm.$pouchdbRefs) {
vm.$pouchdbRefs = Object.create(null)
}
}
function defineReactive(vm,key,val){
if(key in vm){
vm[key] = val
} else {
Vue.util.defineReactive(vm,key,val)
}
}
function bind(vm,key,source){
var array = []
defineReactive(vm,key,array)
vm.$pouchdbRefs[key] = source
source.changes({
since:'now',
live: true,
include_docs: true
}).on('complete',function(info){
}).on('change',function(change){
vm[key].push(change.doc)
}).on('err',function(err){
})
source.allDocs({
include_docs: true,
descending: true
}).then(function(doc){
var docs = doc.rows.map(function(obj){
return obj.doc
})
defineReactive(vm,key,docs)
}).catch(function(err){
})
}
var PouchMixin = {
init: init, // making it usable with vuejs 1.x.x
beforeCreate: init
}
function install(Vue){
Vue.mixin(PouchMixin)
}
// auto install
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
view raw vuepouch.js hosted with ❤ by GitHub

You can find the project at github contributions are welcomed.

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay