DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
11 Monitoring and Observability Tools for 2023
Learn more
  1. DZone
  2. Data Engineering
  3. Data
  4. Key-Value Local Storage in a Vue.js NativeScript App With Vuex

Key-Value Local Storage in a Vue.js NativeScript App With Vuex

We take a look at the Vuex state manager and how to use it with key-value local storage in a Vue application.

Nic Raboy user avatar by
Nic Raboy
·
May. 15, 19 · Tutorial
Like (1)
Save
Tweet
Share
9.66K Views

Join the DZone community and get the full member experience.

Join For Free

If you've ever built a Vue.js application, whether that be web or mobile, you've probably come across Vuex when searching for data storage-related information. When it comes to the web, the common tutorial around Vuex includes browser local storage or similar, where Vuex handles all of the state rules between components.

With NativeScript supporting Vue.js, this opens the door to what we can do for mobile development, but how do we handle data under these circumstances? NativeScript doesn't use a browser so local storage isn't an option.

We're going to see how to manage data in an Android and iOS mobile application built with NativeScript and Vue.js. This application will leverage the power of Vuex and NativeScript's built in Application Settings module.

Before we get into the code, let's take a step back and figure out what each of our proposed modules offer us when it comes to building a mobile application with NativeScript.

Per the Vue.js website, Vuex can be described as the following:

Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.

There are many different ways to store data in a NativeScript application. For this example, we'll be using key-value storage made possible by the Application Settings module which uses SharePreferences on Android and NSUserDefaults on iOS. In a future tutorial we'll explore how to use SQLite or similar.

This tutorial was actually inspired by a web tutorial I read titled, Vue: Using localStorage with Vuex Store.

Creating a NativeScript With Vue.js Project That Supports Vuex

For this tutorial to be successful, you'll need NativeScript installed and configured on your computer as well as the Vue CLI as outlined in the NativeScript documentation. The commands to create our project will be as follows:

vue init nativescript-vue/vue-cli-template vuex-project
cd vuex-project
npm install
npm run watch:ios

The above commands will create a project called vuex-project with the necessary dependencies. When creating the project, make sure that Vuex is enabled when prompted as it will make our lives easier. The defaults are fine for all other prompts in the configuration process.

Defining the Vuex State Logic

Now that we have a NativeScript with Vue.js project created and ready to go, we can focus on developing our Vuex logic for managing our application state. In my opinion, the generator used when creating a new project is a bit wonky. For this reason, we're going to go against the template a little in an effort to match what we'd see for Vue.js on the web.

In the project's src/store/index.js file, include the following JavaScript:

import Vue from 'nativescript-vue';
import Vuex from 'vuex';
import * as ApplicationSettings from "application-settings";

Vue.use(Vuex);

const store = new Vuex.Store({
    state: {
        firstname: "",
        lastname: ""
    },
    mutations: {
        load(state) {
            if(ApplicationSettings.getString("store")) {
                this.replaceState(
                    Object.assign(state, JSON.parse(ApplicationSettings.getString("store")))
                );
            }
        },
        save(state, data) {
            state.firstname = data.firstname;
            state.lastname = data.lastname;
        }
    }
});

Vue.prototype.$store = store;

module.exports = store;

Before we discuss what the above means, how about I mention what I've changed. Instead of referencing a module in the src/store/index.js file, I've included what would have been in the module, directly in the file.

So what is happening in the code above?

First, we're defining the data that can be managed in our store. We're going to be managing first name and last name information for this example, something that is rather simple. By default, the data will be empty.

We're defining two mutations that can be used to alter the state of the application.

load(state) {
    if(ApplicationSettings.getString("store")) {
        this.replaceState(
            Object.assign(state, JSON.parse(ApplicationSettings.getString("store")))
        );
    }
},

The load mutation will first check to see if anything was previously saved in what we're calling the store key. To keep our data flexible, we don't want to restrict ourselves to only what exists in our state variable. Instead, if data was previously saved, we are replacing the current state with a merged copy of what exists in the state and what exists in the storage. The replaceState function is part of the Vuex API.

save(state, data) {
    state.firstname = data.firstname;
    state.lastname = data.lastname;
}

