Kendo-dropdownlist for VUE from array of objects shows "NO DATA FOUND" message - vue.js

I'm having trouble getting the kendo-dropdownlist for VUE working inside a custom component. The component renders, there's no errors in the console, but no options are shown in the list.
I've broken the code down into this bit:
<template>
<div>
<kendo-dropdownlist
:data-items="months"
:text-field="'text'"
:data-item-key="'value'"
></kendo-dropdownlist>
</div>
</template>
<script>
export default {
name: "demo",
data() {
return {
months: [
{
text: "January",
value: 1,
numDays: 31
},
{
text: "February",
value: 2,
numDays: 28
},
{
text: "March",
value: 3,
numDays: 31
}
]
};
}
};
</script>
Does anyone see what I'm doing wrong?

You are writting wrong props, see docs:
<kendo-dropdownlist
:data-source="months"
:data-text-field="'text'"
:data-value-field="'value'">
</kendo-dropdownlist>

Related

How to dynamically insert text in Ckeditor5 for Vue 2

My application provides many selectable standard paragraphs which users can insert at any point. In a previous version insertion was simple: CKEDITOR.instances[editorId].insertHTML(text).
I'm trying to use v5 api with model.insertContent(text) but get error:
"vue.runtime.esm.js:3020 TypeError: t2.is is not a function
at bl.rp (converters.js:771:21)
at bl.fire (emittermixin.js:199:30)
at <computed> (observablemixin.js:262:16)
at VueComponent.testInsert (Test.vue:29:1)"
Here's the composition file. I have tried accessing the insertContent method from this.editor and from the apiReference returned from the #ready event;
<template>
<div>
<button #click="testInsert('abracadabra')">Insert literal content</button>
<ckeditor tag-name="textarea" :editor="editor" v-model="doc.HTML" #ready="editorReady" :config="editorConfig"></ckeditor>
</div>
</template>
<script>
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
export default {
name: 'testEditorInsert',
mounted() {
},
data() {
return {
doc: {ID: 0, HTML: "This is a sample text. Insert here? This is the remainder of the sample text"},
editor: ClassicEditor,
editorData: 'loading',
editorConfig: {
toolbar: [ 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote' ],
},
editorApi:null ,
}
},
methods: {
testInsert: function(text) {
console.log(this.editorApi, text);
//this.editor.model.insertContent(text);
this.editorApi.model.insertContent(text);
},
editorReady: function(editor) {
this.editorApi = editor;
}
},
}
</script>

VueJs Pass array of object to child component do not refresh on changes

I'm trying to pass an array of object to a childComponent as prop but when I add an object in it, it doesn't render. (Note: I'm working on vuejs 2.6)
I suppose it has a link with the "monitoring" of the items of the array and not the array itself? Stuff is that if I do not pass the prop and use the default value instead, it's working perfectly. I think I'm missing something here. Could someone help me ?
By curiosity is this kind of behavior still stand with vue3js ?
As you can see below:
App.vue:
<template>
<div id="app">
<Card
v-for="user in users"
:key="user.userId"
:userId="user.userId"
:username="getUsernameFromUserId(user.userId)"
:links="getUserLinksFromUserId(user.userId)"
/>
</div>
</template>
<script>
import Card from "./components/Card.vue";
export default {
name: "App",
components: {
Card,
},
data: function () {
return {
users: [
{ userId: 1, name: "Bob" },
{ userId: 2, name: "Alice" },
{ userId: 3, name: "Eliot" },
],
links: [
{ userId: 1, link: "hello->world" },
{ userId: 1, link: "world->!" },
{ userId: 3, link: "hello->back" },
{ userId: 4, link: "hello->you" },
],
};
},
methods: {
getUsernameFromUserId: function (userId) {
return this.users.filter((obj) => obj.userId == userId)?.[0]?.name ?? "Not found";
},
getUserLinksFromUserId: function (userId) {
return this.links.filter((obj) => obj.userId == userId);
},
},
};
</script>
Card.vue
<template>
<div class="card">
<h1>{{ username }}</h1>
<button #click="addLink">Add One link</button><br><br>
<span v-if="links.length == 0">No links</span>
<div class="links">
<Link v-for="link in links" :key="links.indexOf(link)" :link="link"></Link>
</div>
</div>
</template>
<script>
import Link from '../components/Link'
export default {
components:{Link},
props: {
userId: Number,
username: String,
links: { type: Array, default: () => [], required: false },
},
methods:{
addLink: function(){
this.links.push({
userId: this.userId,
link: 'newlink->cool'
});
}
}
}
</script>
Link.vue
<template>
<div>
<span>UserId: {{ this.link.userId }} Link: {{ this.link.link }</span>
</div>
</template>
<script>
export default {
props: {
link: { type: Object, default: () => [], required: false },
},
};
</script>
This is a bad way to work with props
Note: do not focus on Dev Tools too much as it can be "buggy" at times - especially if you use Vue in a wrong way. Focus on your app output
Your Card.vue component is modifying (push) a prop, which is not recommended but it sort of works if the prop is object/Array and you do not replace it, just modify it's content (as you do)
But in your case, the values passed to props are actually generated by a method! The getUserLinksFromUserId method is generating a new array every time it is called, and this array is NOT reactive. So by pushing to it, your component will not re-render and what is worse, parent's links array is not changed at all! (on top of that - if App.vue ever re-renders, it will generate new arrays, pass it to pros and your modified arrys will be forgoten)
So intead of modifying links prop in Card.vue, just emit an event and do the modification in App.vue

Vuejs - Component not rendering to screen

I'm trying to create a vue app for budget tracking and I have a BudgetItems component that I want to render in the /budget route. All the other components and raw HTML render but this one component does not
This is the BudgetItems component:
<template>
<div>
<BudgetItem v-for="item in Items" v-bind:key='item.id' v-bind:Item="item" />
</div>
</template>
<script>
import BudgetItem from './BudgetItem'
export default {
name: 'BudgetItems',
components: {
BudgetItem,
},
props: [
'Items'
]
}
</script>
And this is the BudgetItem component I used to render a single item:
<template>
<div class="budgetitem">
<h1>{{item.title}}</h1>
<h1>{{item.value}}</h1>
</div>
</template>
<script>
export default {
name: 'BudgetItem',
props: [
'Item'
]
}
</script>
Last of all, this is the Budget page view:
<template>
<div class="budget">
<Nav />
<h1>Budget</h1>
<BudgetItems v-bind:Items="items" />
</div>
</template>
<script>
import Nav from "../components/Nav"
import BudgetItems from "../components/BudgetItems"
export default {
name: 'Budget',
components: {
Nav,
BudgetItems,
},
data(){
return{
items: [
{
id: 1,
income: false,
title: "Item 1",
value: 200
},
{
id: 2,
income: true,
title: "Item 2",
value: 500
},
{
id: 3,
income: false,
title: "Item 3",
value: 10
},
]
}
}
}
</script>
Also, when I look in the vue dev tools tab, the component appears, it just doesn't show on the screen
You need to change the v-bind declarations to lower case. Replace each instance of Items and Item with items and item.
Vue.JS doesn't like it if you capitalise props when using binding.
Please read this for more explanation.
Essentially, browsers treat all attribute names as lowercase. As a result, it interprets "Items" as being "items".
Budget page view:
<BudgetItems v-bind:items="items" />
BudgetItems:
<BudgetItem v-for="item in items" v-bind:key='item.id' v-bind:item="item"/>
props: [
'items'
]
BudgetItem:
props: [
'item'
]
Once you make these changes, it works perfectly as seen here:

Vue Component Not Displaying Nested Div

I have a component that works fine. However, when I appended <div :id="hint"></div> to the component this specific DIV isn't rendering. I'm sure it has something to do with the way I'm using a DIV to reference the template in my HTML but I don't know how to refine it.
<div
ref="boxAnswers"
is="box-answers"
v-for="box in boxes.slice().reverse()"
v-bind:key="box.id"
v-bind:level="box.level"
v-bind:hint="box.hint"
></div>
Vue.component('box-answers', {
props: ['level','hint'],
template: '<div class="droppable answer ui-widget-header" :id="level"></div><div :id="hint"></div>'
});
new Vue({
el: '#mainapp',
data: {
boxes: [
{ id: 1, level: 'baselevel-1', hint: 'hint-1' },
{ id: 2, level: 'baselevel-2', hint: 'hint-2' },
{ id: 3, level: 'baselevel-3', hint: 'hint-3' },
{ id: 4, level: 'baselevel-4', hint: 'hint-4' },
{ id: 5, level: 'baselevel-5', hint: 'hint-5' }
]
}
});

How to pass the props data to another component correctly in Vue.js

I'm trying to create a simple card component CustomCard.vue and re-use it on HomeComponent.vue page with specified data, so I've created a loop and put the needed data in cards: []
I don't know why it doesn't work. I can see the 3 elements on the page but they are displayed with the default values of the component, instead of taking the data from the cards:[].
HomeComponent.vue:
...
<custom-card v-for="n in cards" :key="n">
<img :src="n.cardImage" alt="">
<p>{{n.cardDesc}}</p>
</custom-card>
...
<script>
export default {
data() {
return {
cardImage: "",
cardDesc: "",
cards: [
{id: "1", cardImage: "../src/assets/img1.jpg", cardDesc: "some description 1"},
{id: "2", cardImage: "../src/assets/img2.jpg", cardDesc: "some description 2"},
{id: "3", cardImage: "../src/assets/img3.jpg", cardDesc: "some description 3"}
]
}
}
}
</script>
CustomCard.vue:
<template>
<div>
<img :src="cardImage" alt="">
<p>{{cardDesc}}</p>
</div>
</template>
<script>
export default {
data () {
return {
cardImage: "../src/assets/default.jpg",
cardDesc: "default description text"
}
}
// props: ['cardDesc', 'cardImage']
}
</script>
I want these values below to be the default component values just as a placeholder (so I've put them in components data):
cardImage: "../src/assets/default.jpg",
cardDesc: "default description text"
If I pass the props out, I get an error: [Vue warn]: The data property "cardImage" is already declared as a prop. Use prop default value instead.
So I commented it out for now.
I've registered the CustomCard.vue globally in index.js:
Your component has no slots so there's no reason to include any content.
Seems to me you just need
<custom-card v-for="card in cards" :key="card.id"
:card-desc="card.cardDesc"
:card-image="card.cardImage" />
Note the key is set to the actual unique identifier for each iterable element.
You should of course un-comment the props declaration and remove the conflicting data keys from your component. As mentioned in the error message, you can also set default values
export default {
props: {
cardDesc: {
type: String,
default: 'default description text'
},
cardImage: {
type: String,
default: '../src/assets/default.jpg'
}
},
data () { // probably don't even need a data property
return {}
}
}