{"id":15566959,"url":"https://github.com/bhoriuchi/vue-deepset","last_synced_at":"2025-04-13T15:50:47.450Z","repository":{"id":57395565,"uuid":"83002071","full_name":"bhoriuchi/vue-deepset","owner":"bhoriuchi","description":"Deep set Vue.js objects","archived":false,"fork":false,"pushed_at":"2018-01-28T05:19:26.000Z","size":127,"stargazers_count":92,"open_issues_count":3,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-27T06:44:51.992Z","etag":null,"topics":["deepset","mutations","reactive","vue","vue2","vuejs","vuex"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bhoriuchi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-24T04:43:30.000Z","updated_at":"2023-09-05T16:04:52.000Z","dependencies_parsed_at":"2022-09-05T05:51:00.851Z","dependency_job_id":null,"html_url":"https://github.com/bhoriuchi/vue-deepset","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhoriuchi%2Fvue-deepset","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhoriuchi%2Fvue-deepset/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhoriuchi%2Fvue-deepset/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bhoriuchi%2Fvue-deepset/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bhoriuchi","download_url":"https://codeload.github.com/bhoriuchi/vue-deepset/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248323097,"owners_count":21084436,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deepset","mutations","reactive","vue","vue2","vuejs","vuex"],"created_at":"2024-10-02T17:09:05.868Z","updated_at":"2025-04-13T15:50:47.422Z","avatar_url":"https://github.com/bhoriuchi.png","language":"JavaScript","funding_links":[],"categories":["Utilities [🔝](#readme)","公用事业","Components \u0026 Libraries","Utilities"],"sub_categories":["杂","Utilities","Miscellaneous"],"readme":"# vue-deepset\nDeep set Vue.js objects using dynamic paths\n\n---\n\nBinding deeply nested data properties and vuex data to a form or component can be tricky. The following set of tools aims to simplify data bindings. Compatible with `Vue 1.x`, `Vue 2.x`, `Vuex 1.x`, and `Vuex 2.x`\n\n**Note** `vueModel` and `vuexModel` use [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) objects if supported by the browser and fallback to an object with generated fields based on the target object. Because of this, it is always best to pre-define the properties of an object when using older browsers.\n\nAlso note that models are flat and once built can set vue/vuex directly using `model[path] = value` where path is a lodash formatted path string or path array.\n\n### Examples\n\nFull examples can be found in the [tests](https://github.com/bhoriuchi/vue-deepset/tree/master/test) folder on the project repo\n\n### Requirements\n\n* `vue@\u003e=1.0.0`\n* `vuex@\u003e=1.0.0` (optional)\n\n### Dynamic paths\n\nIf you knew what every path you needed ahead of time you could (while tedious) create custom computed properties with getter and setter methods for each of those properties. But what if you have a dynamic and deeply nested property? This problem was actually what inspired the creation of this library. Using a Proxy, `vue-deepset` is able to dynamically create new, deep, reactive properties as well as return `undefined` for values that are not yet set.\n\n### Path Strings\n\nThe modeling methods use `lodash.toPath` format for path strings. Please ensure references use this format. You may also use `path Arrays` which can be easier to construct when using keys that include dots.\n\nThe following 2 path values are the same\n```js\nconst stringPath = 'a.b[\"c.d\"].e[0]'\nconst arrayPath  = [ 'a', 'b', 'c.d', 'e', 0 ]\n```\n\n#### Keys with dots\n\nSince dots prefix a nested path and are also valid characters for a key data that looks like the following can be tricky\n\n```js\nconst data = {\n  'foo.bar': 'baz',\n  foo: {\n    bar: 'qux'\n  }\n}\n```\n\nSo care should be taken when building the path string (or just use an array path) as the following will be true\n\n```js\n'foo.bar' // qux\n'[\"foo.bar\"]' // baz\n'foo[\"bar\"]' // qux\n'[\"foo\"].bar' // qux\n```\n\n### Binding `v-model` to deeply nested objects\n\nModel objects returned by `$deepModel`, `vueModel`, and `vuexModel` are flat and use getter/setter methods to access and update deep properties on the target object. Because of this, when binding a deep model object using `v-model` bracket notation should be used and the property value should be a path string. Using not notation past a single level object should be avoided.\n\n```html\n\u003cinput type=\"text\" v-model=\"model.prop1\"\u003e\n\u003cinput type=\"text\" v-model=\"model['prop1.subprop']\"\u003e\n\u003cinput type=\"text\" v-model=\"model['path.to[\u0026quot;deep nested\u0026quot;]']\"\u003e\n```\n\n## Usage\n\n* Webpack `import * as VueDeepSet from 'vue-deepset'`\n* Browser `\u003cscript src='./node_modules/vue-deepset/vue-deepset.min.js'\u003e\u003c/script\u003e`\n\n### As a Plugin\n\nThe easiest way to set up `vue-deepset` is as a Vue.js plugin. The plugin adds instance methods `$deepModel`, `$vueSet`, and `$vuexSet`. For **vuex** a mutation must be added (see vuex section).\n\nWhen using ES6+ use `import * as VueDeepSet from 'vue-deepset'`\n\n* `$deepModel ( obj:Object )` - for local vue objects\n* `$deepModel ( path:String )` - for vuex state properties; path to base object\n* `$vueSet (obj:Object, path:String, value:*)`\n* `$vuexSet (path:String, value:*)`\n\n#### Example - Browser (Vue 2.x)\n\n**html**\n```html\n\u003cdiv id=\"app\"\u003e\n  \u003cinput type=\"text\" v-model=\"model['input1']\"\u003e\n  \u003cinput type=\"text\" v-model=\"model['path.to[\u0026quot;deep nested\u0026quot;]']\"\u003e\n\u003c/div\u003e\n```\n\n**js**\n```js\nVue.use(VueDeepSet)\n\nvar app = new Vue({\n  el: '#app',\n  store,\n  computed: {\n    model () {\n      return this.$deepModel(this.obj)\n    }\n  },\n  data: {\n    obj: {\n      input1: 'Hello World!',\n      path: {\n        to: {\n          'deep nested': 'Hello Vue!'\n        }\n      }\n    }\n  }\n})\n\n```\n\n### Vuex\n\nForm binding to `vuex` using `v-model` requires registering the provided `VUEX_DEEP_SET` mutation. A convienience method `extendMutation` has been provided.\n\n**html**\n```html\n\u003cdiv id=\"app\"\u003e\n  \u003cinput type=\"text\" v-model=\"formData['message']\"\u003e\n\u003c/div\u003e\n```\n\n**js**\n```js\nvar store = new Vuex.Store({\n  state: {\n    formData: {\n      message: 'Hello Vuex!'\n    }\n  },\n  mutations: VueDeepSet.extendMutation({\n    // other mutations\n  })\n})\n\nvar app = new Vue({\n  el: '#app',\n  store,\n  computed: {\n    formData () {\n      return this.$deepModel('formData')\n    }\n  }\n})\n```\nor\n\n```js\nvar store = new Vuex.Store({\n  state: {\n    formData: {\n      message: 'Hello Vuex!'\n    }\n  },\n  mutations: {\n    VUEX_DEEP_SET: VueDeepSet.VUEX_DEEP_SET,\n    // other mutations\n  }\n})\n\nvar app = new Vue({\n  el: '#app',\n  store,\n  computed: {\n    formData () {\n      return this.$deepModel('formData')\n    }\n  }\n})\n```\n\n### API\n\n##### vueSet ( obj:Object, path:String, value:* )\n\nDeep sets a path with a value on a local data object so that is is reactive\n\n##### vuexSet ( path:String, value:* )\n\nDeep sets a path with a value in a vuex store so that it is reactive\n\n##### VUEX_DEEP_SET ( state:VuexState, args:Object )\n\nVuex mutation that should be registered when using vuexSet\n\n##### extendMutation ( [mutations:Object] )\n\nAdds the `VUEX_DEEP_SET` mutation to an optional hash of mutations and returns an updated hash of mutations\n\n##### vueModel ( obj:Object, [options:Object] )\n\nCreates an abstracted model with a set of flat properties that are generated from inspecting the objects properties so that deeply nested properties can be accessed as first level properties\n\n**options**\n* `useProxy=true` {`Boolean`} - disable use of Proxy when false\n\n##### vuexModel ( path:String, [options:Object] )\n\nThe equivalent of `vueModel` for `vuex`. Path should point to the base object\n\n**options**\n* `useProxy=true` {`Boolean`} - disable use of Proxy when false\n\n##### deepModel ( obj:Object, [options:Object] )\n\nEquivalent to `vueModel`\n\n**options**\n* `useProxy=true` {`Boolean`} - disable use of Proxy when false\n\n##### deepModel ( path:String, [options:Object] )\n\nEquivalent to `vuexModel`\n\n**options**\n* `useProxy=true` {`Boolean`} - disable use of Proxy when false\n\n### Non-Plugin usage\n\n##### Example - Browser\n\n```js\nvar store = new Vuex.Store({\n  state: {\n    formData: {\n      message: 'Hello Vuex!'\n    }\n  },\n  mutations: VueDeepSet.extendMutation()\n})\n\nvar app = new Vue({\n  el: '#app',\n  store,\n  computed: {\n    vuexForm () {\n      return this.vuexModel('formData')\n    },\n    localForm () {\n      return this.vueModel(this.localForm)\n    }\n  },\n  methods: {\n    vueSet: VueDeepSet.vueSet,\n    vuexSet: VueDeepSet.vuexSet,\n    vueModel: VueDeepSet.vueModel,\n    vuexModel: VueDeepSet.vuexModel\n  },\n  data: {\n    localForm: {\n      message: 'Hello Vue!'\n    }\n  }\n})\n```\n\n### Example - Webpack + ES6\n\n```js\nimport { vueSet } from 'vue-deepset'\n\nexport default {\n  methods: {\n    clearForm () {\n      vueSet(this.localForm, 'message', '')\n    }\n  },\n  data: {\n    localForm: {\n      message: 'Hello Vue!'\n    }\n  }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbhoriuchi%2Fvue-deepset","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbhoriuchi%2Fvue-deepset","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbhoriuchi%2Fvue-deepset/lists"}