Exploring the Power of Vue.js 3.0: Leveraging Two-Way Data Binding Through the Composition

Currently, I am delving into creating a Vue.js application with Vue.js 3.0 to get acquainted with the Composition API. The simplicity of two-way data-binding in Vue.js 2.0 was one of its standout features for me. However, transitioning to the Composition API has left me uncertain about how to employ it, particularly when dealing with global state. For instance, within my app, there are two components illustrated in this Fiddle. Here's some code snippets:

HTML

<div id="my-vue" class="demo">
  <banner :class="{ 'even-banner': isEven, 'odd-banner': !isEven }"></banner>
  <hr />
  <content :class="{ 'even-content': isEven, 'odd-content': !isEven }"></content>
  <pre>value={{value}} isEven={{isEven}}</pre>
</div>

JavaScript

const store = {
  state: Vue.reactive({
    result: null
  }),
  generateNewValue() {
    this.state.result = Math.floor(Math.random() * 10);
  }
};

const MyApp = {
  setup() {
    const isEven = Vue.computed(() => store.state.result % 2 === 0)
    const value = Vue.toRef(store.state, 'result')
    return {
      isEven,
      value
    }
  }
}
const myApp = Vue.createApp(MyApp)

myApp.component("banner", 
  { 
    template: '<button @click="onGenerateClick">generate</button>',
    setup(props) {
      console.log('setting up...');
    },
    methods: {
      onGenerateClick() {
        store.generateNewValue();
      }
    }
  }
);

myApp.component("content", {
  template: '<div style="padding:2rem;">' +
    '<div>Enter Value: <input type="text" v-model="result" /></div>' +
    '<br /><div>or</div><br />' +
    '<div><button @click="onGenerateClick">generate</button></div>' +
    '</div>',
  methods: {
    onGenerateClick() {
      store.generateNewValue();
    }
  }  
});

myApp.mount('#my-vue')

CSS

.even-banner {
  background-color:navy;
  color: #fff;
}

.even-content {
  background-color:blue;
  color: #fff;
}

.odd-banner {
  background-color:maroon;
  color:#fff;
}

.odd-content {
  background-color:red;
  color:#fff;
} 

The concept behind the design is straightforward - blue backgrounds for even numbers and red backgrounds for odd numbers. There is a "generate" button that functions correctly. Nevertheless, there is a text field where an input value can be manually entered, but unfortunately, it does not change the background color as intended. It appears as though two-way binding is faltering.

How can I implement two-way data binding effectively with a global state in a Vue.js application utilizing the Composition API?

Answer №1

It seems like your text input is not properly connected to the store value, as it is referring to a non-existent data property called result. You can try injecting the store into the component and then adding a getter/setter to bind the property.

myApp.component("content", {
store,
  template: '<div style="padding:2rem;">' +
    '<div>Enter Value: <input type="text" v-model="myAmount" /></div>' +
    '<br /><div>or</div><br />' +
    '<div><button @click="onGenerateClick">generate</button></div>' +
    '</div>',
    computed:{
        myAmount:{
      get: function(){return store.state.result},
      set: function(val){store.state.result = val}
      }
    },
  methods: {
    onGenerateClick() {
      store.generateNewValue();
    }
  }  
});

By the way, please note that using my setter is just a temporary solution. In practice, it's advisable not to directly update the store.state property. However, this should help you get started with the functionality you need.

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

Adapting iFrame height to accommodate fluctuating content height in real time (details included)

