Enhancing Vue.js functionality with extra information stored in local storage

I've created a To Do List app where you can add tasks using a button. Each new task is added to the list with a checkbox and delete button in front of it. I'm trying to save all the values from the inputs and the checked checkboxes on the page once it's refreshed using the browser. Currently, I have implemented the use of mounted and watch functions, but it only stores the input values and not the checked checkboxes. Can someone help me fix this issue? Below is my code:

Vue.createApp({
    data(){
        return{
          placeholder: 'Start typing',
          inputvalue: '',
          notes: [],
          checked: []
        }
    },
    mounted() {
  try {
    this.notes = JSON.parse(localStorage.getItem('note'))
  } catch(e) {
    this.notes = []
  }
},
      watch: {
            notes: {
                handler: function() {
                    localStorage.setItem('note', JSON.stringify(this.notes));
                },
                deep: true
            }
        },
    methods: {
        addnewtask(){
            if (this.inputvalue !== ''){
                this.notes.push(this.inputvalue)
                this.inputvalue=''
            }
        },
        removetask(index){
            if (confirm('Do you really want to delete?'))
            this.notes.splice(index, 1)
        }
    }
}).mount(app)
body {
    font-family: sans-serif;
    font-size: 14px;
    color: #030303;
    background: #3d5f82;
}
h1 {
    font-weight: 500;
    text-transform: uppercase;
    text-align: center;
    font-style: solid;
}
.btn {
    color: #31d78c;
    place-content: center;
    place-items: center;
    width: fit-content;
    border-radius: 99px;
    border: 1px solid #31d78c;
    text-decoration: none;
    text-transform: uppercase;
    margin-right: 10px;
    margin-top: 10px;
    padding: 10px;
    font-weight: 700;
    background: #fff;
}
.btn:hover {
    cursor: pointer;
    background-color:rgb(231, 239, 235);
}
.btn.danger {
    color: #eb3c15;
    place-content: center;
    place-items: center;
    width: fit-content;
    border-radius: 99px;
    border: 1px solid #eb3c15;
    text-decoration: none;
    text-transform: uppercase;
    margin-right: 10px;
    margin-top: 10px;
    padding: 10px;
    font-weight: 700;
    background: #fff;
}
.btn.danger:hover {
    cursor: pointer;
    background-color:rgb(236, 219, 219);
}
.container {
    margin: 0 auto;
    max-width: 1000px;
}
.form-control {
    position: relative;
    margin-bottom: 10px;
}
.form-control input,
.form-control select {
    margin: 0;
    outline: none;
    border: 2px solid #ccc;
    display: block;
    width: 95%;
    color: #2c3e50;
    padding: 0.5rem 1.5rem;
    border-radius: 3px;
    font-size: 1rem;
}
.card {
    overflow: hidden;
    padding: 1rem;
    margin-bottom: 1rem;
    border-radius: 10px;
    box-shadow: 2px 3px 10px rgba(0, 0, 0, 0.2);
    background: #fff;
}
.card.center {
    display: flex;
    flex-direction: column;
    align-items: center;
}
.list {
    margin: 0;
    padding: 0;
    list-style: none;
}
.list-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 0;
    transition: .22s all;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To Do List</title>
</head>
<link rel="stylesheet" href="style.css">
<style>
    [v-cloak] {
        display:none;
    }
</style>
<body>
    <div class="container" id="app" v-cloak>
      <div class="card">
          <h1>To Do List</h1>
          <div class="form-control">
             <input
                 type="text" 
                 v-bind:placeholder="placeholder" 
                 v-model="inputvalue"
                 v-on:keypress.enter="addnewtask"
              />
              <button class="btn" v-on:click="addnewtask">Add Task</button>
            </div>
            <hr />
            <ul class="list" v-if="notes.length !== 0"...>
                <li class="list-item" v-for="(note, index) in notes" v-bind:key="note">
                    <div>
                        <input type="checkbox" v-model="checked[note]"/>
                        <span :style="checked[note] ? 'text-decoration: line-through' : ''">
                            {{index+1}}) {{note}}
                        </span>
                    </div>
                    <button class="btn danger" v-on:click="removetask(index)">Delete</button>
                </li>
                <hr />
                <li>
                    <strong>Total: {{notes.length}}</strong>
                </li>
            </ul>
            <div v-else>No task exist, please add first one.</div>
      </div>
    </div>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="Vue3.js"></script>
</body>
</html>

Answer №1

My suggestion would be to integrate the checkbox value into your items array rather than keeping track of selected items separately. Here's an example of how you could structure this array:

[
  {
    title: "Title",
    selected: true
  }
]

You can then use the item.selected property within your checkbox to indicate whether it is selected or not.

Additionally, instead of manually storing data in localStorage, I recommend utilizing Vuex with localStorage (https://medium.com/js-dojo/how-to-permanently-save-data-with-vuex-localstorage-in-your-vue-app-f1d5c140db69)

You can configure it so that your Vuex state is automatically saved in localStorage, allowing it to be reloaded back into your state upon page refresh. I hope this information proves helpful!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Vue - Utilizing mapState in Vuex to display the contents of the first object within an array

I am trying to display the names array from the first object in players using mapState with Vuex. Currently, the objects in players are listed based on their titles, but I want to filter them based only on the names in the first object for the current page ...

NextJS rewrites work seamlessly in a live environment

I recently implemented a method to rewrite requests to my backend server during development: https://nextjs.org/docs/api-reference/next.config.js/rewrites rewrites: async () => [ ...nextI18NextRewrites(localeSubpaths), { source: '/api/:path*' ...

retrieve dynamically generated content following successful login using cURL

It's common knowledge that curl doesn't process JavaScript, it only fetches static HTML. This is why a simple curl command won't suffice for my needs. I'm not well-versed in PHP, still new to this field. From what I've gathered so ...

Utilize AngularJS's OrderBy feature to iterate through the list for navigation in ascending order by Index

I am looking to customize the order of an Object-array using ng-repeat based on their index keys in ascending order. $scope.paneContainer = {books:[{}] } ; $scope.paneContainer.books[0].science = { title:"science", content:"web/app/views/partials/scienc ...

What advantages does incorporating "function() 'use strict'" into each individual file provide?

As I dive into revamping an older AngularJS 1.3 project, one striking observation is the consistent pattern of starting each AngularJS code file with: (function () { 'use strict'; angular.module('app').factory('Employees', ...

Having issues with retrieving data using findOne or findById in Express and Node JS, receiving undefined values

Currently, I am working on a microservice dedicated to sending random OTP codes via email. Below is the code for my findbyattr endpoint: router.get('/findbyattr/:email', async (request, response) =>{ try { let requestEmail = reque ...

Ways to collaborate on code among multiple projects

What is the most efficient way to share code between a React and Node.js application, both using vanilla JavaScript? Consider this snippet: function slugify(str) { return str.replace(/[^a-z0-9)(\.\-_\s]/gi, ""); } How can I implement t ...

Tips for Identifying Different ID Values of HTML Elements with jQuery

Currently, I have two different divs on my webpage, each containing buttons and hidden fields. When I try to pass the value of the hidden field attached to the button in a jQuery function, I encounter an issue where clicking on the second div results in pa ...

Substituting text in a document by utilizing two separate arrays: one holding the original text to be found and another storing the corresponding text for

I am facing a challenge with replacing specific text strings in a file. I have two arrays - one containing the strings that need to be located and replaced, and the other containing the replacement strings. fs.readFile("./fileName.L5X", "utf8", function( ...

Manipulating strings in Discord.js

if(msg.content.includes("[mid]")) { let str = msg.content let pokeID = str.substring( str.indexOf("[mid]") + 5, str.lastIndexOf("[/mid") //get the unique-code for a pokemon ); msg.channel.send ...

Could a personalized "exit page" confirmation be created?

I am looking for a solution that will allow me to pause the execution of my code, display a dialog box, and then resume execution only after a specific button is pressed. For example, if a user navigates from one page to another on my website, I want a di ...

Angular JS is encountering an issue where the promise object is failing to render correctly

I'm currently learning Angular and I have a question about fetching custom errors from a promise object in Angular JS. I can't seem to display the custom error message on my HTML page. What am I missing? Below is my HTML file - <!DOCTYPE htm ...

What is Angular's approach to handling elements that have more than one directive?

When an element in Angular has multiple directives, each specifying a different scope definition such as scope:false, scope:true, or scope:{}, how does the framework handle this complexity? ...

Unspecified OrbitControls Compatibility Issue between Angular2 and Three.js

I'm running into issues trying to set up OrbitControls in my Angular2 project. I managed to display a scene with a box, but I'm struggling to move the camera. Upon investigation, I found that my OrbitComponent, responsible for defining orbit con ...

Challenge in backward compatibility when converting from .on() to .live()

Struggling to make hammer.js work with an outdated 1.6 jQuery in my CMS. The function "on()" isn't available, so I have to use "live()". Here are the two instances: 1. var hammertime = new Hammer(element[0], { drag_lock_to_axis: true }); hammertime. ...

What is the best way to delete the "Click to sort Ascending" text from the header of each column in a bootstrap-vue table?

Recently, I came across a bootstrap-vue table that caught my attention: Below is the code snippet for the table setup: <template> <div class="container"> <h1 class="pt-2 pb-3">Bootstrap Table</h1> ...

Is there a way to transfer a significant volume of data from one webpage to another without relying on the POST

Currently, I am utilizing a web server framework that exclusively operates with GET requests. Presently, my task involves transferring a substantial volume of data (specifically the text content in a textarea) inputted by users onto another page where it i ...

Emphasize sections of text within a chart

Looking for a Specific Solution: I've encountered similar problems before, but this one has a unique twist. What I'm trying to achieve is to search for a substring within a table, highlight that substring, and hide all other rows (tr's) th ...

Is there a way to change the border property of an element when clicked, without causing the displacement of other elements?

I'm in the process of creating a webpage where users can choose the color and storage capacity of an item. Only one color/capacity can be selected at a time, and once chosen, it should be highlighted with a border. The issue I encountered is that whe ...

How to show ngFor value from Angular in a separate tag

I have a list of companies that I want to display in the following format: <div class="col-md-4"> <select ngModel="selectedCompany" style="width:400px;"> <option *ngFor="let x of mycompanylist&q ...