Setting non-reactive data in Vue 2 components: A step-by-step guide

I have an array of categories that is loaded once in the created hook and remains static thereafter. I am rendering these values in a component template.

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

My data property does not include myArray as I do not want reactive binding:

data() {
    return {
        someReactiveData: [1, 2, 3]
    };
}

In my create hook:

created() {
    // ...
    this.myArray = ["value 1", "value 2"];
    // ...
}

The issue arises when Vue throws an error stating that I cannot use myArray in the template because it is not available when the DOM is mounted.

So how can I achieve this? And where should component constants be stored?

Answer №1

Vue ensures that all properties in the data option are reactive by setting them as setters/getters. For a deeper understanding of reactivity, refer to Reactivity in depth

If you want myArray to remain static, you can define it as a custom option accessible through vm.$options

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

You can loop through this custom option in your template like this:

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

Check out the JSFiddle example

Answer №2

Indeed, it is possible to set properties on this within the created() hook without any issues:

<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>

The output will be:

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

You can check out a live demonstration here: https://codesandbox.io/s/r0yqj2orpn.

Answer №3

My personal preference is to utilize static data (non-reactive) in this manner:

To start, create a mixin (I usually name it static_data.js) with the following 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 wish to incorporate static data, implement the following:

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
  }
}

You may also want to check out the package vue-static

Credits can be found here.

Answer №4

To store the data in a secure way, it is recommended to utilize Object.freeze(), as outlined on the Mozilla Developer Network:

One noteworthy exception would be the application of Object.freeze(), which prohibits modifications to existing properties and subsequently hinders the reactivity system from tracking changes.

Answer №5

If you're looking to eliminate reactivity from an object, give this code snippet a shot. It allows you to create a new object with no reactivity by copying the original.

const newObj = JSON.parse(JSON.stringify(obj));

Answer №6

 <section>
  <div id="container">
    <ul>
      <li v-for="element in newArray" :key="element">
        {{ element }}
      </li>
    </ul>
  </div>
</section>

<script>
export default {
  name: "container",
  data () {
    this.newArray = [
      'element A',
      'element B'
    ];
    return {}
  }
};
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Combine both typescript and javascript files within a single Angular project

Is it feasible to include both TypeScript and JavaScript files within the same Angular project? I am working on a significant Angular project and considering migrating it to TypeScript without having to rename all files to .ts and address any resulting er ...

Parsing error coming up with Angular's ng-model on selection input designation

I am currently dealing with a situation where a Salesforce form provided by a client has a dynamically generated name value for the state selector. When I try to run Angular, it throws a parsing error. It seems that Angular is having trouble accepting the ...

Using Struts2 actions in combination with jQuery AJAX calls

Similar Question: How to utilize $.ajax() method in struts2 In simple terms: 1. Could someone explain how to trigger a struts action using jquery ajax? (without using the struts jquery plugin) 2. How do I retrieve results and display HTML output cor ...

In React, the `context` is consistently an empty object

I am facing an issue while trying to establish a context in my React App. For some reason, I am unable to access context from the children components. Here is the parent component: import React from 'react' import MenuBar from './MenuBar.js ...

What is preventing me from adding a borderRadius to this particular React bootstrap tab?

I have been working on tabbed content and encountered an issue with applying border radius. Despite adding style={{borderRadius: "10px"}}, it seems to have no effect. This styling works perfectly everywhere else in my project, so I am puzzled as ...

Tips for verifying conditional input fields in a React component?

As a beginner in React, I attempted to create a SignIn form component that dynamically changes its layout based on a boolean prop toggled between Login and Signup options. In the signup version, there is an additional text field labeled Confirm password, w ...

How can I prevent the <br/> tag from being included on every new line when exporting data to PDF in jQuery Datatable?

I am currently working with a datatable that contains a large amount of data. Within this table, I have included 2 buttons for exporting the data in PDF and CSV formats. One of the columns within my table contains a comma-separated string, and when I expor ...

What is the best way to ensure a PrimeVue TabPanel takes up the full vertical space and allows the content within the tabs to be scroll

I have created a sandbox demo to illustrate my issue. My goal is to make the content of tabs scroll when necessary but fill to the bottom if not needed. I believe using flex columns could be the solution, however, my attempts so far have been unsuccessful. ...

What could be the reason for JSON refusing to accept an element from an array?

I am looking to retrieve the exchange rates for all currencies from an API using an array that lists all available currencies. Below is the JavaScript code I have written: var requestURL = 'https://api.fixer.io/latest'; var requestUrlstandard ...

The v-checkboxes will be activated upon the initial loading of the page

I'm currently working on form validation with vuelidate. Within the form, I have a group of checkboxes along with other fields. My goal is to display success messages for the checkboxes only when they are checked. However, I'm facing an issue whe ...

Tips for preventing page breaks (when printing or saving as a PDF) in lengthy HTML tables

Here is the link to a single HTML file (including style and scripts): FQ.html The problem I'm facing can be seen in this image: https://i.sstatic.net/Nr4BZ.png I've tried several solutions, the latest of which involves the following CSS... @me ...

Top method for handling multiple conditions - JavaScript

I created a customized function to create a responsive carousel with multiple images per slide. (Unfortunately, I couldn't get Owl Carousel to work on my Angular project, but that's not the focus here). The number of images displayed per slide i ...

Utilizing AWS SDK (S3.putObject) to transfer a Readable stream to Amazon S3 using node.js

I am aiming to successfully send a Readable stream to S3. However, I have encountered an issue where the AWS api only seems to accept a ReadStream as a stream argument. When using a ReadStream, everything works as expected, as shown in the following code ...

What steps can be taken to enable users to draw a path on a Google Map?

I'm working on a new project for a Facebook app that will allow users to map out their marathon route using Google Maps. I plan to utilize mySQL database records to store fixed points along the path (such as specific locations based on latitude and lo ...

What is the best way to retrieve the value of a textbox using jQuery and ajax?

I'm facing an issue where I am trying to retrieve a value from a textbox and display it in a table using jQuery. Strangely, when I try to access the "data" inside the success:function (data) of my AJAX call, it returns empty, but if I log it outside t ...

Is it possible to create a personalized serialize form when sending an AJAX POST request

How can I format form data on an AJAX POST request differently than the default $("#formid").serialze()? The current result is not suitable for my needs, as it looks like this: `poststring="csrfmiddlewaretoken=bb9SOkN756QSgTbdJYDTvIz7KYtAdZ4A&colname= ...

What causes the error message "ng-model is undefined"?

Within my form, there are three angular-ui-bootstrap typehead elements <form> <div class="form-group"> <label for="fieldname" class="col-md-3 control-label">Name</label> <div class="col-md-6"> <input type="text ...

Tips on sorting a FileList object selected by a directory picker in JavaScript/TypeScript

I need to filter or eliminate certain files from a FileList object that I obtained from a directory chooser. <input type="file" accept="image/*" webkitdirectory directory multiple> Within my .ts file: public fileChangeListener($event: any) { let ...

Display a PDF file within an IFrame using JavaScript and then print it

Why is it so challenging to achieve? I've dedicated 48 hours to research this, yet it seems impossible! Although recent Chrome versions allow the parent window to access PDFs in iframes, both FF and IE prevent any interaction with the iframe that dis ...

What is the best way to transfer data between components in VueJS while utilizing the Vue router?

My route setup includes the following: Vue.use(Router) export default new Router({ routes: [ { path: '/group/:id', name: 'Group', component: GroupContainer, children: [ { // when /group/: ...