I have an embedded iframe that contains a form with jQuery validation. When errors occur, the content height of the iframe increases dynamically. Below is the script I use to adjust the height of my iframe based on its content: function doIframe(){ o = d ...

How can I send a Vue.js object to a Laravel controller?

I am working with a Vue component that includes an object like this - dataObj = [{id:1,name:'sanaulla'},{id:1,name:'parvez'}] When I try to send a post request to the Laravel Controller using the following code - axios.post("/api/ ...

Swap out a picture with one that has been uploaded

Can anyone help me with an issue I'm having regarding image uploading? I am currently using an HTML file upload form along with a jQuery function to check the file type of any image selected by the user. My goal is to replace the existing image on a w ...

What could be causing my express router.get endpoints with multiple paths to only render text?

Currently, I am in the process of configuring a password reset flow using Pug (formerly Jade) and Express. Oddly enough, GET requests that contain URLs with multiple appended paths are causing my Pug view files to render with only text. The images and sty ...

Displaying the number of tasks completed compared to the total number of tasks within a JavaScript ToDo list

Currently, I'm in the process of creating a basic ToDo list using HTML, JS, and CSS. The last task on my list is to display to the user the total number of tasks and how many have been completed. For instance, if there are 3 completed tasks out of 7 i ...

Is there a way to make a text area move along with the mouse cursor?

I have been working on my first website and everything is running smoothly so far. However, I have a new idea that I am struggling to implement. Some of the pages on my site feature a video player with buttons to select different videos. When a viewer hove ...

Setting the date in a datetimepicker using the model

I've encountered an issue while trying to utilize the angular date time picker. It seems that when I load data from the model, the picker does not bind the value correctly. If I manually set the value to a date, it works fine. However, when the data ...

Retrieve and display the total from a specific column in Vue using an API

I have an API that retrieves the total sum from a column in MySQL and returns it as JSON data. My goal is to display this data using Vue JS. $stmt = $db->prepare("SELECT ROUND(SUM(total_amount), 2) as TotalAmount FROM orders"); $result = $stm ...

Embedding an image into a component in React Native

Currently, I am utilizing a library called select multiple buttons and I have successfully customized it to my needs. However, I now have the requirement to include an image within this component. const multipleData = [button1, button2, button3, button4, ...

Utilizing AJAX to dynamically load file references and embed iframes

Is the use of multiple iframes on a website impacting its loading speed? Also, regarding AJAX, let's say I have two JSP pages. The first one contains an AJAX call to the second JSP page. Both pages have JavaScript functions with the same name, let&apo ...

Angular allows for the dynamic inclusion and exclusion of components, providing a flexible

In my setup, I have a container that houses two distinct components. The first component receives a list of users from the backend. Upon clicking on a specific user, I aim to display all of their detailed information in the main container of the second co ...

Using Three.js to Spin Cylinder Towards a Vector3 Destination

I've attempted a thorough search, but unfortunately, I haven't come across any solutions that address my issue: I have a vector and a CylinderGeometry Mesh. My goal is to make the cylinder face the direction indicated by the vector. The input pa ...

Issue encountered: Cannot locate module: Error message - Unable to find 'stream' in 'C:devjszip-test ode_modulesjsziplib' folder

I am encountering an issue in my angular 7 application while using jszip v3.2.1. During the project build process (e.g., running npm start), I receive the following error message: ERROR in ./node_modules/jszip/lib/readable-stream-browser.js Module not fo ...

When an Axios response is received, the console logs an error message

Whenever I try to console.log(response) from json placeholder, an error message pops up stating that there is an "Unexpected console statement". Below is the code snippet: import axios from 'axios'; export default { name: 'app', ...

Implementing Undo and Redo functionality in Vuex by capturing and restoring state snapshots

Overview I have developed an undo-redo feature for a plugin, which follows the steps outlined below. Implemented Steps (General) Add the previous state snapshot on every action taken. Undo using a customized replaceState method with the previousState as ...

Storage in private Safari mode is not synced between tabs on mobile devices

In the private mode of mobile Safari, I have successfully stored data in the localStorage. However, when I open my web app in two separate tabs, I notice that the data stored in one tab is not accessible in the other tab. This behavior may be present in ot ...

Working with Ext JS: Dynamically adjusting panel size when the browser window is resized

I am facing an issue with a side panel in Ext.js. Everything is working fine until I resize the browser, at which point some components of the panel get cut off. https://i.sstatic.net/eaEGI.png Is there a way to make the panel resize automatically when t ...

Transferring shapes from a two-dimensional equirectangular view to surfaces in A-Frame

Currently, my goal is to create a hotspot editor for 360-degree images using A-Frame. The concept behind this project involves allowing users to draw on an equirectangular panorama and then having the tool convert those drawings into planes using THREE.Sh ...

How can I import tamplateData into my JavaScript files in Docpad?

Looking for a DocPad plugin that can preprocess JS files and utilize templateData variables and helpers to access configuration values. While experimenting with Hogan, I managed to retrieve the variables but encountered difficulty in invoking the helpers. ...

Calculate the number of views using Laravel and VueJS

Looking for assistance with tracking the number of visits to each article on my Laravel and Vue-based articles site. Previously used eloquent-viewable package in Laravel, but unsure how to implement in Laravel + Vue. Can anyone provide guidance on this? ...