I am using Vue for quite sometime now but having troubles on accessing certain property of my object..
I have object named "table" with "data" and "Paginate" properties that is being passed as a Props to my Datatable Vue component. When I try to console.log the "table" object on my Datatable component, I can see that the "data" and "Paginate" properties has values, but when I try to access the using "this.table.data" I get 0 values..
here is the structure of my table object:
table : {
data : array[7],
paginate: Object
}
trying to access the this.table.data on "Mount" of the Vue instance.
Thanks for the help!
Component Code:
<script>
window.Event = new Vue();
export default {
props: {
tableid: String,
settings: Object,
table: Object,
},
mounted: function(){
console.log(this.table);
}
</script>
Vue.component('table-show', {
template: '#table-show',
props: {
table: Object,
}
});
new Vue({
el: '#app',
data: {
tables: [{
data: [1, 2, 3],
paginate: true
}, {
data: [4, 5, 6],
paginate: true
}, {
data: [7, 8, 9],
paginate: false
}, ],
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.5/vue.js"></script>
<template id="table-show">
<li>{{table.data}}</li>
</template>
<div id="app">
<ul>
<table-show v-for="table in tables" :table="table"></table-show>
</ul>
<pre>
{{$data.tables}}
</pre>
</div>
Related
Please excuse my ignorance as a new web developer, but I can't seem to get the <b-paginate> component to work in my single file Django and Vue 2 app. I access Bootstrap Vue via CDN.
This is my component, which is placed directly above my main Vue app:
let paginationComponent = Vue.component('pagination-component', {
name: 'paginationComponent',
props:['pantryItems'],
template:`<div class="overflow-auto"><b-pagination
v-model="currentPage"
:total-rows="rows"
:per-page="perPage"
first-text="First"
prev-text="Prev"
next-text="Next"
last-text="Last"
class="mt-4"
></b-pagination></div>`,
data: function() {
return {
rows: this.pantryItems.length,
perPage: 10,
currentPage: 1,
}
},
computed: {
rows: function() {
return this.pantryItems.length
}
}
})
and this is my Vue root app:
let mypantryapp = new Vue ({
el: "#app",
delimiters: ['[[', ']]'],
components: {'pagination-component': paginationComponent},
data: {
pantryItems: [],
name: '',
users: [],
itemName: '',
createdDate: '',
expirationDate: '',
csrf_token: '',
itemErrors: {currentUser: false},
currentUser: {id: false},
owner: '',
itemImgs: [],
tags: [],
by_category: false,
grocery_view: false,
...followed by a bunch of unrelated methods for my pantry inventory app.
This is how I call it in my HTML:
<b-pagination :pantry-items='pantryItems' ></b-pagination>
The component renders on the page with just the number 1 in the middle of the pagination button group and all other buttons greyed out.
The only mistake you've made here is confusing b-pagination for your own pagination-component child component.
You're invoking b-pagination perfectly in your template option, you just need to add the child component itself into your HTML to actually use it. The template parameter will replace the HTML of your child component in the DOM.
Simply change:
<b-pagination :pantry-items='pantryItems'></b-pagination>
to:
<pagination-component :pantry-items='pantryItems'></pagination-component>
And it should work correctly! Example below:
let paginationComponent = Vue.component('pagination-component', {
name: 'paginationComponent',
props: ['pantryItems'],
template: `<div class="overflow-auto"><b-pagination
v-model="currentPage"
:total-rows="rows"
:per-page="perPage"
first-text="First"
prev-text="Prev"
next-text="Next"
last-text="Last"
class="mt-4"
></b-pagination></div>`,
data: function() {
return {
//rows: this.pantryItems.length, *** See note below
perPage: 1, //Lower perPage for example sake
currentPage: 1,
}
},
computed: {
rows: function() {
return this.pantryItems.length
}
}
});
let mypantryapp = new Vue({
el: "#app",
delimiters: ['[[', ']]'],
components: {
'pagination-component': paginationComponent
},
data: {
pantryItems: [1, 2, 3, 4, 5], //Dummy items for example sake
}
});
<!-- Set up Vue and Bootstrap-Vue for snippet -->
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap#4/dist/css/bootstrap.min.css" /><link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.css" /><script src="//unpkg.com/vue#latest/dist/vue.min.js"></script><script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>
<div id="app">
<pagination-component :pantry-items='pantryItems'></pagination-component>
</div>
As one final note, you need only declare rows once. In this case, you should remove it from data, because it will change if your total items changes. Your computed rows will reflect the change, the rows var in data will not (since it will be set once at startup and then never again).
I need to display key value from object. Here is my code:
new Vue({
el: '#app',
data: {
x: {"2018-05-11":{"may":4,"june":8,"april":5}}
}
})
In my template I would like to display: 2018-05-11, but not {"2018-05-11":{"may":4,"june":8,"april":5}}. How I can do it?
https://jsfiddle.net/grnok86b/
You can use computed and Object.keys for return key as value.
for example:
new Vue({
el: '#app',
data: {
x: {
"2018-05-11": {
"may": 4,
"june": 8,
"april": 5
}
}
},
computed: {
date() {
return Object.keys(this.x)[0];
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<p>My date is {{date}}</p>
</div>
you can loop it if you want
You can always create a computed method:
new Vue({
el: '#app',
data: {
x: {
"2018-05-11": {
"may": 4,
"june": 8,
"april": 5
}
}
},
computed: {
foo() {
return Object.keys(this.x)[0]
}
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<p>{{ foo }}</p>
</div>
I have created a function even to do this procedure.
HTML
<p v-for="entidade in relato.entidade">${acessaEntidade(entidade)}</p>
The function in methods
JS
acessaEntidade: function (id) {
return this.entidades['nome' + id]
},
In the case I have a variable that is loaded and that variable there are indexes, 1, 2, 3 ... I get these indexes and consult in a new function to return the value by querying on another variable. If you need help, tell me by email :)
I would like to get an array of the values of a Vue Object.
Object.values(obj) does not work as Vue translates object values to getters/setters: https://v2.vuejs.org/v2/guide/reactivity.html
It does work (see below). Since you are looking for the whole data object, you can get it by Object.values(this.$data):
new Vue({
el: '#app',
data: {
message: 'Open the console for a better view',
person: {
name: {first_name: 'Alice', surname: 'Smith'},
age: 15
}
},
methods: {
print() {
console.log(Object.values(this.person));
console.log(Object.values(this.person.name));
console.log(Object.values(this.$data));
}
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<p>{{ message }}</p>
<button #click="print">print</button>
</div>
I am trying to create a component and get its :key for using in axios.
The element is created, but I can't get a key. It's undefined.
<div class="container" id="root">
<paddock is="paddock-item" v-for="paddock in paddocks" :key="paddock.key" class="paddock">
</paddock>
</div>
<script>
var pItem = {
props: ['key'],
template: '<div :test="key"></div>',
created: function() {
console.log(key);
}
};
new Vue({
el: '#root',
components: {
'paddock-item': pItem
},
data: {
paddocks: [
{key: 1},
{key: 2},
{key: 3},
{key: 4}
]
}
})
</script>
I tried some variants, but no result. key was empty.
you don't need to use an extra attribute. You can get the key by
this.$vnode.key
In Vue 3 you can get the key with:
import { getCurrentInstance} from "vue";
getCurrentInstance().vnode.key
This answer answers the question of how you would pass the key to a child component. If you just want to get the current key from inside the child component, use the highest voted answer.
`key` is a [special attribute][1] in Vue. You will have to call your property something else.
Here is an alternative using pkey instead.
console.clear()
var pItem = {
props: ['pkey'],
template: '<div :test="pkey"></div>',
created: function() {
console.log(this.pkey);
}
};
new Vue({
el: '#root',
components: {
'paddock-item': pItem
},
data: {
paddocks: [{
key: 1
},
{
key: 2
},
{
key: 3
},
{
key: 4
}
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div class="container" id="root">
<paddock-item v-for="paddock in paddocks" :pkey="paddock.key" :key="paddock.key" class="paddock">
</paddock-item>
</div>
In Vue 3 you can get the key by
this.$.vnode.key
Using this.$options._parentVnode.key work for me:
created() {
console.log(this.$options._parentVnode.key)
}
Using Vue extension for chrome you can see the keys in the elements tree:
Here is the link to extension:
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
I am fairly new to vue and can't figure out how to add data values within a template. I am trying to build a very basic form builder. If I click on a button it should add another array of data into a components variable. This is working. The I am doing a v-for to add input fields where some of the attributes are apart of the array for that component. I get it so it will add the input but no values are being passed into the input.
I have created a jsfiddle with where I am stuck at. https://jsfiddle.net/a9koj9gv/2/
<div id="app">
<button #click="add_text_input">New Text Input Field</button>
<my-component v-for="comp in components"></my-component>
<pre>{{ $data | json }}</pre>
</div>
new Vue({
el: "#app",
data: function() {
return {
components: [{
name: "first_name",
showname: "First Name",
type: "text",
required: "false",
fee: "0"
}]
}
},
components: {
'my-component': {
template: '<div>{{ showname }}: <input v-bind:name="name" v-bind:type="type"></div>',
props: ['showname', 'type', 'name']
}
},
methods: {
add_text_input: function() {
var array = {
name: "last_name",
showname: "Last Name",
type: "text",
required: "false",
fee: "0"
};
this.components.push(array);
}
}
})
I appreciate any help as I know I am just missing something obvious.
Thanks
Use props to pass data into the component.
Currently you have <my-component v-for="comp in components"></my-component>, which doesn't bind any props to the component.
Instead, do:
<my-component :showname="comp.showname"
:type="comp.type"
:name="comp.name"
v-for="comp in components"
></my-component>
Here is a fork of your fiddle with the change.
while asemahle got it right, here is a boiled down version on how to expose data to the child component. SFC:
async created() {
await this.setTemplate();
},
methods: {
async setTemplate() {
// const templateString = await axios.get..
this.t = {
template: templateString,
props: ['foo'],
}
},
},
data() {
return {
foo: 'bar',
t: null
}
}
};
</script>
<template>
<component :is="t" :foo="foo"></component>
It pulls a template string that is compiled/transpiled into a js-render-function. In this case with Vite with esm to have a client-side compiler available:
resolve: {
alias: {
// https://github.com/vuejs/core/tree/main/packages/vue#with-a-bundler
vue: "vue/dist/vue.esm-bundler.js",
the index.js bundle size increases by few kb, in my case 30kb (which is minimal)
You could now add some what-if-fail and show-while-loading with defineasynccomponent