2

I am following this CodePen, and trying to fit it into the default VueJS 2.0 Boilerplate. This is how I would split the files up:

App.vue
main.js
components/Transitions.vue
components/Controls.vue
components/Page.vue

I am having huge problems getting this to run. E.g. my App.vue does not find the state. This is how I defined it in main.js:

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

const state = {
    animations: ['fade', 'slide', 'slideUp', 'zoom', 'flipX', 'flipY'],
    view: 'slide'
}

new Vue({
  render: h => h(App),
  data() {
    return this.state
  }
}).$mount('#app')

This is my App.vue:

<template>
  <div id="app">
    <component :is="state.view">
      <h1>{{ state.view }}</h1>
    </component>
    <controls></controls>
  </div>
</template>

This would be my controls:

<template id="controls">
<ul class="controls">
  <li v-for="(animation, index) in state.animations" v-bind:key="index" @click.prevent="setView(animation)" v-bind:class="{ 'active': animation === state.view }">
    {{ animation }}
  </li>
</ul>
</template>

<script>
export default {
  template: '#controls',

  methods: {
    setView(animation) {
      this.state.view = animation
    }
  }
}
</script>

..and so forth. Unfortunately I am getting:

[Vue warn]: data functions should return an object:
https://v2.vuejs.org/v2/guide/components.html#data-Must-Be-a-Function

(found in <Root>) vue.runtime.esm.js:619
[Vue warn]: Property or method "state" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

found in

---> <App> at src/App.vue
       <Root> vue.runtime.esm.js:619
[Vue warn]: Error in render: "TypeError: this.state is undefined"

What am I doing wrong here? How to get this thing to run?

tony19
  • 125,647
  • 18
  • 229
  • 307
Stephan Kristyn
  • 15,015
  • 14
  • 88
  • 147

2 Answers2

2

Attaching data properties to the root instance does not make them globally available in all descendant components (which appears to be what you attempted). There are actually a few ways to share state across components, including Vuex or global event bus (e.g., using $root.emit() and $root.on()). However, another simple solution is to use Vue.observable along with a mixin, exported from a shared file:

stateMixin.js:

import { observable } from "vue";

const state = observable({
  animations: ["fade", "slide", "slideUp", "zoom", "flipX", "flipY"],
  view: "slide"
});

// a mixin that declares a data propety named `state`
export default {
  data() {
    return {
      state
    };
  }
};

Then, you could import that file into any component that needs to access state:

App.vue:

import stateMixin from '@/stateMixin'

export default {
  mixins: [stateMixin],
  mounted() {
    console.log(this.state.view) // <-- stateMixin provides access to `state`
  }
}

demo of that Codepen in Codesandbox


Also note that since you're converting to single-file-components (SFC), you should not export a template property. The SFC itself declares the template already, and the compiler knows to use that by default.

tony19
  • 125,647
  • 18
  • 229
  • 307
1

You could return that state by applying spread operator as follows :

const state = {
    animations: ['fade', 'slide', 'slideUp', 'zoom', 'flipX', 'flipY'],
    view: 'slide'
}

new Vue({
  render: h => h(App),
  data() {
    return {...state} 
  }
}).$mount('#app')
Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164
  • 1
    How would this solve the problem that multiple files cannot access variables declared in other files? – Ferrybig Feb 20 '20 at 18:57
  • if you're sharing data between multiple files try to use `props`, `emit` or `vuex`, i just answered the error of reading state data property, please check my updated answer and this [code](https://codesandbox.io/s/great-cloud-1nw4o) – Boussadjra Brahim Feb 20 '20 at 19:01
  • 1
    I don't think its helpful to give a partial answer (without mentioning this fact) to the question that still gives the exact same error message even if the author implements your solution. – Ferrybig Feb 20 '20 at 19:27
  • it might not be helpful for the first time but trying my answer and posting other details we could clarify that better – Boussadjra Brahim Feb 20 '20 at 19:36
  • I did as you did in your example and got exactly same error, only now it says msg not defined. Could you take a look at the example CodePen I posted? Appreciate it! – Stephan Kristyn Feb 20 '20 at 22:46
  • the codepen example that you provided doesn't contain that error – Boussadjra Brahim Feb 20 '20 at 23:57