如何在Vue中使模板变量无效

时间:2018-10-16 20:50:36

标签: vue.js

我有一个编辑表单,其中的变量保存在data()中。我不希望编辑页面的标题更新,但我想保持输入和数据之间数据的V模型同步。使标题在h1标签中不活跃的最简单方法是什么?尤先生为此必须袖手旁观。.

<template>
    <div>
        <h1>{{ title }}</h1>
        <input v-model="title">
    </div>
</template>

<script>    
export default {
    data: {
        title: 'Initial value'      
    }
}
</script>

5 个答案:

答案 0 :(得分:2)

Vue docs建议在data()中返回的对象上使用Object.freeze()以禁用对属性的反应:

data() {
  return Object.freeze({ title: 'Initial value' })
}

但是需要注意的是,它冻结了所有属性(看起来不存在使用此方法仅冻结某些属性的方法),并且与此同时使用v-model导致控制台错误(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/vue@2.5.17"></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>

或者,您可以通过redefining itwriteable: 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/vue@2.5.17"></script>

<div id="app">
  <p>{{ message }}</p>
  <input v-model="message">

  <div>
    <button @click="removeReactivity">
      Remove reactivity for <code>message</code>
    </button>
  </div>
</div>

答案 1 :(得分:1)

如果您不希望输入更改数据项的值,请使用value来绑定它,而不是双向v-model。然后,它仅充当输入的初始化程序。

如果要有两个值,一个不变,而另一个不变,则需要两个数据项。不变的可以是prop with a default value。另一个是data成员,如果您使用data函数,则可以将自身初始化为prop值。

new Vue({
  el: '#app',
  props: {
    initTitle: {
      default: 'Initial value'
    }
  },
  data() {
    return {
      title: this.initTitle
    };
  }
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <h1>{{ initTitle }}</h1>
  <input v-model="title">
  <div>Title is "{{title}}"</div>
</div>

您也可以使用鲜为人知的$options属性将标题定义为内部常量而不是prop。对于这是一种好的设计方法还是太奇怪的步骤,我感到百感交集。

new Vue({
  el: '#app',
  initTitle: 'Initial value',
  data() {
    return {
      title: this.$options.initTitle
    };
  }
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <h1>{{ $options.initTitle }}</h1>
  <input v-model="title">
  <div>Title is "{{title}}"</div>
</div>

答案 2 :(得分:0)

the contents of this blog向后工作...

看来,当您为Vue创建对象时,它会使用反应性的吸气剂和吸气剂来创建特性。然后,如果您带外将属性附加到该对象,则它将无法获得反应功能,但仍可以作为值来访问。

这应该为您解决:

<template>
    <div>
        <h1>{{ titleContainer.value }}</h1>
        <input v-model="title">
    </div>
</template>

<script>    
export default {
    data: {
        titleContainer: {}
    }
}
titleContainer.value = "Initial Value"
</script>

答案 3 :(得分:0)

如果您不想为v-once创建单独的变量,则可以根据需要使用input指令。来自docs

  

仅渲染一次元素和组件。在随后重新渲染时,   元素/组件及其所有子元素将被视为静态   内容并跳过。

new Vue({
  el: "#app",
  data: {
    title: "initial value"
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/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>

答案 4 :(得分:0)

没有一种简单的方法可以解决Vue的问题,因为Vue会自动为所有对象属性注入反应性吸气剂和吸气剂。您可以在变量上使用Object.freeze()来删除反应性,但它​​将应用于整个对象本身,而不是您想要的。

我创建了一个名为vue-for-babylonians的vue分支,以限制反应性,甚至允许某些对象属性具有反应性。检出here

使用它,您可以告诉Vue不要使任何存储在vue或vuex中的对象成为被动对象。您还可以告诉Vue使对象属性的某些子集具有反应性。您会发现性能大大提高,并且享受了存储和传递大型对象的便利,就像通常在vue / vuex中一样。