Determining button click events in VueJS using the Watch method

Creating a feature for undo/redo in VueJS involves watching the settings and adding a new element to an array of changes when there is a setting change. Additionally, there is a method for undoing actions when the corresponding button is clicked.

An issue arises when clicking the undo button and reverting the last setting update triggers the watch function again.

To address this problem, how can we prevent adding a new element to the changes array if the settings changed due to the Undo button being clicked?

(function () {

var Admin = {};
Admin.init = function () {

};

var appData = {
    settings: {
        has_border: true,
        leave_reviews: true,
        has_questions: true
    },
    mutations: [],
    mutationIndex: null,
    undoDisabled: true,
    redoDisabled: true
};

var app = new Vue({
    el: '#app',
    data: appData,
    methods: {
        undo: function() {
            if (this.mutations[this.mutationIndex - 1]) {
                let settings = JSON.parse(this.mutations[this.mutationIndex - 1]);
            
                this.settings = settings;
                this.mutationIndex = this.mutations.length - 1;
                
                console.log (settings);
            }
        },
        redo: function() {
            
        }
    },
    computed: {
        border_class: {
            get: function () {
                return this.settings.has_border ? ' rp-pwb' : ''
            }
        },
        undo_class: {
            get: function () {
                return this.undoDisabled ? ' disabled' : ''
            }
        },
        redo_class: {
            get: function () {
                return this.redoDisabled ? ' disabled' : ''
            }
        }
    },
    watch: {
        undoDisabled: function () {
            return this.mutations.length;
        },
        redoDisabled: function () {
            return this.mutations.length;
        },
        settings: {
            handler: function () {

                let mutation = JSON.stringify(this.settings),
                    prevMutation = JSON.stringify(this.mutations[this.mutations.length-1]);

                  if (mutation !== prevMutation) {
                      this.mutations.push(mutation);
                      this.mutationIndex = this.mutations.length - 1;
                      this.undoDisabled = false;
                 }
            },
            deep: true
        }
    }
});

Admin.init();
})();

Answer №1

By incorporating a button click to make changes, you have the option to create a method for achieving your objective rather than relying on watchers.

methods: {
   customSettings() {
      // Implement this method in undo and redo methods if certain conditions are met.
      // Transfer the watcher code to this custom method.
   }
}

In addition, If you choose not to utilize setter in computed properties, omitting getters will suffice:

borderStyle() {
    return this.customSettings.hasBorder ? ' rp-pwb' : ''
},

These watcher codes could be better suited as part of computed properties:

disableUndo() {
    return this.changes.length;
},
disableRedo() {
    return this.changes.length;
},

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

Implementing the row delete function in MUI DataGrid using JavaScript

My grid has a delete icon button in each row, but it's not deleting the row. Can someone please help me with this issue? I'm working on a todo app where each row should have its own delete button. I'm struggling to connect the deleteTodo co ...

Unraveling and interpreting all incoming requests to my Node.js application

Looking for a simple method to identify and decipher all encoded characters in every URL received by my Node.js application? Is it possible to achieve this using a middleware that can retrieve and decode symbols such as & ? ...

displaying 'undefined' upon completion of iterating through a JSON file using $.each

For my project, I am attempting to extract only the date data from a JSON object. I have successfully looped through the object and displayed it, but the issue arises at the end of the loop where it shows undefined. I am not sure what mistake I am making. ...

Navigate through stunning visuals using Bokeh Slider with Python callback functionality

After being inspired by this particular example from the Bokeh gallery, I decided to try implementing a slider to navigate through a vast amount of collected data, essentially creating a time-lapse of biological data. Instead of opting for a custom JavaS ...

Does Vuejs emit an event when a specific tab becomes active in boostrap-vue?

I am looking for a way to display and hide a section on my page when a specific tab is active, and close it when the tab is inactive. I have tried using the forceOpenSettings and forceCloseSettings methods for opening and closing the div. Is there an event ...