The save mutation will take data committed to the mutation and save it in our state. You'll notice that we're not actually saving any data to storage in the Vuex controller, but we could. Instead, the actual saving will happen via a subscription in our component.

Building a Vue.js Component in NativeScript With Data Requirements

We want to see the Vuex magic in action and we also want to actually persist data rather than just manage while the application is open and being used. For this reason, we need to work on our component.

When you created your project, you probably had a src/components/Counter.vue file. You can either rename it, leave it as is, or create a new file. This is an example, so our naming conventions are not too important, but we won't be counting anything.

Open the component and include the following code:

<template></template>

<script>
    import * as ApplicationSettings from "application-settings";
    export default {
        data() {
            return {
                input: {
                    firstname: "",
                    lastname: ""
                }
            }
        },
        mounted() {
            this.$store.subscribe((mutations, state) => {
                ApplicationSettings.setString("store", JSON.stringify(state));
                this.input.firstname = state.firstname;
                this.input.lastname = state.lastname;
            });
        },
        methods: {
            save() {
                this.$store.commit("save", this.input);
            },
            load() {
                this.$store.commit("load");
            },
            clear() {
                this.input.firstname = "";
                this.input.lastname = "";
            }
        }
    };
</script>

You can see that I stripped out the <template> content for now because we want to focus on the <script> content. In short, this component will have a form and three buttons. We can save the content of the form, load the content of the form, or clear the content of the form. The form will allow for first name and last name input.

First, we want to initialize our variables in the data method. Next, when the application mounts, we want to subscribe to our Vuex store. This is where the actual saving happens. Any time our store changes, this subscription triggers which then persists our state and sets the form content. Remember, this isn't the only strategy towards saving data.

methods: {
    save() {
        this.$store.commit("save", this.input);
    },
    load() {
        this.$store.commit("load");
    },
    clear() {
        this.input.firstname = "";
        this.input.lastname = "";
    }
}

The save method will call the save mutation found in our Vuex file. We are passing the form input to this mutation. The load method will call the load mutation found in the Vuex file. Finally, the clear method will just wipe out our form in terms of UI, not saved data.

Now let's look at the <template> that I previously wiped out:

<template>
    <Page class="page">
        <ActionBar class="action-bar" title="Person"></ActionBar>
        <StackLayout class="form">
            <StackLayout class="input-field">
                <Label text="First Name" class="label font-weight-bold m-b-5" />
                <TextField class="input" v-model="input.firstname" />
                <StackLayout class="hr-light"></StackLayout>
            </StackLayout>
            <StackLayout class="input-field">
                <Label text="Last Name" class="label font-weight-bold m-b-5" />
                <TextField class="input" v-model="input.lastname" />
                <StackLayout class="hr-light"></StackLayout>
            </StackLayout>
            <GridLayout rows="auto, auto" columns="*, *">
                <Button text="Save" @tap="save" class="btn btn-primary" row="0" col="0" />
                <Button text="Load" @tap="load" class="btn btn-primary" row="0" col="1"  />
                <Button text="Clear" @tap="clear" class="btn btn-primary" row="1" col="0" colSpan="2"  />
            </GridLayout>
        </StackLayout>
    </Page>
</template>

In the <template> we have two form fields that are styled with the core NativeScript theme. They are bound using the v-model property to the data that we defined in our <script> block. Each of the @tap events on our buttons will call an appropriate function.

If you changed the file name or created a new file like I mentioned previously, don't forget to update the project's src/main.js file.

Conclusion

You just saw how to use Vuex and a form of persisted local storage in an Android and iOS application created with NativeScript and Vue.js. Like I previously mentioned, there are many ways to persist data in NativeScript, but the commonality is that you'll likely be using Vuex when it comes to management.

To see another example of Vuex, I have a web example titled, A Vue.js App using Axios with Vuex, that can easily be ported to NativeScript.

NativeScript Vue.js mobile app Data (computing) Form (document)

Published at DZone with permission of Nic Raboy, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • DevOps vs Agile: Which Approach Will Win the Battle for Efficiency?
  • Building the Next-Generation Data Lakehouse: 10X Performance
  • The Power of Zero-Knowledge Proofs: Exploring the New ConsenSys zkEVM
  • Authenticate With OpenID Connect and Apache APISIX

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: