I've got basic template that is outputing text from wysiwyg editor via two-ways data binding as below:
<template>
<div>
<quill-editor
v-model="debounceText"
:options="editorOptionProTemplate"
>
</quill-editor>
<div v-html="textComputed"></div>
</div>
</template>
<script>
data () {
return {
text: ''
}
},
computed: {
debounceText: {
get() { return this.text; },
set: _.debounce(function(newValue) {
this.text = newValue;
}, 100)
},
//using computed for many variants for styling output in web (here just adding <b> tag)
textComputed() {
return '<b>' + this.text + '</b>'
}
}
</script>
at this level all works fine
Now, I'm changing variable into array (object), using v-for (many elemnents to edit at the same time and outputing them in the array as below):
<template>
<div v-for="item in items">
<quill-editor
v-model="item.text"
:options="editorOptionProTemplate"
>
</quill-editor>
<div v-html="textComputedArray"></div>
</div>
</template>
<script>
data () {
return {
items: [
{active: true, text: 'text1', textOutput: ''},
{active: true, text: 'text2', textOutput: ''},
{active: true, text: 'text3', textOutput: ''},
{active: true, text: 'text4', textOutput: ''},
{active: true, text: 'text5', textOutput: ''}
]
}
},
textComputedArray: {
var output=''
for (var i=0; i<this.items.length; i++) {
if (this.items[i].active) {
this.items[i].textOutput= this.items[i].text + '<br />'
output = output + this.items[i].textOutput
}
else {
this.items[i].textOutput= ''
}
}
return output
},
</script>
how should I modify my code to apply debounceText computed to this output? I think that I simply cannot add computed to my template, and also I cannot pass any parameter into computed property.
Maybe someone more experienced than me will give me some solution/advice?
You can use computed properties to calculate and display values based on a value or set of values in the data model.
Computed properties are used to calculate the value of a property based on some other conditions. Watchers, on the other hand, are not primarily used for changing the value of a property; instead, they are used to notify you when the value has changed and let you perform certain actions based on these changes.
The combination of the v-model and computed property makes your code robust and more reusable. Hope this article helps you to understand how to use two-way data binding in Vue. js by using the v-model directive and computed properties.
Any time you have an array and you think each item needs a computed, you should look at making a component. That is how data and computeds get attached to each other.
In a lot of cases, you can make a computed based on the array, and it's fine, but you should be aware that any change to the array causes a recompute of the entire computed array. With a component, only the affected rows are recomputed. A simple example is embedded here.
new Vue({
el: '#app',
data: {
arr: [1, 2, 3]
},
computed: {
carr() {
console.log("Computing the whole array");
return this.arr.map(x => 'hi ' + x);
}
},
components: {
addHi: {
props: ['value'],
template: '<div>{{a}}</div>',
computed: {
a() {
console.log("Computing for", this.value);
return 'hi ' + this.value;
}
}
}
},
created() {
setTimeout(() => {
console.log("** Changing a value");
this.arr.splice(2, 1, 'X');
}, 1500);
}
});
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
<div v-for="a in carr">{{a}}</div>
<add-hi v-for="a in arr" :value="a" :key="a"></add-hi>
</div>
If you need your computed to be writable, you won't be able to edit individual items, so you're really forced to make a component. It is pretty straightforward: just move the HTML into the template of the component, move the computed into the component (adjusting it to work on the prop value
), and then – because it is operating on a prop – change the set
function to use $emit
rather than changing its value directly.
debouncedQuillEditor: {
props: ['value', 'options'],
template: '<quill-editor v-model="debouncedValue" :options="options"></quill-editor>',
computed: {
debouncedValue: {
get() {
return this.value;
},
set: _.debounce(function(newValue) {
this.$emit('input', newValue);
}, 100)
}
}
},
I made a fiddle to demonstrate. I made a second component to handle the output HTML, although it could have been included in the first component.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With