3
votes

in my admin app I have an , inside this component I also have Vue 2's quill rich editor which uses v-model for its data, now I want to pass the v-model from my child vue-2-editor to my own parent component, the docs say you can have custom v-model in yur compoennt with props value and emiting an 'input' event with that value, but how can I pass one v-model to another, from child to parent component.

Im using vue 2 editor, A text editor using Vue.js and Quill: https://github.com/davidroyer/vue2-editor

My component :

<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>

I want to be able to do:

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

More info about -model in custom components.

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

2

2 Answers

2
votes

TL;DR

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

Like you said, to support v-model in a component you need to add a model prop and emit a model event to let the parent know you want to update data.

By default v-model uses a value prop and an input event, but, since 2.2.0+, you can customize the component v-model.

The <vue-editor> component uses v-model default property and event, so it expects a value property and emits an input event whenever the data is updated.

So:

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

Is equivalent to:

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


Your <admin-editor> component also needs to support v-model, so you need to do the same <vue-editor> component does, add a model property and emit a model event.

Then, emit an input event from <admin-editor> whenever the <vue-editor> component 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>
1
votes

You can achive this by creating separate private variable (in data(), not a prop),and use it as the v-model on the vue-editor components, Than watch it and emit @input event on change, Also to receive update from the parent v-model, you need to watch the value prop and update the private variable.

<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>
<!--SCRIPTS-->
<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>

Note v-model="pvalue"