Answer a question

I'm fetching data from an API and want to achieve it via Vuex. So my users store module is holding and managing all users.

To fetch all users I have a fetch action which calls the API via Axios and passes the users array from the response to the mutation.

I have a view component at /users which renders a list of users. Within that component I call

async mounted() {
  await this.fetch();
}

to initialize the store. After that, the store getter will return the users array and the list gets rendered. I know that I can also fetch one item by id via getter

getById: state => id => state.users.find(user => user.id === id)

When navigating to a user detail page /users/:id I can make use of it, extract the userId via this.$router.currentRoute.params.id and render the user details. But what if I load that route directly? Then the store initialized with an empty users array and it won't find a single user.

So should I fetch all users again in the mounted hook of that user details view? I think calling the axios service directly would be an anti pattern because the resources say I should use Vuex as an interface between the component and the API.

Is there a best practise when to fetch all users from the api? Because let's image you navigate to another page which loads all users in a select component, should I fetch them from the getter? Maybe it will load a user that doesn't exist anymore. But polling all users every X seconds would be bad too...

What is the correct way to update the store data to make it accessible for all components in the entire application?

Answers

I don't agree that Vuex should be used to store an entire tables worth of user data in the manner you described. This sounds like a security concern to me. Remember that Vuex is a client-side store; meaning all your user data would be visible to any client using your application. You should never store sensitive data client-side.

Type this into your browser console, and you'll see what I mean.

document.getElementsByTagName('a')[0].__vue__.$store.state

Vuex should be used for storing non-sensitive data of an individual user required to drive their session.

If you are storing all user data for the purpose of listing accounts so that they can be managed by an admin or something, then I would instead, make that API call on demand when you load whatever view you have which lists your user accounts. This way you will always have the most up-to-date data, without the need for constantly polling your API.

I would paginate that data, loading only the first 5 records (to keep the API call initially light), then provide your admins the ability to search for accounts; that searching should be done server side, through your API.

Example:

methods: {
    fetchUsers(limit, page, search) {
        const thisIns = this;
        if (search) {
            this.userQuery = `/users/find?search=${search}`
        } else {
            this.userQuery = `/users/find?limit=${limit}&page=${page}`
        }
        thisIns.$http.get(this.userQuery)
            .then(async (response) => {
                console.log(response.data)
            })
            .catch(function (error) {
                console.log(error)
            });
    }
},
created() {
    this.fetchUsers(5, 1)
},

You can then call your fetchUsers() method as needed, such as when performing a search for user(s).

Since you are using Axios, you can also consider implementing a caching mechanism, axios-cache-adapter, so that your API calls are cached for some period of time you define. This would reduce the number of API calls hitting your server.

I also don't consider this to be scaleable. Remember that an application user will have to wait for this payload when they first load your app. This also has performance implications; as your user data grows over time, you'll be consuming more and more of the devices RAM.

Logo

Vue社区为您提供最前沿的新闻资讯和知识内容

更多推荐