Giter Club home page Giter Club logo

Comments (19)

liximomo avatar liximomo commented on April 27, 2024 70

@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.

u3u avatar u3u commented on April 27, 2024 24

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.

posva avatar posva commented on April 27, 2024 5

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.

PatrykWalach avatar PatrykWalach commented on April 27, 2024 5

I've made vuex-composition-api that helps with incorporating Vuex by providing typesafe modules using syntax inspired by this api.

from composition-api.

AlexQuidditch avatar AlexQuidditch commented on April 27, 2024 4

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.

SilentDepth avatar SilentDepth commented on April 27, 2024 2

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.

darkylmnx avatar darkylmnx commented on April 27, 2024 2

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
image

from composition-api.

dmitry avatar dmitry commented on April 27, 2024 1

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.

ambit-tsai avatar ambit-tsai commented on April 27, 2024 1

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.

cdmoro avatar cdmoro commented on April 27, 2024

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.

SilentDepth avatar SilentDepth commented on April 27, 2024

@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.

SilentDepth avatar SilentDepth commented on April 27, 2024

@liximomo You're right. Vuex should evolve to provide function-based API just like Vue 3.

from composition-api.

exodusanto avatar exodusanto commented on April 27, 2024

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.

darkylmnx avatar darkylmnx commented on April 27, 2024

@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.

chunkey711 avatar chunkey711 commented on April 27, 2024

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,
    };
  },
};

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.

AlexQuidditch avatar AlexQuidditch commented on April 27, 2024

@chunkey711

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.

Emobe avatar Emobe commented on April 27, 2024

@chunkey711

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.

yisibell avatar yisibell commented on April 27, 2024

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.

github-actions avatar github-actions commented on April 27, 2024

Stale issue message

from composition-api.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.