Mastering the Vue 3 Composition API: A guide to efficiently utilizing it across multiple Vue instances spread across different files

tl;dr What is the best way to import Vue3 in a base Javascript file and then utilize Vue's composition API in subsequent standalone files that will be loaded after the base file?


I incorporate Vue to improve user interactions on specific pages like the registration page. This involves handling ajax requests and displaying server errors without refreshing the entire page, creating mini single-page applications within a multi-page application...

In Vue2, importing Vue in the base file and utilizing Vue's options API in other files worked smoothly. The subsequent files remained concise as they only included logic relevant to that particular file.

However, with Vue3's composition API requiring imports such as

ref, reactive, watch, onMount...etc
, this leads to repetitive imports of Vue in the subsequent files. I tried to tackle this issue with the following approach:

// register.blade.php (excerpt)
<div id="root">
  <input type="text" name="first_name" v-model="FirstName">
  <input type="text" name="last_name" v-model="LastName">
// (before edit) <script src="main.js"></script>
// (before edit) <script src="register.js"></script>
  <script src="{{ mix('/main.js') }}"></script>
  <script src="{{ mix('/register.js') }}"></script>
</div>
// main.js (excerpt)
// (before edit) import Vue from 'node_modules/vue/dist/vue.js';
// (before edit) window.Vue = Vue;
window.Vue = require('vue');
// register.js (excerpt)
const app = Vue.createApp({
  setup() {
    const FirstName = Vue.ref('');
    const LastName = Vue.ref('');
    const FullName = Vue.computed(() => FirstName.value + ' ' + LastName.value);

    return {
      FirstName, LastName, FullName
    }
  }
});
app.mount('#root');

This method works well for this simple example, but I am unsure if using Vue. prefix is correct. Is it acceptable to access all the exposed functions by Vue in the setup() method using this syntax?

EDIT: I employ webpack with laravel mix. Although I omitted these details initially, they are essential. Comments indicate edits made to the initial code to prevent confusion.

// webpack.mix.js (excerpt)
mix.webpackConfig({
  resolve: {
    alias: {
      'vue$': path.resolve(__dirname, 'node_modules/vue/dist/vue.esm-bundler.js'),
    }
  }
});

mix.js('resources/main.js', 'public/main.js')
  .js('resources/register.js', 'public/register.js')
  .version();

Answer №1

When incorporating individual parts from Vue 3 (ref, watch, computed...) into your .js files, you won't experience any additional overhead. In fact, utilizing a bundler can aid in reducing the size of resulting files through tree shaking (as explained by Evan You).

Importing the entire Vue library and using it as before, similar to Vue 2, is perfectly fine. If you find the syntax cumbersome, consider destructuring what you need:

// register.js (contains)
const { ref, computed } = Vue;

const app = Vue.createApp({
  setup() {
    const FirstName = ref('');
    const LastName = ref('');
    const FullName = computed(() => FirstName.value + ' ' + LastName.value);

    return {
      FirstName, LastName, FullName
    }
  }
});

app.mount('#root');

UPDATE:

I'm not well-versed in Laravel Mix, but you could experiment with something like this:

// webpack.mix.js (contains)
const jsfiles = [
    'resources/main.js',
    'public/main.js',
    'resources/register.js',
    'public/register.js',
];

mix.js(...jsFiles).extract(['vue']).webpackConfig({
    resolve: {
        alias: {
            'vue$': path.resolve(__dirname, 'node_modules/vue/dist/vue.esm-bundler.js'),
        }
    }
}).version();

// now in your `register.js` and `main.js` use `import`, not `require`
//
// import Vue from 'vue';

Answer №2

If you're looking to utilize Vue.ref or ref, one approach is to destructure them as shown in the following code snippet:

import {ref, reactive} from 'vue/dist/vue.js';

It's worth noting that including window.Vue = Vue; may not be required. By simply using

import Vue from 'vue/dist/vue.js';
in each file such as register.js or its destructured version, the bundler will intelligently manage and include Vue library parts only once even with multiple imports.

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

JQuery is having trouble with playing multiple sound files or causing delays with events

I've been working on a project that involves playing sounds for each letter in a list of text. However, I'm encountering an issue where only the last sound file is played instead of looping through every element. I've attempted to delay the ...

How can I showcase the index of `<tr>` and `<td>` elements in a dynamically generated table

