I have an edit form with variables held in the data(). I don't want the title of the edit page to update yet I want to maintain the v-model sync of data between the input and data. What's the simplest way to make the title non-reactive in the h1 tag? Mr You has to have something up his sleeve for this..
<template>
<div>
<h1>{{ title }}</h1>
<input v-model="title">
</div>
</template>
<script>
export default {
data: {
title: 'Initial value'
}
}
</script>
The Vue docs recommend Object.freeze() on the returned object in data() to disable reactivity on properties:
data() {
return Object.freeze({ title: 'Initial value' })
}
But the caveat is it freezes all properties (it doesn't look like there's a way to freeze only some properties using this method), and using v-model with this causes console errors (Cannot assign to read only property).
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data() {
return Object.freeze({
message: 'Hello Vue.js!',
})
}
})
<script src="https://unpkg.com/[email protected]"></script>
<div id="app">
<p>{{ message }}</p>
<input v-model="message"> <!-- XXX: Cannot use v-model with frozen property. This will cause a console error. -->
</div>
Alternatively, you could arbitrarily remove the reactivity from any configurable data property by redefining it with writeable: false:
methods: {
removeReactivity() {
Object.defineProperty(this, 'title', {value: null, writeable: false});
}
}
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data() {
return {
message: 'Hello Vue.js!',
}
},
methods: {
removeReactivity() {
Object.defineProperty(this, 'message', {value: null, writeable: false});
}
}
})
<script src="https://unpkg.com/[email protected]"></script>
<div id="app">
<p>{{ message }}</p>
<input v-model="message">
<div>
<button @click="removeReactivity">
Remove reactivity for <code>message</code>
</button>
</div>
</div>
You could potentially use v-once directive for your purpose if you don't want to create a separate variable for input. From the docs:
Render the element and component once only. On subsequent re-renders, the element/component and all its children will be treated as static content and skipped.
new Vue({
el: "#app",
data: {
title: "initial value"
}
})
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<div id="app">
<input v-model="title">
<p>Reactive title: {{ title }}</p>
<p v-once>Static title: {{ title }}</p>
</div>
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