From 6416ebb1e7822d52884824a4f54413b5a2e28647 Mon Sep 17 00:00:00 2001 From: Kia King Ishii Date: Sun, 15 Mar 2020 17:37:23 +0900 Subject: [PATCH 001/124] feat!: add vue 3 support BREAKING CHANGE: - It only works with Vue 3. - The installation process has been changed due to aligning with Vue 3's new initiation process. --- .circleci/config.yml | 40 +- README.md | 67 +- build/build.main.js | 2 + examples/chat/app.js | 19 - examples/{ => classic}/chat/api/index.js | 0 examples/{ => classic}/chat/api/mock-data.js | 0 examples/classic/chat/app.js | 13 + .../{ => classic}/chat/components/App.vue | 0 .../{ => classic}/chat/components/Message.vue | 7 +- .../chat/components/MessageSection.vue | 0 .../{ => classic}/chat/components/Thread.vue | 9 +- .../chat/components/ThreadSection.vue | 0 examples/{ => classic}/chat/css/chat.css | 0 examples/{ => classic}/chat/index.html | 2 +- examples/{ => classic}/chat/store/actions.js | 0 examples/{ => classic}/chat/store/getters.js | 0 examples/{ => classic}/chat/store/index.js | 9 +- .../{ => classic}/chat/store/mutations.js | 22 +- .../counter-hot/CounterControls.vue | 0 examples/classic/counter-hot/app.js | 9 + .../counter-hot}/index.html | 2 +- .../counter-hot/store/actions.js | 0 .../counter-hot/store/getters.js | 0 .../{ => classic}/counter-hot/store/index.js | 7 +- .../counter-hot/store/mutations.js | 0 examples/{ => classic}/counter/Counter.vue | 0 examples/classic/counter/app.js | 10 + .../counter}/index.html | 2 +- examples/{ => classic}/counter/store.js | 7 +- .../{ => classic}/shopping-cart/api/shop.js | 0 examples/{ => classic}/shopping-cart/app.js | 14 +- .../shopping-cart/components/App.vue | 0 .../shopping-cart/components/ProductList.vue | 12 +- .../shopping-cart/components/ShoppingCart.vue | 6 +- .../{ => classic}/shopping-cart/currency.js | 0 .../{ => classic}/shopping-cart/index.html | 2 +- .../shopping-cart/store/index.js | 9 +- .../shopping-cart/store/modules/cart.js | 0 .../shopping-cart/store/modules/products.js | 0 examples/classic/todomvc/app.js | 9 + .../{ => classic}/todomvc/components/App.vue | 14 +- .../todomvc/components/TodoItem.vue | 10 +- examples/{ => classic}/todomvc/index.html | 2 +- .../{ => classic}/todomvc/store/actions.js | 0 examples/{ => classic}/todomvc/store/index.js | 7 +- .../{ => classic}/todomvc/store/mutations.js | 2 +- .../{ => classic}/todomvc/store/plugins.js | 2 +- examples/composition/chat/api/index.js | 24 + examples/composition/chat/api/mock-data.js | 58 + examples/composition/chat/app.js | 13 + examples/composition/chat/components/App.vue | 21 + .../composition/chat/components/Message.vue | 23 + .../chat/components/MessageSection.vue | 63 + .../composition/chat/components/Thread.vue | 29 + .../chat/components/ThreadSection.vue | 39 + examples/composition/chat/css/chat.css | 98 ++ examples/composition/chat/index.html | 13 + examples/composition/chat/store/actions.js | 17 + examples/composition/chat/store/getters.js | 25 + examples/composition/chat/store/index.js | 42 + examples/composition/chat/store/mutations.js | 64 + .../counter-hot/CounterControls.vue | 32 + examples/composition/counter-hot/app.js | 9 + examples/composition/counter-hot/index.html | 13 + .../composition/counter-hot/store/actions.js | 18 + .../composition/counter-hot/store/getters.js | 15 + .../composition/counter-hot/store/index.js | 33 + .../counter-hot/store/mutations.js | 9 + examples/composition/counter/Counter.vue | 35 + examples/composition/counter/app.js | 10 + examples/composition/counter/index.html | 13 + examples/composition/counter/store.js | 55 + .../composition/shopping-cart/api/shop.js | 23 + examples/composition/shopping-cart/app.js | 13 + .../shopping-cart/components/App.vue | 19 + .../shopping-cart/components/ProductList.vue | 48 + .../shopping-cart/components/ShoppingCart.vue | 42 + .../composition/shopping-cart/currency.js | 23 + examples/composition/shopping-cart/index.html | 13 + .../composition/shopping-cart/store/index.js | 15 + .../shopping-cart/store/modules/cart.js | 92 ++ .../shopping-cart/store/modules/products.js | 38 + examples/composition/todomvc/app.js | 9 + .../composition/todomvc/components/App.vue | 103 ++ .../todomvc/components/TodoItem.vue | 68 + examples/composition/todomvc/index.html | 12 + examples/composition/todomvc/store/actions.js | 33 + examples/composition/todomvc/store/index.js | 13 + .../composition/todomvc/store/mutations.js | 26 + examples/composition/todomvc/store/plugins.js | 12 + examples/counter-hot/app.js | 9 - examples/counter/app.js | 10 - examples/index.html | 23 +- examples/server.js | 4 + examples/todomvc/app.js | 10 - examples/webpack.config.js | 23 +- package.json | 11 +- src/index.esm.js | 11 +- src/index.js | 8 +- src/injectKey.js | 7 + src/mixin.js | 43 +- src/store.js | 96 +- test/e2e/specs/cart.js | 61 +- test/e2e/specs/chat.js | 57 +- test/e2e/specs/counter.js | 47 +- test/e2e/specs/todomvc.js | 322 ++--- test/unit/helpers.spec.js | 1160 ++++++++--------- test/unit/hot-reload.spec.js | 106 +- test/unit/modules.spec.js | 6 +- test/unit/setup.js | 4 - test/unit/store.spec.js | 51 +- yarn.lock | 156 ++- 112 files changed, 2772 insertions(+), 1142 deletions(-) delete mode 100644 examples/chat/app.js rename examples/{ => classic}/chat/api/index.js (100%) rename examples/{ => classic}/chat/api/mock-data.js (100%) create mode 100644 examples/classic/chat/app.js rename examples/{ => classic}/chat/components/App.vue (100%) rename examples/{ => classic}/chat/components/Message.vue (71%) rename examples/{ => classic}/chat/components/MessageSection.vue (100%) rename examples/{ => classic}/chat/components/Thread.vue (71%) rename examples/{ => classic}/chat/components/ThreadSection.vue (100%) rename examples/{ => classic}/chat/css/chat.css (100%) rename examples/{ => classic}/chat/index.html (85%) rename examples/{ => classic}/chat/store/actions.js (100%) rename examples/{ => classic}/chat/store/getters.js (100%) rename examples/{ => classic}/chat/store/index.js (78%) rename examples/{ => classic}/chat/store/mutations.js (87%) rename examples/{ => classic}/counter-hot/CounterControls.vue (100%) create mode 100644 examples/classic/counter-hot/app.js rename examples/{counter => classic/counter-hot}/index.html (81%) rename examples/{ => classic}/counter-hot/store/actions.js (100%) rename examples/{ => classic}/counter-hot/store/getters.js (100%) rename examples/{ => classic}/counter-hot/store/index.js (84%) rename examples/{ => classic}/counter-hot/store/mutations.js (100%) rename examples/{ => classic}/counter/Counter.vue (100%) create mode 100644 examples/classic/counter/app.js rename examples/{counter-hot => classic/counter}/index.html (82%) rename examples/{ => classic}/counter/store.js (92%) rename examples/{ => classic}/shopping-cart/api/shop.js (100%) rename examples/{ => classic}/shopping-cart/app.js (50%) rename examples/{ => classic}/shopping-cart/components/App.vue (100%) rename examples/{ => classic}/shopping-cart/components/ProductList.vue (71%) rename examples/{ => classic}/shopping-cart/components/ShoppingCart.vue (81%) rename examples/{ => classic}/shopping-cart/currency.js (100%) rename examples/{ => classic}/shopping-cart/index.html (81%) rename examples/{ => classic}/shopping-cart/store/index.js (61%) rename examples/{ => classic}/shopping-cart/store/modules/cart.js (100%) rename examples/{ => classic}/shopping-cart/store/modules/products.js (100%) create mode 100644 examples/classic/todomvc/app.js rename examples/{ => classic}/todomvc/components/App.vue (89%) rename examples/{ => classic}/todomvc/components/TodoItem.vue (85%) rename examples/{ => classic}/todomvc/index.html (79%) rename examples/{ => classic}/todomvc/store/actions.js (100%) rename examples/{ => classic}/todomvc/store/index.js (72%) rename examples/{ => classic}/todomvc/store/mutations.js (89%) rename examples/{ => classic}/todomvc/store/plugins.js (84%) create mode 100644 examples/composition/chat/api/index.js create mode 100644 examples/composition/chat/api/mock-data.js create mode 100644 examples/composition/chat/app.js create mode 100644 examples/composition/chat/components/App.vue create mode 100644 examples/composition/chat/components/Message.vue create mode 100644 examples/composition/chat/components/MessageSection.vue create mode 100644 examples/composition/chat/components/Thread.vue create mode 100644 examples/composition/chat/components/ThreadSection.vue create mode 100644 examples/composition/chat/css/chat.css create mode 100644 examples/composition/chat/index.html create mode 100644 examples/composition/chat/store/actions.js create mode 100644 examples/composition/chat/store/getters.js create mode 100644 examples/composition/chat/store/index.js create mode 100644 examples/composition/chat/store/mutations.js create mode 100644 examples/composition/counter-hot/CounterControls.vue create mode 100644 examples/composition/counter-hot/app.js create mode 100644 examples/composition/counter-hot/index.html create mode 100644 examples/composition/counter-hot/store/actions.js create mode 100644 examples/composition/counter-hot/store/getters.js create mode 100644 examples/composition/counter-hot/store/index.js create mode 100644 examples/composition/counter-hot/store/mutations.js create mode 100644 examples/composition/counter/Counter.vue create mode 100644 examples/composition/counter/app.js create mode 100644 examples/composition/counter/index.html create mode 100644 examples/composition/counter/store.js create mode 100644 examples/composition/shopping-cart/api/shop.js create mode 100644 examples/composition/shopping-cart/app.js create mode 100644 examples/composition/shopping-cart/components/App.vue create mode 100644 examples/composition/shopping-cart/components/ProductList.vue create mode 100644 examples/composition/shopping-cart/components/ShoppingCart.vue create mode 100644 examples/composition/shopping-cart/currency.js create mode 100644 examples/composition/shopping-cart/index.html create mode 100644 examples/composition/shopping-cart/store/index.js create mode 100644 examples/composition/shopping-cart/store/modules/cart.js create mode 100644 examples/composition/shopping-cart/store/modules/products.js create mode 100644 examples/composition/todomvc/app.js create mode 100644 examples/composition/todomvc/components/App.vue create mode 100644 examples/composition/todomvc/components/TodoItem.vue create mode 100644 examples/composition/todomvc/index.html create mode 100644 examples/composition/todomvc/store/actions.js create mode 100644 examples/composition/todomvc/store/index.js create mode 100644 examples/composition/todomvc/store/mutations.js create mode 100644 examples/composition/todomvc/store/plugins.js delete mode 100644 examples/counter-hot/app.js delete mode 100644 examples/counter/app.js delete mode 100644 examples/todomvc/app.js create mode 100644 src/injectKey.js diff --git a/.circleci/config.yml b/.circleci/config.yml index cb7d199ff..c12856e77 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,23 +27,23 @@ jobs: paths: - vuex - lint-types: - <<: *defaults - steps: - - attach_workspace: - at: ~/ - - run: - name: Linting - command: | - yarn lint --format junit --output-file test-results/eslint/results.xml - - run: - name: Testing Types - command: | - yarn test:types - - store_test_results: - path: test-results - - store_artifacts: - path: test-results + # lint-types: + # <<: *defaults + # steps: + # - attach_workspace: + # at: ~/ + # - run: + # name: Linting + # command: | + # yarn lint --format junit --output-file test-results/eslint/results.xml + # - run: + # name: Testing Types + # command: | + # yarn test:types + # - store_test_results: + # path: test-results + # - store_artifacts: + # path: test-results test-unit: <<: *defaults @@ -80,9 +80,9 @@ workflows: install-and-parallel-test: jobs: - install - - lint-types: - requires: - - install + # - lint-types: + # requires: + # - install - test-unit: requires: - install diff --git a/README.md b/README.md index e43391e6b..bef0e0f5b 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,58 @@ -# Vuex [![Build Status](https://circleci.com/gh/vuejs/vuex/tree/dev.png?style=shield)](https://circleci.com/gh/vuejs/vuex) +# Vuex 4 -> Centralized State Management for Vue.js. +This is the Vue 3 compatible version of Vuex. The focus is compatibility, and it provides the exact same API as Vuex 3, so users can reuse their existing Vuex code for Vue 3. -

