npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vue-data-proxy

v1.0.4

Published

Easily create deep object proxy (mainly to map a Vuex nested sub-state to a computed property)

Downloads

50

Readme

vue-data-proxy

This package provides vueDataProxy() to generate a two-way bindable computed property from the result of a user's fetch function (e.g. to retrieve the object from a Vuex store), that calls back a user's commit function on any change on the object, even deeply nested. Then, you get a very simple way of doing two-way binding with Vuex for use with v-model

Motivation

This package, even if it doesn't limit its scope to the Vuejs / Vuex environment, was initially design to provide a simple way to get deep two way binding with Vuex. At the end, it can finally work with any type of datastore as long as they use Vue's reactivity system.

It can also be used without Vue at all as a starting point of a MVC system.

Related works

There are already a wide variety of utilities to deal with two-way bindings with Vuex store. However, none of them addresses the problem of dealing with nested substate, and having deep reactivity. For example, suppose you have this store :

export default new Vuex.Store({
  state: {
    users : [
      { name : 'foo', category : 'bar' },
      // ...
    ]
  },
  mutations : {
     updateUser(state, {id, name, category}){
       state.users[id].name = name;
       state.users[id].category = category;
     }
  }

With the official Vuex' recommended way, you would have to declare two computed property, one for name and one for category, both calling the same mutation to update.

With Vuex's mapState, it would be less verbose, but you'd still have to define a method and both the computed properties.

With vuex-bound, it would be even shorter, but still need you to define each property one by one.

vuex-dot introduces an interresting way to do what the previous one does using a dot-synthax. However, it still does not handle the nested case.

Contribution

This package addresses the problem of deep nested two-way binding by providing a function that generate a two-way bound computed property definition. Considering the previous example, you would simply write the following (let's suppose you write a .vue component) :

<template>
  <input v-model="user.name" placeholder="user's name"/>
  <input v-model="user.category" placeholder="user's category"/>
</template>

import vueDataProxy from 'vue-data-proxy';
export default {
  computed : {
    ...vueDataProxy({
      user : {
        fetch() { return this.$store.state.input[this.userId] },
        commit(newVal){ this.$store.commit('updateUser', {id : this.userId, name : newVal.name, category : newVal.category}) },
      }
    }),
  }
  props : {
    userId : Number,
  },
},

On non-object proxied data, this generate a code equivalent to a simple two-way bound computed property.

Limitations

Since the code is greatly inpired by Vue's reactivity system, it does have the same limitations. For example, it won't detect property addition nor array [] synthax assigment. However, you can use the array's method that Vue reactvity system is compatible with. (splice(), push(), pop(), [...])

Another limitation, if you want the computed property nested attribute to be reactive, always access the computed property first. For example, the folowing wouldn't work :

var alias // global scope alias
//[...]
  methods : {
    genAlias(){
      alias = this.user.name;
    }
  computed : {
    ...vueDataProxy({
      user : {
        fetch() { return this.$store.state.input[this.userId] },
        commit(newVal){ this.$store.commit('updateUser', {id : this.userId, name : newVal.name, category : newVal.category}) },
      }
    }),
    name() { return alias } // not reactive because user is not a dependency
    name2() { _ = this.user; return alias } // Reactive because even alias is accessed without accessing this.user, the _ variable marks this.user as a dependency, and force recomputation. (note you'd still need to regenerate the alias...)
  }

Installation

With a build system

npm install --save vue-data-proxy

Wherever you need it:

import vueDataProxy from 'vue-data-proxy'

(Re)build

The needed files are already provided in dist/, but if you want to re build, simlply run :

npm run build

Directely in html

<script src="vueDataProxy.min.js"></script>

API

vueDataProxy(params)
params is an object. Each key represents a proxy definition (a resulting computed property), and each associated value should be an object with the following fields :

  • fetch : A function with no arguments, this representing the Vue local component instance. Should return the store object value.
  • commit : A function called at each modification (on the returned object from the computed property), taking the new value as parameter, and this representing the Vue local component.

License

This code is provided as-is, under the terms of the MIT license (see License file for more details).

A link to the original sources and contribution / pull request are welcome if you enjoy / use / contribute to this module ! :)