Utilizing the v-model directive with nested components in VueJS

Within my admin application, I have a component that includes Vue 2's Quill rich editor which utilizes v-model for its data. Now, I aim to transmit this v-model from my child vue-2-editor component to the parent component. The documentation suggests creating a custom v-model in your component using props value and emitting an 'input' event with that value. However, the challenge lies in passing one v-model to another, particularly from the child to the parent component.

The text editor I am utilizing is the vue2 editor, a unique take on text editing through Vue.js and Quill: https://github.com/davidroyer/vue2-editor

This is how my component looks like :

<template>
<div style="width:auto; height:auto; display:flex; flex-direction.column;">
    <button @click="editorVisible = true">Show Editor</button>
    <vue-editor v-model="value" :editorToolbar="customToolbar" useCustomImageHandler @imageAdded="handleImageAdded"></vue-editor>
</div>
</template>
<!--SCRIPTS-->
<script>
import { VueEditor } from 'vue2-editor';
export default {
name: 'ADMINeditor',


props:
{
    value:{ required:true, type:String }
},


data()
{
    return { 
        editorVisible:false
    }
},


methods:
{

    wrote()
    {
        this.$emit('input', this.value);
    }
}


}
</script>
<!--STYLES-->
<style scoped>
</style>

My goal is to achieve:

<admin-editor v-model="text"></admin-editor>

To dive deeper into -model within custom components, you can refer here:

https://alligator.io/vuejs/add-v-model-support/

Answer №1

Summary

<vue-editor :value="value" @input="$emit('input' $event)" />

As mentioned, in order to enable v-model functionality in a component, you must include a model property and emit a model event to inform the parent component of data updates.

The standard way for v-model to work is by utilizing a value prop and an input event. However, starting from version 2.2.0+, it is possible to customize the usage of v-model within a component.

The <vue-editor> component follows the default v-model setup by expecting a value prop and emitting an input event whenever there are data changes.

Therefore:

<vue-editor v-model="value" />

Is essentially equivalent to:

<vue-editor :value="xxx" @input="onXxxUpdate"


Your <admin-editor> component also needs to support v-model, so you should follow the same pattern as <vue-editor>: add a model property and emit a model event.

Additionally, emit an input event from <admin-editor> whenever the <vue-editor> emits an input event.

<template>
  <vue-editor :value="value" @input="onEditorUpdate" />
</template>

<script>
import { VueEditor } from 'vue2-editor'

export default {
  name: 'AdminEditor',

  props: {
    value: {
      type: String,
      default: '',
    },
  },

  methods: {
    onEditorUpdate(newVal) {
      //           ^^^^^^
      //           <vue-editor> input event payload
      this.$emit('input', newVal)
    },
  },
}
</script>

Answer №2

To accomplish this task, you can create a separate private variable within the data() function instead of using a prop. Then, utilize this variable as the v-model in the vue-editor components. Next, watch for changes and emit the @input event accordingly. Additionally, to receive updates from the parent v-model, set up a watcher for the value prop and update the private variable when needed.

<template>
    <div style="width:auto; height:auto; display:flex; flex-direction.column;">
        <button @click="editorVisible = true">Show Editor</button>
        <vue-editor v-model="pvalue" :editorToolbar="customToolbar" useCustomImageHandler
            @imageAdded="handleImageAdded"></vue-editor>
    </div>
</template>

<script>
import { VueEditor } from 'vue2-editor'
export default {
    props: {
        value: { required: true, type: String }
    },
    data() {
        return {
            pvalue: '',
        }
    },
    watch: {
        value(val) {
            this.pvalue = val
        },
        pvalue(val) {
            this.$emit('input', val)
        }
    }
}
</script>

Remember to include v-model="pvalue" in your code.

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

Error: Vue.js is unable to find the reference for "_vm.KisanData" and throws a TypeError

