Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a template variable non-reactive in Vue

Tags:

vue.js

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>
like image 534
digout Avatar asked Jan 29 '26 13:01

digout


2 Answers

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>
like image 90
tony19 Avatar answered Feb 02 '26 01:02

tony19


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>
like image 23
Psidom Avatar answered Feb 02 '26 03:02

Psidom



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!