0.5.1 • Published 5 years ago

@vue-feathers/vue-feathers v0.5.1

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

vue-feathers

Feathers helpers and components for Vue

Getting Started

npm install @vue-feathers/vue-feathers

You'll need to set up a feathers client in your app. Each client is different. This example client uses SocketIO and feathers-reactive for real-time events.

import feathers from '@feathersjs/feathers'
import socketio from '@feathersjs/socketio-client'
import reactive from 'feathers-reactive'
import io from 'socket.io-client'

const socket = io('http://localhost:3030', {transports: ['websocket']})

export const feathersClient = feathers()
  .configure(socketio(socket))
  .configure(reactive({idField:'_id'}))

Then import and install the vue-feathers plugin

import Vue from 'vue'
import feathersClient from 'path/to/your/feathers/client'
import VueFeathers from '@vue-feathers/vue-feathers'

Vue.use(VueFeathers, { feathersClient })

Nuxt

Just put the above code in a js file and register it in nuxt.config.js as a plugin.

The Feathers Client: $F

The plugin registers the feathers client on all Vue components under this.$F, so in a component you could fetch and display all users like so:

export default {
  data() {
    return {
      users: [], // Initialize for storing fetched users 
    }
  },
  mounted() {
    this.findUsers()
  },
  methods: {
    findUsers() {
      this.$F.service('users')
        .find()               // Find all users.
        .then(users => {      // When the data arrives... 
          this.users = users  // store it.
        })
    }
  }
}

Mixins

The above scenario is so common that I wrapped it in a mixin. Using the same example with the same HTML:

import { mixins } from '@vue-feathers/vue-feathers'
const usersMixin = mixins.ListsMixin(['users']) // takes a list of service names

export default {
  mixins: [usersMixin], // handles the data hookup and provides some useful methods
  mounted() {
    this.find('users') // or use this.findAll() to fetch all at once
  },
}

This approach scales nicely:

const mixin = mixins.ListsMixin(['users', 'groups', 'roles', 'permissions', 'profiles'])

export default {
  mixins: [mixin],
  mounted() {
    this.findAll()
  },
}

Real-Time Data

feathers-reactive provides data stream interfaces that we can tap into. Assuming your feathers client has feathers-reactive installed, you can make a reactive list for the users example above like so:

export default {
  data() {
    return {
      users: [], // Initialize for storing fetched users
      subscription: null, // Initialize for storing the subscription to the 'users' endpoint 
    }
  },
  mounted() {
    this.sub()
  },
  methods: {
    sub(query) {
      this.unsub() // Unsub before sub in case component is remounted (ex. hot reload in dev mode)
      this.subscription = this.$F.service('users')
        .watch() // Watch 'users' for changes.
        .find({ query })  // On change, fetch all records.
        .subscribe(users => { // Whenever data arrives... 
          this.users = users  // store it.
        })
    },
    unsub() {
      if (this.subscription) {
        this.subscription.unsubscribe()
        this.subscription = null
      }
    }
  }
}

And again I provide a mixin to simplify:

import {mixins} from '@vue-feathers/vue-feathers'
const usersMixin = mixins.StreamsMixin(['users'])

export default {
  mixins: [usersMixin],
  mounted() {
    this.sub('users', { /* optional query goes here */ }) 
    // or use this.subAll(query) to subscribe to all at once
  },
}

And it scales in the same manner as the ListsMixin.

Data Provider Components

Here's where the magic happens. These data providers dynamically fetch and provide data via scoped slots.

Notes:

  • they render no DOM, like <template> and <slot> elements
  • :class and such do nothing on these components

Observable Stream

Subscribes to a query on an endpoint. Use the paginated prop to indicate if the endpoint returns a paginated response.

Provides an object of the form { stream, loading, refresh, pagination }. (See Scoped Props below for details.)

<observable-stream paginated endpoint="users" :query="{ active: true }">
  <template v-slot="{ stream, loading, refresh, pagination }">
    <pre v-for="record in stream">{{ record }}</pre>    
  </template>
</observable-stream>

Scoped Props

  • stream is an array of DB records, defaulting to an empty array before data arrives
  • loading is false when requested data has been fetched, true when waiting for requested data
  • refresh is a function that resets the stream and re-fetches data
  • pagination is data is present when "paginated" is set to true on observable-stream

Observable Streams (deprecated)

Subscribes to a set of endpoint queries given an object of the form { endpoint: query, ... }.

Provides an object of the form { endpoint: stream,... }.

<observable-streams :queryset="{ users: { active: true } }">
  <template v-slot="{ users }">
    <pre>{{ users }}</pre>
  </span>
</observable-streams>

Observable Object (deprecated)

Fetches the first element of the provided query from a single endpoint.

<observable-object endpoint="users" :query="{ username: 'moot' }">
  <div v-slot="{ object }">
    {{datum}}
  </div>
</observable-object>
0.5.1

5 years ago

0.5.0

5 years ago

0.4.0

5 years ago

0.3.3

5 years ago

0.3.2

5 years ago

0.3.1

5 years ago

0.3.0

5 years ago

0.2.3

5 years ago

0.2.2

5 years ago

0.2.1

5 years ago

0.2.0

6 years ago

0.1.13

6 years ago

0.1.12

6 years ago

0.1.11

6 years ago

0.1.10

6 years ago

0.1.9

6 years ago

0.1.8

6 years ago

0.1.7

6 years ago

0.1.6

6 years ago

0.1.5

6 years ago

0.1.4

6 years ago

0.1.3

6 years ago

0.1.2

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago

0.0.1

6 years ago