Comments (19)
@SilentDepth 'vuex' is designed with the old API. We may expect something like this in the future:
import { useStore, useComputed } from 'vuex';
setup (props, { root }) {
const store = useStore();
const filed = useComputed('state.filed');
}
You can create a useStore
now.
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
export function userStore() {
return store;
}
from composition-api.
Hi, everyone, I created a vue-hooks repository and package.
It contains commonly used hooks (e.g: vuex
/ vue-router
).
Documentation has not been written yet, welcome everyone to contribute! 😄
from composition-api.
The api for accessing the store and the router haven't yet been decided upon because they may improve for Vue 3. However, the current version to use for Vue 2 is through the root
: root.$store
/root.$router
in the context or creating your own useStore
/useRouter
functions that return the exported instance created in store.js
/router.js
but these are not reliable on SSR:
As pointed out here
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
export function userStore() {
return store;
}
const router = new Router({
// ...
})
export function useRouter() {
return router
}
A compatible solution that works on SSR would rely on provide
, meaning that the Root component also needs to inject
the store and the router
from composition-api.
I've made vuex-composition-api that helps with incorporating Vuex by providing typesafe modules using syntax inspired by this api.
from composition-api.
My example of usage mapXXX
helpers and router
.
// template
<section class="">
<p>{{ cubical() }}</p>
<p>{{ double() }}</p>
<p>{{ state.counter }}</p>
<button
type="button"
@click="increment(1)"
>
increment
</button>
<button
type="button"
@click="goHome({ foo: 'bar' })"
>
goHome
</button>
</section>
// script.ts
import {
computed,
reactive,
createComponent,
watch,
onMounted,
} from '@vue/composition-api';
import { mapGetters, mapActions, mapMutations } from 'vuex';
import { Route, Location } from 'vue-router/types';
import { useStore } from '@/store';
import { useRouter } from '@/router';
import { useI18n } from '@/i18n';
import {
mutations,
getters,
modules,
actions,
} from '@/store/types';
export default createComponent({
props: {},
setup(props, { emit }) {
console.log('setup');
console.time('mounted');
const state = reactive({
counter: computed(() => useStore().state.Counter.value),
});
const { cubical, double } = mapGetters(modules.COUNTER, [
getters.COUNTER.CUBICAL,
getters.COUNTER.DOUBLE,
]);
const { increment } = mapActions(modules.COUNTER, [
actions.COUNTER.INCREMENT,
]);
const { INCREMENT } = mapMutations(modules.COUNTER, [
mutations.COUNTER.INCREMENT,
]);
onMounted(() => console.timeEnd('mounted'));
return {
state,
double,
cubical,
increment,
};
},
};
from composition-api.
I'm now doing things like this:
setup (props, ctx) {
const $store = ctx.root.$store
const $router = ctx.root.$router
// ...
}
I think we need a better way to access those "globally-available" members. Maybe auto-inject into ctx
?
from composition-api.
There seem to be a dependency cycle issue in the following case :
// router.js
import Home from '@/views/Home.vue'
const router = new Router({
// ...
routes [
{ path: '/', component: Home, ... }
]
})
export function useRouter() {
return router
}
// something.js
import { userRouter } from '@/router'
export function useSomething() {
// using router...
}
// Home.vue
import { useSomething } from 'somewhere'
export default {
setup() {
return {
...userSomthing()
}
}
}
Home.vue imports Something.js imports Router.js imports Home.vue imports Something.js ...
Any solutions ? There's a VScode alert on this
from composition-api.
What if Vue is going to run in SSR mode and for each request we have to build new router, how it is possible to return router
from the imported useRouter
?
PS. Question is for Vue 3.x Composition API.
from composition-api.
I've made vue2-helpers that provides vuex@4 and vue-router@4 composition api in Vue2.
Example:
import { useRouter } from 'vue2-helpers/vue-router';
import { useStore } from 'vue2-helpers/vuex';
const router = useRouter();
router.push('/login');
API:
Vuex API | Vue-Router API |
---|---|
createStore | createRouter |
useStore | onBeforeRouteLeave |
onBeforeRouteUpdate | |
useRoute | |
useRouter |
from composition-api.
Thanks, @SilentDepth it really help me, but I change a little bit your code, I destructure the context data, It's a bit shorter... but it's still a workaround, I think...
setup (props, { root }) {
const fields = computed(() => root.$store.state.fields)
}
from composition-api.
@cdmoro Yes it's a workaround. Also it loses the real component context, so if you apply a different store
in component options you may never be able to access that (since you can only access members of root
or parent
).
We need more info on this. What makes me confused is that no one discussed this situation in the original RFC thread. Am I missing something? 🤪
from composition-api.
@liximomo You're right. Vuex should evolve to provide function-based API just like Vue 3.
from composition-api.
I had to implement my own mapState and mapActions. Suggestions?
import { computed } from 'vue-function-api';
import { isNil, isPlainObject } from 'lodash-es';
export const mapState = (states, store, moduleId) => {
Object.keys(states).forEach(key => {
const closure = states[key];
const state = !isNil(moduleId) ? store.state[moduleId] : store.state;
states[key] = computed(() => closure(state));
});
return states;
};
export const mapActions = (actions, { dispatch }, moduleId) => {
if (isPlainObject(actions)) {
Object.keys(actions).forEach(key => {
const action = actions[key];
const base = !isNil(moduleId) ? moduleId : '';
actions[key] = arg => dispatch(`${base}/${action}`, arg);
});
} else {
const mappedActions = {};
actions.forEach(action => {
const base = !isNil(moduleId) ? moduleId : '';
mappedActions[action] = arg => dispatch(`${base}/${action}`, arg);
});
actions = mappedActions;
}
return actions;
};
from composition-api.
@AlexQuidditch you did everything in one file (scripts.ts), but when you need to reuse logic in multiple components, that's when things get messy. Reuse of logic is the main goal of composition API, else it wouldn't be so useful.
from composition-api.
My example of usage
mapXXX
helpers androuter
.// template <section class=""> <p>{{ cubical() }}</p> <p>{{ double() }}</p> <p>{{ state.counter }}</p> <button type="button" @click="increment(1)" > increment </button> <button type="button" @click="goHome({ foo: 'bar' })" > goHome </button> </section>
// script.ts import { computed, reactive, createComponent, watch, onMounted, } from '@vue/composition-api'; import { mapGetters, mapActions, mapMutations } from 'vuex'; import { Route, Location } from 'vue-router/types'; import { useStore } from '@/store'; import { useRouter } from '@/router'; import { useI18n } from '@/i18n'; import { mutations, getters, modules, actions, } from '@/store/types'; export default createComponent({ props: {}, setup(props, { emit }) { console.log('setup'); console.time('mounted'); const state = reactive({ counter: computed(() => useStore().state.Counter.value), }); const { cubical, double } = mapGetters(modules.COUNTER, [ getters.COUNTER.CUBICAL, getters.COUNTER.DOUBLE, ]); const { increment } = mapActions(modules.COUNTER, [ actions.COUNTER.INCREMENT, ]); const { INCREMENT } = mapMutations(modules.COUNTER, [ mutations.COUNTER.INCREMENT, ]); onMounted(() => console.timeEnd('mounted')); return { state, double, cubical, increment, }; }, };
does it work correctly with 3.0.1 vuex?
cuz I've still had an error when using vuex's mappers:
TypeError: Cannot read property '$store' of undefined
at mappedAction (vuex.esm.js?2f62:952)
But I've made some custom helpers to fix it:
// heplers/vuexMappers.js
export const _mapGetters = (store, namespace, keys) => {
return keys.reduce((acc, key) => {
acc[key] = computed(() => store.getters[`${namespace}/${key}`]);
return acc;
}, {});
};
export const _mapActions = (store, namespace, keys) => {
return keys.reduce((acc, key) => {
acc[key] = (atrs) => store.dispatch(`${namespace}/${key}`, atrs);
return acc;
}, {});
};
export const _mapMutations = (store, namespace, keys) => {
return keys.reduce((acc, key) => {
acc[key] = (atrs) => store.commit(`${namespace}/${key}`, atrs);
return acc;
}, {});
};
// COMPONENT
import { _mapGetters, _mapActions, _mapMutations } from '@/helpers/vuexMappers';
const setup = (props, { root }) => {
...
const { GETTER_NAME } = _mapGetters(root.$store, 'namespace', ['GETTER_NAME']);
...
}
from composition-api.
I can't remember it :)
It looks like Composition API approach does not provides any helpers by design. If you will check documentation, you'll be able to see it clearly.
from composition-api.
I can't remember it :)
It looks like Composition API approach does not provides any helpers by design. If you will check documentation, you'll be able to see it clearly.
you need to have vue v3 to use vuex v4 unfortunately and use that documentation
from composition-api.
In Vue 2.x we can use this.$store and this.$router, inside setup, we should use context.store or something? The only way I could use it is import the store in every SFC, but I prefer have global access, like in Vue 2.x if it's possible... thanks!
you can use this pkg vue-composition-wrapper。this let you can do useStore
, useRouter
, useRoute
and useContext
in vue2.
from composition-api.
Stale issue message
from composition-api.
Related Issues (20)
- Typing component refs HOT 2
- onMounted is called when there is no active component instance to be associated with HOT 7
- Variables created with ref in <templete>,do not automatically expand value HOT 4
- why setup run twice in vue2 HOT 8
- setup function provide a wrong prop type,when use type: Function HOT 3
- not work nice in web component, no error HOT 2
- How to avoid duplicate register composition-api ? HOT 1
- It doesn't work with nuxt 2 HOT 2
- watch 的回调如果发生错误,会一直触发调用 HOT 1
- ComponentRenderProxy类型与Vue不兼容,导致Ts编译报错 HOT 2
- vue2项目, 怎么在option API的基础上, 混用composition API? HOT 1
- render 函数中使用 web components 自定义标签,移除了HTML中原生的 slot 属性 HOT 3
- No support for Vue >= 2.7
- cdn方式引入导致vue devtools调试数据丢失 HOT 2
- 客户端使用vuecli 打包出来的commonjs模式的库,出现“Error: [vue-composition-api] must call Vue.use(VueCompositionAPI) before using any functio” HOT 2
- setup返回的data在development环境下会被expose到全局mixin的data中 HOT 2
- 是否有提供withDefaults?
- 安装时,报vue版本范围错误 HOT 2
- 【Bug】Memory Leak cause by toVue3ComponentInstance HOT 1
- 【BUG】watch() 传入reactive类型的数据,vue3.4与3.3表现不一致 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from composition-api.