How to set a component non-reactive data in Vue 2?

前端 未结 5 1070
别跟我提以往
别跟我提以往 2020-12-03 10:05

I have a categories array, which is loaded once (in created hook) and then it is static all the time. I render this array values in a component template.

<         


        
相关标签:
5条回答
  • 2020-12-03 10:24

    I prefer using static data (non reactive) like this:

    Create a mixin (i name it static_data.js) with the follow content

    import Vue from 'vue'
    
    Vue.prototype.$static = {}
    
    export default {
      beforeCreate () {
        const vue_static = this.$options.static
        const vue_static_destination = this.$static || this
    
        if (vue_static && typeof(vue_static) === 'function') {
          Object.assign(vue_static_destination, vue_static.apply(this))
        } else if (vue_static && typeof(vue_static) === 'object') {
          Object.assign(vue_static_destination, vue_static)
        }      
      }
    }
    

    In your components where you want to use static data you can do:

    import use_static_data from '@mixins/static_data'
    
    export default {
      mixins: [use_static_data],
    
      static: () => ({
        static_value: 'Vue is awesome'
      }),
    
      created () {
        console.log(this.$static.static_value); // Vue is awesome
      }
    }
    

    There is also a package vue-static

    Credits here.

    0 讨论(0)
  • 2020-12-03 10:25

    Actually, setting properties on this in created() should work out of the box:

    <template>
      <div id="app">
        <ul>
          <li v-for="item in myArray" :key="item">
            {{ item }}
          </li>
        </ul>
      </div>
    </template>
    
    <script>
    export default {
      name: "app",
      created() {
        this.myArray = [
          'item 1',
          'item 2'
        ];
      }
    };
    </script>
    

    will render

    <div id="app">
      <ul>
        <li>
          item 1
        </li>
        <li>
          item 2
        </li>
      </ul>
    </div>
    

    Demo here: https://codesandbox.io/s/r0yqj2orpn .

    0 讨论(0)
  • 2020-12-03 10:27

    If you want to keep it in data, the proper way is using Object.freeze(), as described in the documentation:

    The only exception to this being the use of Object.freeze(), which prevents existing properties from being changed, which also means the reactivity system can’t track changes.

    0 讨论(0)
  • 2020-12-03 10:31

    Vue sets all the properties in the data option to setters/getters to make them reactive. See Reactivity in depth

    Since you want myArray to be static you can create it as a custom option which can be accessed using vm.$options

    export default{
        data() {
            return{
                someReactiveData: [1, 2, 3]
            }
        },
        //custom option name myArray
        myArray: null,
        created() {
            //access the custom option using $options
            this.$options.myArray = ["value 1", "value 2"];
        }
    }
    

    you can iterate over this custom options in your template as follows:

    <template>
        <ul>
            <li v-for="item in $options.myArray">{{ item }}</li>
        </ul>
    </template>
    

    Here is the fiddle

    0 讨论(0)
  • 2020-12-03 10:41

    You can try this line of code. You can copy an object and remove the reactivity.

    var newObj = JSON.parse(JSON.stringify(obj));
    
    0 讨论(0)
提交回复
热议问题