0.3.2 • Published 5 years ago

vue-computed-firestore v0.3.2

Weekly downloads
-
License
ISC
Repository
bitbucket
Last release
5 years ago

vue-computed-firestore

Simple two-way(ish) binding of firestore docs and collections to vue computed properties.

Install

npm install vue-computed-firestore

Usage

Somewhere in your apps boot process

  const VueComputedFirestore = require('vue-computed-firestore');
  Vue.use(VueComputedFirestore, {firebase: appFirebase});

Component

<template>
  <h3>{{user.name}}</h3><br>
  <input v-model.lazy="user.bio" />
  <div v-for="(todo, key) in todos" :key="key" >
    {{todo.text}}
  </div>
</template>
<script>
export default {
  data(){
    return {
      currentUserID: 'abc123',
    },
  },
  computedFirestore(){
    return {
      user: ['user', '$currentUserID'],
      todos: ['user', '$currentUserID', 'todos'],
    }
  },
}

In the above example, the user and todos defined within computedFirestore become reactive properties on the vue instance root (just like computed or data objects) and will update whenever the database changes.

Options

Options can be passed to this module in multiple ways

  • As the second parameter to Vue.use
  • As a object with the key $config within the computedFirestore() return object
  • As an object at index 0 within a property path array

Available options

  • firebase Root firebase object to read from (required param for Vue.use)
  • baseName = '$fs' Internal property added to Vue prototype. Only changeable during install. Only modify this if there are conflicts.
  • definitionName = 'computedFirestore' String name of function called to create bindings. Only changeable during install.
  • includeKey = '$key' Whether to include the id of a document, and it's keypath if included. Set to a falsy value to not include, otherwise it will be included as a non-enumerable property on the document.
  • includeMetadata = '$metadata' Whether to include document snapshot metadata, and it's keypath if included. Set to a falsy value to not include, otherwise it will be included as a non-enumerable property on the document.
  • collectionsAsObject = true Whether to return collections and queries as objects (using document id's as keys) or arrays.

  • handlers = {} See section below on handlers.

Property paths

The core of this modules use comes in defining property paths. Property paths are an array (optionally starting with a config object) of strings (document and collection IDs), arrays (where queries) and objects (orderBy and limit clauses).

Reactivity is added through property interpolation. Any place that can accept a string can be made to accept a reactive object by providing a string beginning with '$' e.g., To retrieve a doc matching a computed, prop, or data value id, you can use a property path like ['user', '$id']. lodash.get is used internally to access this property, so dot-notated paths are acceptable.

  • Documents & Collections

    Fetching documents and collections by ID is done by passing a string containing the ID to fetch. This can obviously be nested as required.

    ['users','$id','todos']`

    would fetch the todos collection on the current user document

  • Where

    Where-style queries are performed by using an array in the property path. The three elements of this array correspond to the three parameters in a firestore where query.

    ['users', '$id', 'todos', ['due', '<', Date.now()], ['completed', '==', '$showCompleted'] ]

    would show the users todos that were due in the past either (depending on the value of this.showCompleted ) been completed or were not completed.

  • OrderBy and Limit

    OrderBy and limit clauses are performed by using an object in the property path. This object can have one or both of orderBy and limit keys. limit must be a number (or link to a reactive property which is a number), while orderBy can be a string (field name) or array (field name and ordering).

    ['users', '$id', 'todos', ['completed', '==', false ]{ orderBy: ['due', 'asc'], limit: '$numberToShow'}]

    will only show this.$numberToShow uncompleted todos, order by the date they're due

  • Per-property config

    If the first element of the property path is an object, it is treated as a config object, which overwrites any global or component-scope config, but only for this property path.

      [{includeKey: false}, 'users', '$id']

    would return the users document, but without the non-enumerable $key field included.

Available operations

Several firestore functions are made available.

  • Document

    set, update and delete are made available as non-enumerable methods on each document ($set, $update and $delete respectively).

    this.todos[completedID].$update({ completed: true });

    would mark a todo as completed.

  • Document property

    Document properties can be used directly with v-model, which will trigger $update when changed. This can also be set programmatically.

    <q-input v-model.lazy="user.bio">
    changeName(newName) {
      this.user.name = newName;
    }

    Note that this functionality is not debounced - to reduce the number of writes you perform, you may add debouncing functionality yourself.

    You may also use v-model directly with documents - both documents retrieved directly and those accessed through collections.

      computedFirestore(){
        user: ['users', '$id'];
      },
      methods: {
        setUser(name, age, bio){
          this.user = { name, age, bio };
        },
      },
      computedFirestore(){
        users: ['users'],
      },
      methods: {
        updateUser(id, newUserDocument){
          this.users[id] = newUserDocument;
        },
      },

    Attempting to set a document which doesn't exist will create a new document.

  • Collection

    add is made available as a non-enumerable method $add on each collection (but not on queries or collections that have been ordered or limited)

    this.todos.$add({ completed: false, text: newTodoText, due: newTodoDueTimestamp });

    would add a new todo

Handlers

Handlers are added as subkeys of the option key handlers. If you pass a single handler to a hook, all previous (higher) handlers for that hook are removed for any descendant configs. If you pass an array (even just an array with one handler), all previous higher handlers will still be invoked. The available hooks are:

  • error Called whenever there is a firebase error. Receives the error as a parameter.
  • once Called on the first snapshot event after component created lifecycle hook.
  • populated Called when all properties have received their first snapshot event after component created lifecycle hook. Can only be registered at the install or component level.
  • added Called whenever a document is added. Receives the new document(s) as a parameter. Only valid for collection-type bindings.
  • removed Called whenever a document is deleted. Recieves an array containing the ID's of the deleted documents. Only valid for collection-type bindings.
  • modified Called whenever a document is modified. Receives the new document(s) as a parameter.
  • updated Called whenever one of the previous three would be called. Receives the relevant document(s) as a parameter.
  • changed Called whenever the document or query ref changes - meaning this runs whenever one of the reactive variables you're depending on changes. Receives the relevant documents as a parameter.

    All of the above callbacks, when passing multiple documents (including collections or queries with only one document), will pass either an Object or Array depending on the value of config.collectionsAsObject.

0.3.2

5 years ago

0.3.1

5 years ago

0.2.0

5 years ago

0.1.1

5 years ago

0.1.0

5 years ago

0.0.4

5 years ago

0.0.3

5 years ago

0.0.2

5 years ago

0.0.1

5 years ago