Estoy siguiendo este CodePen, e intentando encajarlo en el VueJS 2.0 Boilerplate predeterminado. Así es como dividiría los archivos:
App.vue
main.js
components/Transitions.vue
components/Controls.vue
components/Page.vue
Tengo grandes problemas para que esto funcione. P.ej. mi App.vue no encuentra el state
. Así es como lo definí en 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')
Este es mi App.vue :
<template>
<div id="app">
<component :is="state.view">
<h1>{{ state.view }}</h1>
</component>
<controls></controls>
</div>
</template>
Estos serían mis controles:
<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>
..Etcétera. Lamentablemente estoy obteniendo:
[Vue warn]: data functions should return an object:
https://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://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"
¿Qué estoy haciendo mal aquí? ¿Cómo hacer que esto funcione?
2 respuestas
Adjuntar propiedades de datos a la instancia raíz no las hace disponibles globalmente en todos los componentes descendientes (que parece ser lo que intentó). En realidad, hay algunas formas de compartir el estado entre los componentes, incluidos Vuex o bus de eventos globales (p. ej., usando $root.emit()
y $root.on()
). Sin embargo, otra solución simple es usar Vue.observable junto con un mixin, exportado desde un archivo compartido:
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
};
}
};
Luego, puede importar ese archivo a cualquier componente que necesite acceder a state
:
App.vue:
import stateMixin from '@/stateMixin'
export default {
mixins: [stateMixin],
mounted() {
console.log(this.state.view) // <-- stateMixin provides access to `state`
}
}
demostración de ese Codepen en Codesandbox
También tenga en cuenta que, dado que está convirtiendo a componentes de un solo archivo (SFC), no debe exportar una propiedad template
. El SFC mismo declara la plantilla ya, y el compilador sabe usarla por defecto.
Puede devolver ese state
aplicando el operador de propagación de la siguiente manera:
const state = {
animations: ['fade', 'slide', 'slideUp', 'zoom', 'flipX', 'flipY'],
view: 'slide'
}
new Vue({
render: h => h(App),
data() {
return {...state}
}
}).$mount('#app')
Preguntas relacionadas
Nuevas preguntas
vue.js
Vue.js es un marco Javascript progresivo de código abierto para construir interfaces de usuario que apuntan a ser incrementalmente adoptables. Vue.js se utiliza principalmente para el desarrollo front-end y requiere un nivel intermedio de HTML y CSS. Las preguntas específicas de la versión de Vue.js deben etiquetarse con [vuejs2] o [vuejs3].