How can I print the index of table rows and data on click in javascript? <html> <head> <title>Table Creation</title> <script language="javascript" type="text/javascript"> function createTable() { ...

Trouble keeping HTML/Javascript/CSS Collapsible Menu closed after refreshing the page

My issue is that the collapsible menu I have created does not remain closed when the page is refreshed. Upon reloading the page, the collapsible menu is always fully expanded, even if it was collapsed before the refresh. This creates a problem as there is ...

Utilizing jQuery functions within Vue components in Quasar Framework

I've recently started delving into web app development and I'm encountering some basic questions regarding jQuery and Vue that I can't seem to find answers to. I have an application built using the Quasar Framework which frequently involves ...

Tips for setting a default value in a Multi Select component with reactjs and Material UI

Is it possible to set a default value on a Multiple selection (CHIP) using reactjs and material ui? Despite searching extensively online, I have not been able to find any relevant documentation addressing this issue. import * as React from 'react&apos ...

Is it possible to dynamically insert additional fields when a button is clicked?

My FormGroup is shown below: this.productGroup = this.fb.group({ name: ['', Validators.compose([Validators.required, Validators.maxLength(80)])], desc: ['', Validators.maxLength(3000)], category: ['', Validators.require ...

A guide on breaking down the ID passed from the backend into three segments using React JS

I pulled the data from the backend in this manner. https://i.stack.imgur.com/vMzRL.png However, I now require splitting this ID into three separate parts as shown here. https://i.stack.imgur.com/iy7ED.png Is there a way to achieve this using react? Bel ...

Hey there, what exactly does 'TypeError: Cannot access the 'scopedFn' property of an undefined object' mean?

Having trouble implementing RadListView with Nativescript-Vue. I am attempting to utilize a v-template for the header followed by another v-template for the list itself. 1) The header does not seem to be recognized, as only the standard v-template is disp ...

The functionality of Jquery datatables seems to be faulty when navigating to the second page

While utilizing the jQuery datatables plugin, I encountered an issue where the event click function only worked on the first page and not on subsequent pages. To address this problem, I discovered a helpful resource at https://datatables.net/faqs/ Q. My ...

Experiencing an anonymous condition post onChange event in a file input of type file - ReactJS

When using the input type file to upload images to strapi.io, I noticed that an unnamed state is being generated in the React dev tools. Can someone explain how this happened and how to assign a name to that state? https://i.sstatic.net/ZyYMM.png state c ...

The useStarRating() hook continues to display 0 even after the user has interacted with the star component

I've created a custom useStarRating hook to manage the state of a star rating component in my React project. Everything seems to be working properly, but I'm facing an issue with retrieving the updated value of currentValue after the user interac ...

Having trouble with React throwing a SyntaxError for an unexpected token?

Error message: Syntax error: D:/file/repo/webpage/react_demo/src/App.js: Unexpected token (34:5) 32 | 33 | return ( > 34 <> | ^ 35 <div className="status">{status}</div> 36 <div className=&quo ...

What is the best way to determine the count of results using a v-if statement?

Sorry for the possibly silly question, but I'm trying to figure out how to retrieve the number of results from my v-if statement within a v-for loop? This is what my code looks like: <div v-for="conv in conversation.hits" :key="conv ...

Is there a way to dynamically alter the theme based on stored data within the store

Is it possible to dynamically change the colors of MuiThemeProvider using data from a Redux store? The issue I'm facing is that this data is asynchronously loaded after the render in App.js, making the color prop unreachable by the theme provider. How ...

Using AngularJS, trigger an httpget request when the value in a textbox is changed

I am currently working on a web service that returns a json file when called with an entry ID parameter. I have successfully created an Angular method to retrieve the data from this service. However, I am facing difficulty in recalling the service when the ...

What is the process for converting the color names from Vuetify's material design into hexadecimal values within a Vue component?

I'm looking to obtain a Vuetify material design color in hexadecimal format for my Vue component's template. I want to use it in a way that allows me to dynamically apply the color as a border, like this: <div :style="`border: 5px solid $ ...

Issue with vuejs: npm run dev command not functioning

I'm facing an issue with running VueJS webpack on a server using the command: npm run dev. Instead of it running smoothly, I am getting a long list of errors. You can view the screenshot of the errors by clicking here. ...

Having trouble escaping single quotes in JSON.stringify when using a replacer function

I'm attempting to replace single quotation marks in the values of my JSON string with \' however, it seems to not be working when I try to use the replacer function. var myObj = { test: "'p'" } var re ...

"VueJS application can now be restarted with the simple push of a

Is there a way to reload the application in VueJS when a button is pressed? I've attempted the following: this.$nextTick(() => { var self = this; self.$forceUpdate(); }); However, $forceUpdate() does not serve the purpose I need. ...

The mismatch between JSON schema validation for patternProperties and properties causes confusion

Here is the JSON schema I am working with: { "title": "JSON Schema for magazine subscription", "type": "object", "properties": { "lab": { "type": "string" } }, "patternProperties": { "[A-Za-z][A-Za-z_]*[A-Za-z]": { "type" ...