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>
Related
I'm wondering if there is a way to hide a whole row/item in a vuetify data-table. I've read threads about hiding columns but not data-table items.
As per my understanding, You want to hide the specific rows from the <v-data-table>. If Yes, you can achieve that by using v-slot and manipulate the template.
Demo :
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
headers: [
{
text: 'Dessert',
value: 'name'
}
],
items: [
{
name: 'Frozen Yogurt',
show: true
},
{
name: 'Ice cream sandwich',
show: false
},
{
name: 'Eclair',
show: true
},
{
name: 'Cupcake',
show: false
}
]
}
},
})
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.6/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.6/dist/vuetify.min.css"/>
<link rel="stylesheet" href="https://unpkg.com/#mdi/font#6.x/css/materialdesignicons.min.css"/>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="items"
class="elevation-1"
>
<template v-slot:item="props">
<template v-if="props.item.show">
<tr>{{ props.item.name }}</tr>
</template>
</template>
</v-data-table>
</v-app>
</div>
I think passing an empty array to your :items would fix your problem. or you can do this one :items="defaultVales || desserts".
In my opinion, the best way to handle this is to add a show property to your objects and use a computed property to hide and show items
Working example
Here it will hide column on click
new Vue({
el: '#app',
vuetify: new Vuetify(),
computed:{
showItems(){
return this.desserts.filter(x => x.show)
}
},
data() {
return {
headers: [
{ text: 'Name', value: 'name' },
{ text: 'Score', value: 'score' },
],
desserts: [{
name: "Frozen",
score: 66,
show: true,
},
{
name: "Tom",
score: 100,
show: true,
},
{
name: "Eclair",
score: 100,
show: true,
},
{
name: "Frozen",
score: 89,
show: true,
},
]
}
},
methods: {
hideColumn(col){
col.show = false
}
}
})
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/vuetify#2.3.4/dist/vuetify.min.css'>
<script src='https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js'></script>
<script src='https://cdn.jsdelivr.net/npm/vuetify#2.3.4/dist/vuetify.min.js'></script>
<div id="app">
<v-data-table
:items="showItems"
:headers="headers"
#click:row="hideColumn"
>
</v-data-table>
</div>
I have a vuejs method that appends data on a screen. My issue is, I want to append all of the items found in the array to the screen using v-for instead of just one that is filtered by an index?
new Vue({
el: "#app",
data: () => ({
chocs:[{"title":'a man tale'}, {"title":'a boy tale'},{"title":'a mermaid tale'},{"title":'a dog tale'}]
}),
methods: {
handleTileClick: function(){
$("#fox").append(`<div id="popover-dialog">data here: ${this.chocs.title}</div>`
);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Todos:</h2>
<button v-on:click="handleTileClick()">Click Me</button>
<div id="fox" v-for="choc in chocs"></div>
</div>
Check the below code
var app = new Vue({
el: '#app',
name: "App",
data: () => ({
showList: false,
chocs: [
{ title: "a man tale" },
{ title: "a boy tale" },
{ title: "a mermaid tale" },
{ title: "a dog tale" },
],
}),
methods: {
handleTileClick: function () {
this.showList = true;
},
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Todos:</h2>
<button v-on:click="handleTileClick">Click Me</button>
<div id="fox" v-if="showList">
<div id="list-item" v-for="(choc, index) in chocs" :key="index">{{ choc.title }}</div>
</div>
</div>
You can first hide the elements and show them after click on the click Me button:
Live Demo
<div id="fox" v-if="isShowing">
<div id="popover-dialog" v-for="choc in chocs" :key="choc.title">
data here: {{ choc.title }}
</div>
</div>
data and methods as:
export default {
name: "App",
data: () => ({
isShowing: false,
chocs: [
{ title: "a man tale" },
{ title: "a boy tale" },
{ title: "a mermaid tale" },
{ title: "a dog tale" },
],
}),
methods: {
handleTileClick: function () {
this.isShowing = true;
},
},
};
I am asking this again because I don't understand what I am doing wrong. This is a tutorial I did and I did exactly as the tutorial went. I am trying to toggle between tasks being marked done and not done. When I run the code it does not toggle and there are no errors. I read the documentation but I don't fully understand. I am new to programming.
let bus = new Vue();
let Task = {
props: ['task'],
template: `
<div class="task" :class="{ 'task--done' : task.done , 'task-notdone' : task.done === false }">
{{ task.body }}
Mark me as {{ task.done ? 'not done' : 'done' }}
</div>
`,
methods: {
toggleDone(taskId) {
bus.$emit('task:toggleDone', taskId);
}
}
};
let Tasks = {
components:{
'task': Task
},
data() {
return {
tasks: [
{id: 1, body: 'Task One', done: false },
{id: 2, body: 'Task Two', done: true },
{id: 3, body: 'Task Three', done: true }
],
}
},
template: `
<div>
<template v-if="tasks.length">
<task v-for="task in tasks" :key="task.id" :task="task"></task>
</template>
<span v-else>No tasks</span>
<form action="">
form
</form>
</div>
`,
methods: {
toggleDone(taskId){
let task = this.tasks.find(function (task) {
return task.id === taskId;
});
console.log(task);
}
},
mounted () {
bus.$on('task:toggleDone', (taskId) => {
this.toggleDone(taskId);
})
},
};
let app = new Vue({
el:'#app',
components: {
'tasks': Tasks,
},
});
I'm not sure why the tutorial was leading you to using a bus; it's just not needed here. There is a list of tasks that are javascript objects and each task object is being passed to the task component. Since it is a javascript object, and not a primitive value, you can update the done property in the task component.
console.clear()
let Task = {
props: ['task'],
template: `
<div class="task" >
<span :class="{ 'task--done' : task.done , 'task-notdone' : !task.done}">{{ task.body }}</span>
Mark me as {{ task.done ? 'not done' : 'done' }}
</div>
`
};
let Tasks = {
components:{
'task': Task
},
data() {
return {
tasks: [
{id: 1, body: 'Task One', done: false },
{id: 2, body: 'Task Two', done: true },
{id: 3, body: 'Task Three', done: true }
],
}
},
template: `
<div>
<template v-if="tasks.length">
<task v-for="task in tasks" :key="task.id" :task="task"></task>
</template>
<span v-else>No tasks</span>
</div>
`,
};
let app = new Vue({
el:'#app',
components: {
'tasks': Tasks,
},
});
.task--done{
text-decoration: line-through
}
<script src="https://unpkg.com/vue#2.5.2/dist/vue.js"></script>
<div id="app">
<tasks></tasks>
</div>
Additionally, if you don't want to mutate the object in the component, you can instead emit an event that lets the parent mutate it.
console.clear()
let Task = {
props: ['task'],
template: `
<div class="task" >
<span :class="{ 'task--done' : task.done , 'task-notdone' : !task.done}">{{ task.body }}</span>
Mark me as {{ task.done ? 'not done' : 'done' }}
</div>
`
};
let Tasks = {
components:{
'task': Task
},
data() {
return {
tasks: [
{id: 1, body: 'Task One', done: false },
{id: 2, body: 'Task Two', done: true },
{id: 3, body: 'Task Three', done: true }
],
}
},
template: `
<div>
<template v-if="tasks.length">
<task v-for="task in tasks" :key="task.id" :task="task" #toggle-task="toggleTask"></task>
</template>
<span v-else>No tasks</span>
</div>
`,
methods:{
toggleTask(task){
task.done = !task.done
}
}
};
let app = new Vue({
el:'#app',
components: {
'tasks': Tasks,
},
});
.task--done{
text-decoration: line-through
}
<script src="https://unpkg.com/vue#2.5.2/dist/vue.js"></script>
<div id="app">
<tasks></tasks>
</div>
This is my pseudo code:
var vm = new Vue({
el: '#test',
data: {
words: [{name:'1'}, {name:'2'}, {name:'3'},{name:'4'},{name:'5'},{name:'6'}],
},
computed: {
paginatedWords: function (words) {
return vm.words.slice(2, 2);
}
}
});
I want to show only a portion of words with v-for,
Here is the Html:
<ul>
<li v-for="w in paginatedWords"> #{{w.name}} </li>
</ul>
But console gives me this error :
Error in render function: "TypeError: Cannot read property 'words' of
undefined"
What am I doing wrong?
Use this, not vm.
paginatedWords: function () {
return this.words.slice(2, 2);
}
Also, slice(2,2) will return an empty array. The first argument is where to start and the second is where to end. See slice.
Finally, the words argument is ignored.
var vm = new Vue({
el: '#test',
data: {
words: [{
name: '1'
}, {
name: '2'
}, {
name: '3'
}, {
name: '4'
}, {
name: '5'
}, {
name: '6'
}],
},
computed: {
paginatedWords: function() {
return this.words.slice(2, 4);
}
}
});
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="test">
<ul>
<li v-for="w in paginatedWords"> {{w.name}} </li>
</ul>
</div>
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.