- -

+## Status: Alpha -- [What is Vuex?](https://vuex.vuejs.org/) -- [Full Documentation](http://vuex.vuejs.org/) +All Vuex 3 feature works. There are a few breaking changes described in a later section, so please check them out. You can find basic usage with both option and composition API at `example` folder. -## Examples +Please note that it's still unstable, and there might be bugs. Please provide us feedback if you find anything. You may use [vue-next-webpack-preview](https://github.com/vuejs/vue-next-webpack-preview) to test out Vue 3 with Vuex 4. -- [Counter](https://github.com/vuejs/vuex/tree/dev/examples/counter) -- [Counter with Hot Reload](https://github.com/vuejs/vuex/tree/dev/examples/counter-hot) -- [TodoMVC](https://github.com/vuejs/vuex/tree/dev/examples/todomvc) -- [Flux Chat](https://github.com/vuejs/vuex/tree/dev/examples/chat) -- [Shopping Cart](https://github.com/vuejs/vuex/tree/dev/examples/shopping-cart) +## Breaking changes -Running the examples: +### Installation process has changed -``` bash -$ npm install -$ npm run dev # serve examples at localhost:8080 +To align with the new Vue 3 initialization process, the installation process of Vuex has changed as well. + +You should use a new `createStore` function to create a new store instance. + +```js +import { createStore } from 'vuex' + +const store = createStore({ + state () { + return { + count: 1 + } + } +}) +``` + +> This is technically not a breaking change because you could still use `new Store(...)` syntax. However, to align with Vue 3 and also with Vue Router Next, we recommend users to use `createStore` function instead. + +Then to install Vuex to Vue app instance, pass the store instance instead of Vuex. + +```js +import { createApp } from 'vue' +import store from './store' +import App from './APP.vue' + +const app = createApp(Counter) + +app.use(store) + +app.mount('#app') ``` -## License +## Kown issues + +- The code is kept as close to Vuex 3 code base as possible, and there're plenty of places where we should refactor. However, we are waiting for all of the test cases to pass before doing so (some tests require Vue 3 update). +- TypeScript support is not ready yet. Please use JS environment to test this for now. + +## TODOs as of 4.0.0-alpha.1 -[MIT](http://opensource.org/licenses/MIT) +- Add TypeScript support +- Make all unit test working +- Refactor the codebase +- Update the build system to align with Vue 3 +- Update docs diff --git a/build/build.main.js b/build/build.main.js index 7f6e4e7ec..d433f000d 100644 --- a/build/build.main.js +++ b/build/build.main.js @@ -27,6 +27,8 @@ function build (builds) { } function buildEntry ({ input, output }) { + input.external = ['vue'] + output.globals = { vue: 'Vue' } const { file, banner } = output const isProd = /min\.js$/.test(file) return rollup.rollup(input) diff --git a/examples/chat/app.js b/examples/chat/app.js deleted file mode 100644 index 75081c2b1..000000000 --- a/examples/chat/app.js +++ /dev/null @@ -1,19 +0,0 @@ -import 'babel-polyfill' -import Vue from 'vue' -import App from './components/App.vue' -import store from './store' -import { getAllMessages } from './store/actions' - -Vue.config.debug = true - -Vue.filter('time', timestamp => { - return new Date(timestamp).toLocaleTimeString() -}) - -new Vue({ - el: '#app', - store, - render: h => h(App) -}) - -getAllMessages(store) diff --git a/examples/chat/api/index.js b/examples/classic/chat/api/index.js similarity index 100% rename from examples/chat/api/index.js rename to examples/classic/chat/api/index.js diff --git a/examples/chat/api/mock-data.js b/examples/classic/chat/api/mock-data.js similarity index 100% rename from examples/chat/api/mock-data.js rename to examples/classic/chat/api/mock-data.js diff --git a/examples/classic/chat/app.js b/examples/classic/chat/app.js new file mode 100644 index 000000000..6a8128b67 --- /dev/null +++ b/examples/classic/chat/app.js @@ -0,0 +1,13 @@ +import 'babel-polyfill' +import { createApp } from 'vue' +import App from './components/App.vue' +import store from './store' +import { getAllMessages } from './store/actions' + +const app = createApp(App) + +app.use(store) + +app.mount('#app') + +getAllMessages(store) diff --git a/examples/chat/components/App.vue b/examples/classic/chat/components/App.vue similarity index 100% rename from examples/chat/components/App.vue rename to examples/classic/chat/components/App.vue diff --git a/examples/chat/components/Message.vue b/examples/classic/chat/components/Message.vue similarity index 71% rename from examples/chat/components/Message.vue rename to examples/classic/chat/components/Message.vue index db78157c0..0c1f2e92c 100644 --- a/examples/chat/components/Message.vue +++ b/examples/classic/chat/components/Message.vue @@ -2,7 +2,7 @@
  • {{ message.authorName }}
    - {{ message.timestamp | time }} + {{ time(message.timestamp) }}
    {{ message.text }}
  • @@ -13,6 +13,11 @@ export default { name: 'Message', props: { message: Object + }, + methods: { + time (value) { + return new Date(value).toLocaleTimeString() + } } } diff --git a/examples/chat/components/MessageSection.vue b/examples/classic/chat/components/MessageSection.vue similarity index 100% rename from examples/chat/components/MessageSection.vue rename to examples/classic/chat/components/MessageSection.vue diff --git a/examples/chat/components/Thread.vue b/examples/classic/chat/components/Thread.vue similarity index 71% rename from examples/chat/components/Thread.vue rename to examples/classic/chat/components/Thread.vue index 3794241ce..af5359515 100644 --- a/examples/chat/components/Thread.vue +++ b/examples/classic/chat/components/Thread.vue @@ -1,11 +1,11 @@