I need assistance in fixing an error that I am encountering. The issue arises in this method where I am using KisanData, but I am unable to resolve it. const API_URL = "http://localhost:3000/User"; export default { name: "home", info(){ ...

Is there a way to extract only the titles from this JSON array? (using JavaScript/discord.js)

How can I extract the "title" values from this JSON array using JavaScript? I need to retrieve all the "title"s and store them in a new array like shown below: array( `hey title1`, `hey title2`, ... ) I am unsure of the number of titles we will receive, b ...

Unable to locate a contact within the state

Currently, I am diving into the world of React by exploring its documentation and challenging myself to build a small chat application. While I have a good grasp on the basics, I am encountering some issues with states. Within my code, there is an object ...

Unable to access Vue3 props from setup() results in empty values

I'm encountering an unusual issue with my Vue3 component. I'm attempting to access a value from the props within the setup() function, but it seems to be returning nothing. <template> <div class="border p-2 space-y-2"> ...

Using Jquery to tally the number of JSON elements

I'm currently developing a chart system that pulls data from an AJAX JSON response. My goal is to categorize certain JSON objects based on color and month. For instance, I aim to organize all the colors (Red, Blue, Yellow) into separate groups and th ...

Exploring the possibilities of implementing Undo and Redo features in freehand drawing with Reactjs on

After attempting to create a Freehand drawing using HTML5 canvas with React, my next step is to incorporate an undo and redo functionality when the corresponding buttons are clicked. I would greatly appreciate any assistance provided. function App(props) ...

Troubleshooting issues with ngIf and [hidden] in Angular 5 while utilizing the fxFlex Framework

Important Note: The following snippet showcases the use of ngIf, where elements meant to be hidden are still present in the DOM but invisible, occupying space. <div fxLayout="row wrap" fxLayoutAlign="space-around center"> <div *ngFor= ...

When SVGs are dynamically loaded, the SVG fill with "url(#foo)" disappears

Within my AngularJS web application, I am dynamically loading various SVGs and adjusting the opacity of their layers. Some paths within these SVGs have fill pattern properties like this: <defs> <pattern id="glass-floral" patternUnits="userSpace ...

Ways to conceal a div using jQuery when the video source is missing

If there is no source in the video, I want to hide the video_wrapper class <div class="video_wrapper" style="width: 100%; height: 100%; display: none;"> <video id="df-video" playsinline="" webkit-playsinline="" style="height: 100%; width: 100%; ...

Why is it necessary to re-export both * and { default } in zustand.js?

As I delved into analyzing the codebase of zustand, I stumbled upon this snippet in index.ts: export * from './vanilla' export * from './react' export { default as createStore } from './vanilla' export { default } from '. ...

What is the best way to access all of a class's properties in JavaScript?

Is there a way to retrieve all the properties of a class using JavaScript? For example, if I have a class like this: .menu { color: black; width: 10px; } How can I extract "color: black; width: 10px;" as a string using JavaScript? Thanks in advance! ...

"Access denied" error when using Internet Explorer and jQuery

Attempting to make an AJAX call using jQuery's $.post in Internet Explorer is resulting in an error message stating "Permission denied." This peculiar issue only seems to occur when accessing a page after having visited another page. For example, if ...

Managing Scripts and Stylesheets with AngularJS Directives

Can I organize all my stylesheets and scripts into a directive for easier management? I'm considering cleaning up my index file by placing them in separate directives like this: <head> <ng-stylesheets></ng-stylesheets> ...

How can one effectively develop a component library that is compatible with both React and Preact?

I'm currently in the midst of a project that involves both React and Preact. I've come across a situation where I need to utilize the same component for both React and Preact. Would it be wise to package the component into an npm library? What a ...

When accessing a sub-array directly within an object, it transforms into a collection of nested objects

Is there a way to pass an array of objects to canvasJS? I am trying to include this array as part of a more complex object that is passed from PHP to a JS script. Here is my current approach: var active_alarms_data = JSON.parse('<?php echo json_enc ...

I'm looking to create a redirect feature using a QR code that will direct users to a specific page within my Flutter app. How

When the user scans the QR code, they will be taken to a secret internal page that can only be accessed through this specific link. I attempted to use various libraries such as , but it did not achieve the desired outcome. ...

How can JSON data be passed to the Google Charts API?

I am currently working on a project that involves retrieving JSON data from a website and visualizing it on a live graph using the Google Charts API. Despite my efforts, I am unable to get the chart to display properly. Can someone please guide me in the r ...

Sending form data without interrupting the user interface by using asynchronous submission

Using jQuery version 1.7.2, I am currently using the submit() method to send a form via POST. This triggers a Python cgi-bin script that performs some tasks which may take around ten seconds to finish. Upon completion of the task, the Python script instruc ...

Instead of using `await asyncCall()`, try using `(await asyncCall())[0]`

After examining the Typescript code below, I'm curious to understand the rationale behind assigning myArray with (await asyncRPCCall())[0] instead of simply using await asyncRPCCall(). Why is the result placed inside () and why return only the first e ...

Error encountered: DOM Exception: Attempting to append a child node which is not permitted by the hierarchy. (Error

I'm attempting to set up a popup within a window body with the following code: this.popObj = $('<div class="notif-popup DialogInner"><div class="closeIcon" onclick="$(this).parent().hide();"></div><div style="Float:left;max- ...