]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
feat: add support for Vue 2
authorEduardo San Martin Morote <posva13@gmail.com>
Mon, 2 Aug 2021 14:17:49 +0000 (16:17 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Mon, 2 Aug 2021 14:17:49 +0000 (16:17 +0200)
package.json
src/index.ts
src/mapHelpers.ts
src/store.ts
src/vue2-plugin.ts [new file with mode: 0644]

index b7260f2493240656ab448a27707290aa20f6db9e..9e0ee62865b1fffa48f53a408db522ee74049440 100644 (file)
@@ -19,6 +19,7 @@
     "name": "Eduardo San Martin Morote",
     "email": "posva13@gmail.com"
   },
+  "funding": "https://github.com/sponsors/posva",
   "scripts": {
     "docs": "vitepress dev docs",
     "docs:build": "vitepress build docs",
@@ -96,6 +97,7 @@
     "vite": "^2.4.1",
     "vitepress": "^0.15.6",
     "vue": "^3.2.0-beta.1",
+    "vue2": "npm:vue@2",
     "vue-promised": "^2.1.0",
     "vue-router": "^4.0.10",
     "yorkie": "^2.0.0"
index 17edf463f7352de4aae2fede66a808a3d0b8512f..b15060c96d634ee5e86e4d39b1c19d82e7521668 100644 (file)
@@ -61,3 +61,5 @@ export { createTestingPinia } from './testing'
 export type { TestingOptions, TestingPinia } from './testing'
 
 export { acceptHMRUpdate } from './hmr'
+
+export { PiniaPlugin } from './vue2-plugin'
index db847794d736dfd08db40425d5d0392f22143ba9..de55bfe75baf7fd0117d49b15e79e526039e8f1f 100644 (file)
@@ -1,5 +1,5 @@
-import { ComponentPublicInstance } from 'vue-demi'
-import {
+import type { ComponentPublicInstance } from 'vue-demi'
+import type {
   GettersTree,
   _Method,
   StateTree,
@@ -109,7 +109,7 @@ export function mapStores<Stores extends any[]>(
   }
 
   return stores.reduce((reduced, useStore) => {
-    // @ts-ignore: $id is added by defineStore
+    // @ts-expect-error: $id is added by defineStore
     reduced[useStore.$id + mapStoreSuffix] = function (
       this: ComponentPublicInstance
     ) {
index 1b009449ed6b86a09b2c9e148a67f0dc0c5f8662..4b4da49c5ce38e35daffbdb29ffb65210d2b7210 100644 (file)
@@ -17,6 +17,8 @@ import {
   toRefs,
   Ref,
   ref,
+  set,
+  isVue2,
 } from 'vue-demi'
 import {
   StateTree,
@@ -102,7 +104,11 @@ function createOptionsStore<
 
   function setup() {
     if (!initialState && (!__DEV__ || !hot)) {
-      pinia.state.value[id] = state ? state() : {}
+      if (isVue2) {
+        set(pinia.state.value, id, state ? state() : {})
+      } else {
+        pinia.state.value[id] = state ? state() : {}
+      }
     }
 
     // avoid creating a state in pinia.state.value
@@ -170,7 +176,7 @@ function createSetupStore<
   // watcher options for $subscribe
   const $subscribeOptions: WatchOptions = { deep: true, flush: 'sync' }
   /* istanbul ignore else */
-  if (__DEV__) {
+  if (__DEV__ && !isVue2) {
     $subscribeOptions.onTrigger = (event) => {
       if (isListening) {
         debuggerEvents = event
diff --git a/src/vue2-plugin.ts b/src/vue2-plugin.ts
new file mode 100644 (file)
index 0000000..1fed391
--- /dev/null
@@ -0,0 +1,58 @@
+import type { Plugin } from 'vue-demi'
+import { piniaSymbol } from './rootStore'
+
+/**
+ * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need
+ * this plugin if you are using Nuxt.js**. Use the `buildModule` instead:
+ * https://pinia.esm.dev/ssr/nuxt.html.
+ *
+ * @example
+ * ```js
+ * import Vue from 'vue'
+ * import { PiniaPlugin, createPinia } from 'pinia'
+ *
+ * Vue.use(PiniaPlugin)
+ * const pinia = createPinia()
+ *
+ * new Vue({
+ *   el: '#app',
+ *   // ...
+ *   pinia,
+ * })
+ * ```
+ *
+ * @param _Vue
+ */
+export const PiniaPlugin: Plugin = function (_Vue) {
+  // Equivalent of
+  // app.config.globalProperties.$pinia = pinia
+  _Vue.mixin({
+    beforeCreate() {
+      const options = this.$options
+      if (options.pinia) {
+        // HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/master/src/apis/inject.ts#L30
+        /* istanbul ignore else */
+        if (!(this as any)._provided) {
+          const provideCache = {}
+          Object.defineProperty(this, '_provided', {
+            get: () => provideCache,
+            set: (v) => Object.assign(provideCache, v),
+          })
+        }
+        ;(this as any)._provided[piniaSymbol as any] = options.pinia
+
+        // propagate the pinia instance in an SSR friendly way
+        // avoid adding it to nuxt twice
+        /* istanbul ignore else */
+        if (!this.$pinia) {
+          this.$pinia = options.pinia
+        }
+      } else if (!this.$pinia && options.parent && options.parent.$pinia) {
+        this.$pinia = options.parent.$pinia
+      }
+    },
+    destroyed() {
+      delete this._pStores
+    },
+  })
+}