Tips for automatically closing all other divs when one is opened

I have multiple divs structured like this: <div id="income"> <h5 onclick="toggle_visibility('incometoggle');">INCOME</h5> <div id="incometoggle"> <h6>Income Total</h6> </div> </div> <d ...

The v-show directive is not activated by a Vuex commit

I am experimenting with vuex for the first time, and I have come across an issue where a v-show directive is not triggering after a mutation commit on the store. // store.js import Vue from "vue" import Vuex from "vuex" const states = ...

The React DOM element undergoes mounting and unmounting on each render cycle when it should be simply altered/updated

As per the React documentation, callback refs are invoked during both component mounting (with the DOM element's value) and unmounting (with null): When a React component mounts, the ref callback is triggered with the actual DOM element, and when it ...

What methods can be used to control the URL and back button in a web application designed similar to an inbox in Gmail?

Similar Question: Exploring AJAX Techniques in Github's Source Browser In my application, there are essentially 2 main pages: The main page displays a list of applications (similar to an inbox) The single application page is packed with various ...

Material-UI Scroll Dialog that begins scrolling from the bottom

While attempting to incorporate a scrolling div with the ref tag inside Dialog Material-UI Design, I encountered an error stating Cannot read property 'scrollHeight' of undefined When running my code outside of the Dialog, it functions correctly ...

Calculating the sum() of a specific attribute in Loopback without the need to iterate through every instance of the object

Within my DummyModel, there are attributes named attOne, attTwo, and attThree. If we want to retrieve all instances of attOne, we can utilize the following query: DummyModel.find({where: {attTwo: 'someValue'}, fields: {attOne: true} }); The ab ...

Steps to avoid reinitializing the component upon changing routes in an Angular 9 component

In my component, the width of a chart is stored in a variable (because I can't use style for d3). However, every time the route changes, all variables in this class component become undefined. I have tried using ngIf, services (which also become unde ...

A feature to reveal additional content when it extends beyond a single line

<div class="questionnaire-description col-xs-12" id="questionnaire_description_wrapper"> <text-truncate> <span ng-class="questionnaire_description.show_more ? 'full-description' : 'ph-ellips ...

Incorporating a template or component into the Vue.js router.js

If someone can provide me with an answer on how to import templates into route.js in Vue.js, I would greatly appreciate it:) Here is my HTML: <head> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="h ...

Surprising outcome of Vue

As a newcomer to vue.js, I am struggling with a side effect issue in a computed property. The unexpected side effect error is popping up when running the code below, and ESlint is pointing it out in the console. I understand the concept of side effects, bu ...

A step-by-step guide on showcasing Flickr images through API using a Justified Gallery

I am looking to integrate the Miromannino Justified Gallery () into my project, but I want it to showcase images fetched from Flickr. I have successfully implemented the code to retrieve photos from Flickr using the API through Ajax: $.ajax({ url ...

Obtain all the selection choices in a dropdown list using Selenium

Although I have come across similar questions, this one is distinct in its simplicity. Unlike other queries that involve iterating over options in a loop, my question revolves around the usage of the getOptions() method mentioned in Selenium documentation. ...

Terminate a targeted recipient following the completion of the on event

I am currently running a node service with socket.io and utilizing an event emitter to send updates based on user context. For example, context A may have users 1, 2, and 3 while context B has users 4 and 5. Once a successful connection is established wit ...

How can I swap a string for a symbol in JavaScript?

Is there a way to convert the text @abc some text here to <a href="some_url">@abc</a> some text here using JavaScript? Are there any libraries that can help with this task? ...

Tips for improving the performance of the JavaScript code mentioned

Can you assist with optimizing the code below? The question at hand is whether all values in this array need to be checked to see if two of them sum up to 8. If yes, then we should identify the indexes of these values. const arr = [1, 2, 3, 4, 5]; const ...