vue-condition-watcher

Vue Composition API for automatic fetch data when condition has been changed

Usage no npm install needed!

<script type="module">
  import vueConditionWatcher from 'https://cdn.skypack.dev/vue-condition-watcher';
</script>

README

vue-condition-watcher 🕶

CircleCI vue3 vue3 npm npm bundle size npm

Introduction

Vue Composition API for automatic fetch data when condition has been changed

requires Node.js 12.0.0 or higher.

Features

✔ Auto fetch data when conditions changed.
✔ Auto filter falsy value in conditions.
✔ Auto convert the corresponding type. (string, number, array, date)
✔ Store the conditions within the URL hash every time a condition is changed
✔ Sync the state with the query string and initialize off of that and that back/forward/refresh work.
✔ Works for Vue 2 & 3 by the power of vue-demi

👉 Download Vue3 example here (Use Vite)

cd examples/vue3
yarn 
yarn serve

👉 Download Vue2 @vue/composition-api example here

cd examples/vue2
yarn 
yarn serve

👉 Online demo with vue-infinite-scroll

Edit vue-condition-watcher demo


export default {
  directives: { infiniteScroll },
  setup() {
    const items = ref([])

    const config = {
      fetcher: api.addBox,
      conditions: {
        offset: 0,
        limit: 10
      },
      afterFetch(data) {
        if (!data) return
        items.value = items.value.concat(data)
      }
    }
    
    const { conditions, loading } = useConditionWatcher(config)

    const loadMore = () => {
      if (loading.value) return
      conditions.offset += conditions.limit
    }

    return {
      conditions,
      loading,
      items,
      loadMore
    }
  }
}

Quick Start

Simple example for vue-next and vue-router-next

createApp({
  template: `
    <div class="filter">
      <input v-model="conditions.name">
      <button @click="refresh">Refresh</button>
    </div>
    <div class="container" v-if="!loading">
      {{ data }}
    </div>
    <div class="loading" v-else>Loading...</div>
  `,
  setup() {
    const config = {
      fetcher: params => axios.get('/user/', {params}),
      conditions: {
        name: ''
      },
    }
    return useConditionWatcher(config, {sync: 'router'})
  },
})
.provide('router', router)
.use(router)
.mount(document.createElement('div'))

Usage

In your project

yarn add vue-condition-watcher

Or with npm

npm install vue-condition-watcher

CDN

https://unpkg.com/vue-condition-watcher/dist/index.js

API

const { conditions, data, error, loading, refresh } = useConditionWatcher(config, queryOptions)

Parameters

  • config : An object of config for vue-condition-watcher

    • fetcher (⚠️Required) : Can be any asynchronous function to fetch data

    • conditions (⚠️Required) : An object of conditions, also be initial value

    • defaultParams: An object of fetcher's default parameters

    • beforeFetch: A function you can do before fetch data Parameters

    • afterFetch: A function you can do after fetch data. Parameters: data.

      
      const config = {
        fetcher: params => axios.get('url', { params }),
        defaultParams: {
          type: 'member'
        },
        conditions: {
          offset: 0,
          limit: 10,
          username: '',
          tags: [],
          created_at: new Date()
        },
        beforeFetch: conditions => {
          // conditions is an object clone copy from config.conditions
          conditions.created_at = dayjs(conditions.created_at, 'YYYY-MM-DD');
          return conditions
        },
        afterFetch(data) {
          console.log(data)
        }
      }
      
  • queryOptions: An object of options to sync query string with conditions

    • ⚠️ queryOptions work base on vue-router, you need install vue-router first.

    • sync: key of provide name ( String | Symbol )

      • main.js: register router
        import {createApp} from 'vue'
        import App from './App.vue'
        import { router } from './router'
      
        const app = createApp(App)
          .provide('router', router) // it's should be required
          .use(router)
          .mount('#app')
      
      • then
      useConditionWatcher(config, {sync: 'router'})
      
    • ignore: you can ignore key name from conditions, will not push with query.

      useConditionWatcher(config, {sync: 'router', ignore: ['offset', 'limit']})
      
    • navigation: use vue router navigation method push or replace, default value is push.

        useConditionWatcher(config, {sync: 'router', navigation: 'replace'})
      
How to use in vue@2 with @vue/composition-api
  • ( Good ) Add provide in main.js

    new Vue({
      el: '#app',
      router,
      store,
      provide: {
        router
      },
      render: h => h(App)
    })
    
  • Add provide in current file

    import { useConditionWatcher } from "vue-condition-watcher";
    import { provide } from "@vue/composition-api";
    import router from "@/router";
    import api from "../api";
    
    export default {
      setup() {
        provide("router", router);
    
        const config = {
          fetcher: api.users,
          conditions: {
            offset: 0,
            limit: 9
          }
        };
    
        return useConditionWatcher(config, {sync: 'router', ignore: ['offset', 'limit']});
      }
    };
    
How to use in Nuxt with @nuxtjs/composition-api
  • Add provide in current file

    import { useConditionWatcher } from "vue-condition-watcher";
    import { defineComponent, useRoute, provide, useContext } from "@nuxtjs/composition-api";
    import api from "~/api";
    
    export default defineComponent({
      setup() {
        const route = useRoute();
        const { app } = useContext();
        provide('router', app.router);
    
        const config = {
          fetcher: api.users,
          conditions: {
            offset: 0,
            limit: 9
          }
        };
    
        return useConditionWatcher(config, {sync: 'router', ignore: ['offset', 'limit']});
      }
    });
    

Return Values

  • conditions : An object and returns a reactive proxy of conditions
  • data: Data resolved by config.fetcher
  • error: Error thrown by config.fetcher
  • loading: Request is loading
  • refresh: A function to re-fetch data