I am trying to load some content into a component with Vue.js. I am trying to do this with the :is attribute. I keep getting "[Vue warn]: Failed to resolve component: interview"
<todo-tabs :list="items"></todo-tabs>
<template id="interview-slot">
//Interview Slot Content
</template>
<template id="membership-slot">
//Interview Slot Content
</template>
<script>
Vue.component('todo-tabs', {
template: '#todo-tabs',
props: ['list'],
data: function(){
return {
currentView: 'interview',
components:{
interview:{
template: '#interview-slot'
},
membership:{
template: '#membership-slot'
}
}
}
}
});
var vm = new Vue({
el: "#todo",
data: {
items : [
{id: 'interview', name: 'interview', complete: true, body: 'something1', step_content: 'SOME',current: true },
{id: 'membership', name: 'membership', complete: true, body: 'something2', step_content: 'SOME' },
{id: 'profile', name: 'profile', complete: false, body: 'something3', step_content: 'SOME' },
{id: 'handoff', name: 'handoff', complete: false, body: 'something4', step_content: 'SOME'}
]
}
});
</script>
I really don't want to put my html in the json if possible as it content lots of form elements.
Thank you in advance for any help
In this part of the code:
<template id="interview-slot">
//Interview Slot Content
</template
You are missing the closing > after </template.
Related
I am trying to make a component using shepperd library for my guide tour in vuejs. Here is the library: https://shepherdjs.dev/ So I created a component for it and I want to use it in my parent component:
<template>
<div></div>
</template>
<script>
export default {
name: 'Example',
props: {
element: {
type: Object,
required: true,
},
text: {
type: String,
required: true,
},
},
mounted() {
this.$nextTick(() => {
const tour = this.$shepherd({
defaultStepOptions: {
cancelIcon: {
enabled: true,
},
scrollTo: { behavior: 'smooth', block: 'center' },
},
});
tour.addStep({
attachTo: { element: this.element, on: 'top' },
text: this.text,
buttons: [
{
action() {
return this.back();
},
classes: 'shepherd-button-secondary',
text: 'Back',
},
{
action() {
return this.next();
},
text: 'Next',
},
],
});
tour.start();
});
},
};
Here is my parent component:
So in my parent component I want to add two times this component into my parent component. But I dont know how to connect with them. So when I click next, I want to trigger it and kill it then I want to trigger the next one.
Any help will be appreciated.
I am using shepperd for my guide tour in vue. Here is the documentation: https://shepherdjs.dev/
I created component for it:
<template>
<div></div>
</template>
<script>
export default {
name: 'Guide',
props: {
element: {
type: Object,
required: true,
},
title: {
type: String,
},
text: {
type: String,
required: true,
},
position: {
type: String,
required: true,
},
},
mounted() {
this.$nextTick(() => {
const tour = this.$shepherd({
defaultStepOptions: {
cancelIcon: {
enabled: true,
},
classes: 'class-1 class-2',
scrollTo: { behavior: 'smooth', block: 'center' },
},
});
tour.addStep({
attachTo: { element: this.element, on: this.position },
title: this.title,
text: this.text,
buttons: [
{
action() {
return this.back();
},
classes: 'shepherd-button-secondary',
text: 'Back',
},
{
action() {
return this.next();
},
text: 'Next',
},
],
id: 'creating',
});
tour.start();
});
},
};
</script>
<style lang="scss">
#import '~shepherd.js/dist/css/shepherd.css';
</style>
Whats wrong in my code is, in parent component I cannot get the element. I am trying to do it with ref in vue. So I want to get the element of this button:
<button ref="button">
Click
</button>
beforeMount() {
this.element = this.$refs.button;
},
But it is getting null all the time. How can I get the element of the button?
https://v2.vuejs.org/v2/api/#mounted
If you want to access the DOM element, you should put the code in mounted hooks.
mounted() {
this.element = this.$refs.button;
}
Note: mounted does not guarantee that all child components have also been mounted. If you want to wait until the entire view has been rendered, you can use vm.$nextTick inside of mounted
Being quite new to Vue, I ran into the issue when I cannot establish binding between input/select tags inside components and the data inside Vue instance.
Example #1:
html
<sidebar-select
:title="UI.sidebar.localeSelect.title"
:name="UI.sidebar.localeSelect.name"
:options="UI.sidebar.localeSelect.options"
:vmodel="selectedLocale">
</sidebar-select>
<sidebar-select
:title="UI.sidebar.currencySelect.title"
:name="UI.sidebar.currencySelect.name"
:options="UI.sidebar.currencySelect.options"
:vmodel="state.currency">
</sidebar-select>
js - component
Vue.component('sidebar-select', {
props: ['title', 'name', 'options', 'vmodel'],
data() {
return {
vmodel: this.value
}
},
template: `<div class="col-xs-12 col-md-6" style="padding-left:0;padding-right:30px">
<div class="cg">
<label :for="name"><h4>{{ title }}</h4></label>
<select class="form-control form-horizontal" style="max-width: 300px"
:name="name"
v-model="vmodel">
<option v-for="option in options" :value="option.value">{{ option.text }}</option>
</select>
</div>
</div>`
});
js - data part
var app = new Vue({
el: '#app',
data: {
selectedLocale: 'ru',
user: {
'ru': {
name: 'Саша',
surname: 'Найдович',
position: 'программист',
phone: '1234567',
email: 'jdlfh#jdlbf.com'
},
'en': {
name: 'Alex',
surname: 'Naidovich',
position: 'frontend',
phone: '1234567',
email: '1234567#email.eu'
}
},
state: {
locale: 'ru',
currency: '€',
/* *** */
},
UI: {
sidebar: {
localeSelect: {
title: 'Язык КП',
name: 'offer-lang',
options: [
{value: 'en', text: 'International - English'},
/* *** */
{value: 'ru', text: 'Русский'}
],
preSelected: 'ru',
stateprop: 'locale'
},
currencySelect: {
title: 'Валюта КП',
name: 'offer-curr',
options: [
{value: '$', text: '$ (Dollar)'},
{value: '€', text: '€ (Euro)'},
{value: '₤', text: '₤ (UK Фунт)'},
{value: '₽', text: '₽ (RUS Рубль)'},
{value: '', text: 'Ввести вручную'}
],
preSelected: '€',
stateprop: 'currency'
},
} /* etc */
}
}
});
There are 2 errors I run into: [Vue warn]: The data property "vmodel" is already declared as a prop. Use prop default value instead. at init and [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "vmodel" vhen I try to change selects. I wish to know what am I doing wrong and what would be the best-practice way for this case.
UPDATE: the main question is about how to properly use v-model two-way-data-binding when passing v-model as an argument into the props of component.
To be updated: example #2 with text inputs will be added tomorrow (the code is left at work).
I'm just new to Vue and I'm struggling with accessing my component data within a v-for scope. I get this error using the following code.
TypeError: Cannot read property 'whatever' of undefined
at eval
<template>
<b-row class="my-1" v-for="field in inputFields" :key="field.key">
<b-col>
<b-form-input :type="field.type" :placeholder="this.whatever" required>
</b-form-input> <!-- placeholder ERROR! -->
</b-col>
</b-row>
<b-form-input :placeholder="this.whatever" required>
</b-form-input> <!-- placeholder OK! -->
</template>
<script>
export default {
data() {
return {
whatever: 'this is a string',
userShouldSignup: false,
parameters: {
email: {
label: 'Enter email',
type: 'email',
value: '',
},
password: {
label: 'Enter password',
type: 'password',
value: '',
},
confirmPassword: {
label: 'Confirm password',
type: 'password',
value: '',
},
},
}
},
computed: {
inputFields() {
return this.userShouldSignup ? [
this.parameters.email,
this.parameters.password,
this.parameters.confirmPassword,
] : [
this.parameters.email,
this.parameters.password,
];
},
}
};
</script>
How do I access my data variables within v-for?
Change :placeholder="this.whatever" to :placeholder="whatever". You don't need to use this there because Vue recognize that you want to access its data or computed values. This doesn't work because this in the loop is something else.
Look at this code snippet below (I had to change some things to reproduce your problem):
var app = new Vue({
el: '#app',
data() {
return {
whatever: 'this is a string',
userShouldSignup: false,
parameters: {
email: {
label: 'Enter email',
type: 'email',
value: '',
},
password: {
label: 'Enter password',
type: 'password',
value: '',
},
confirmPassword: {
label: 'Confirm password',
type: 'password',
value: '',
},
},
}
},
computed: {
inputFields() {
return this.userShouldSignup ? [
this.parameters.email,
this.parameters.password,
this.parameters.confirmPassword,
] : [
this.parameters.email,
this.parameters.password,
];
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
<div class="my-1" v-for="field in inputFields" :key="field.key">
<div>
<input type="text" :placeholder="whatever" required/>
</div>
</div>
<input :placeholder="whatever" required/>
</div>
It's not working because "this" is pointing to "field" (loop), and the "field" doesn't have a "whatever" variable.
You just need to remove "this" keyword. You don't need it at all when access the variables from "data"
I am trying to use an inline-template in Vue.js but I can't get it to display data, here is my code:
Vue.component('food-item', {
props: ['food'],
})
var app7 = new Vue({
el: '#app-7',
data: {
foodList: [
{ id: 0, text: 'Vegetables' },
{ id: 1, text: 'Cheese' },
{ id: 2, text: 'Whatever else humans are supposed to eat' }
]
}
})
HTML Code:
<div id="app-7">
<ol>
<food-item v-for="item in foodList" v-bind:food="item" v-bind:key="item.address">
</food-item>
</ol>
<!-- template -->
<food-item inline-template>
<li>{{ food.text }}</li>
</food-item>
</div>
I get the following error:
TypeError: Cannot read property 'text' of undefined
You're treating it as a way of specifying the template separate from the component. That's not how inline-template works. The inline-template attribute and the template specification go in the tags where you're instantiating the component.
Vue.component('food-item', {
props: ['food'],
})
var app7 = new Vue({
el: '#app-7',
data: {
foodList: [{
id: 0,
text: 'Vegetables'
},
{
id: 1,
text: 'Cheese'
},
{
id: 2,
text: 'Whatever else humans are supposed to eat'
}
]
}
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app-7">
<ol>
<food-item v-for="item in foodList" v-bind:food="item" v-bind:key="item.address" inline-template>
<li>{{ food.text }}</li>
</food-item>
</ol>
</div>