Answer the question
In order to leave comments, you need to log in
Multiple templates for one Vue.js component, implementation?
There are components that accept several objects with props. There are HTML files (30+ pieces) that contain different data layout.
This implementation gives an error
Cannot find module './undefined.html'- the variable does not exist when the template is initialized
export default {
props: {
id: Number,
tmplLink: String
},
template: require(`./${this.tmplLink}.html`)
};
<template>
<component :is="component" :data="data" v-if="component" />
</template>
<script>
export default {
name: 'dynamic-link',
props: ['data', 'type'],
data() {
return {
component: null,
}
},
computed: {
loader() {
if (!this.type) {
return null
}
return () => import(`templates/${this.type}`)
},
},
mounted() {
this.loader()
.then(() => {
this.component = () => this.loader()
})
.catch(() => {
this.component = () => import('templates/default')
})
},
}
</script>
loader() {
return () => import(`./templates/${this.tmplLink}`);
}
Failed to resolve async component: function () {
return __webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./templates/default */ "./resources/js /makets/templates/default/index.vue"));
}
Reason: TypeError: Cannot read property 'call' of undefined
Answer the question
In order to leave comments, you need to log in
You are most likely getting the error because of this condition:
if (!this.type) {
return null
}
You can try like this (see code below). This is essentially Philipp Kühn's solution, but for your case where templates are stored in files, not components. To make it work, you need to set up a loader for html files ( raw-loader is perfect) and include the compiler in the assembly ( the "full" option ).
In theory, this can be optimized to a functional component, but for some reason it does not work in practice. Maybe my hands are crooked)
export default {
props: {
name: {
type: String,
default: 'default'
}
},
computed: {
component () {
// Не сокращать до одной строки, иначе свойство не будет реактивным.
const name = this.name
return () => this.load(name)
}
},
methods: {
async load (name) {
// В import() должен быть статический элемент (как './templates/'), иначе не заработает.
const { default: template } = await import(`./templates/${name}.html`)
return { template }
}
},
render (h) {
return h(this.component)
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question