I just wonder if its possible to pass data like this:
<tr v-for="item1 in items1">
<tr v-for="item in items">
<td><label>#{{ item.id }}</label></td>
<td><label>#{{ item.name }}</label></td>
<td><label>#{{ item.age }}</label></td>
<td><label>#{{ item.profession }}</label></td>
<td><label>#{{ item1.approval }}</label></td>
<td><label>#{{ item1.request }}</label></td>
</tr>
</tr>
in JS
data: {
items: [],
items1:[],
},
mounted: function mounted() {
this.getVueItems();
},
methods: {
getVueItems: function getVueItems() {
var _this = this;
axios.get('/vueitems').then(function (response) {
alert(response.data);
_this.items = response.data;
_this.items1 = response.data;
})
.catch(response => {
alert("WTF happen!?");
});
I want to know is this possible. Or is there any other options?.
Related
I'm stucked with this issue. When I click on some element it push an item to an array, and I show this array in a table. I want to add an action to delete any row of the table on this way for example:
Table
My code:
<div id="pos">
<div class="container-fluid" style="font-size: 0.8em;">
<div class="row grid-columns">
<div class="col-md-6 col">
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Descripcion</th>
<th>Stock</th>
<th>Precio uni</th>
<th>Precio alt</th>
<th>Cant</th>
<th>Subtotal</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<pos-products
:products="products"
v-on:remove-product="removeProduct"
>
</pos-products>
<!-- <tr v-for="item in products" :key="item.id">
<th scope="row">${item.id}</th>
<td>${ item.descripcion }</td>
<td>${ item.stock }</td>
<td>${ item.precio } $</td>
<td>${ item.precio_alt } $</td>
<td>
<v-minusplusfield :value="1" :min="1" :max="100" v-model="item.cant"></v-minusplusfield>
</td>
<td>${ getSubtotal(item) }</td>
<td> Borrar </td>
</tr> -->
</tbody>
</table>
</div>
<div class="col-md-6 col">
<div>
<div id="grid-header" class="p-2 border-b ">
<input class="form-control" name="searchString" placeholder="Buscar producto" type="text" v-model="searchString" />
</div>
</div>
<div style="background-color:#fff">
<div class="col-md-3" v-for="item in searchResults">
<a
href="#"
class="list-group-item"
:key="item.id"
#click="loadItem(item)"
>
<img src="//images03.nicepage.com/a1389d7bc73adea1e1c1fb7e/af4ca43bd20b5a5fab9f188a/pexels-photo-3373725.jpeg" alt="" class="u-expanded-width u-image u-image-default u-image-1" width="25" height="30">
<h6 class="u-text u-text-default u-text-1">${item.descripcion}</h6>
<h4 class="u-text u-text-default u-text-2">${item.precio}$ / ${item.precio_alt}$</h4>
</a>
</div>
</div>
</div>
</div>
</div>
Vue code:
const app = new Vue({
el: "#pos",
delimiters: ["${", "}"],
data () {
return {
products: [],
total: 0,
client: "",
user: "",
paymentDetail: [],
errors: {},
garantia: false,
saveButton: false,
seller: "",
searchString: "",
searchTypingTimeout: "",
searchResults: [],
}
},
methods: {
getSubtotal: function (item) {
return parseInt(item.cant) * parseFloat(item.precio);
},
loadItem: function (item) {
this.products.push({
id: item.id,
descripcion: item.descripcion,
stock: item.stock,
precio: item.precio,
precio_alt: item.precio_alt,
cant: 1,
});
},
removeItem: () => {
products = products.filter((el) => el !== item);
},
searchProducts: function (value) {
axios
.post("/v2/producto/search", {
query: value
})
.then((response) => {
if (!response.status == 200 || response.data.error) {
console.log('error')
const errorMessage = response.data.error
? response.data.error
: "Ha ocurrido un error";
console.log("mensaje: " + errorMessage);
this.$swal({
icon: "error",
title: "Oops...",
text: errorMessage,
});
return;
}
this.searchResults = response.data.data;
})
.catch((error) => {
console.log("catch error", error);
});
},
},
mounted() {
var csrf = document
.querySelector('meta[name="csrf-token"]')
.getAttribute("content");
this.products = [];
},
computed: {},
watch: {
total(val) {
this.total = parseFloat(val);
},
searchString(val) {
if (this.searchTypingTimeout) clearTimeout(this.searchTypingTimeout);
this.searchTypingTimeout = setTimeout(
() => this.searchProducts(this.searchString),
850
);
},
},
});
I got this:
vue.js?3de6:634 [Vue warn]: Property or method "removeItem" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
Try using classic function like this :
removeItem(item){
const index = this.items.findIndex(x => x.id === item.id)
this.items.splice(index, 1)
},
I've here loaded the data with the jsonplaceholder.typicode.com api
new Vue({
el: '#app',
data: () => ({
items: []
}),
async mounted(){
await axios.get('https://jsonplaceholder.typicode.com/posts')
.then(res => {
this.items = res.data
})
},
methods: {
removeItem(item){
const index = this.items.findIndex(x => x.id === item.id)
this.items.splice(index, 1)
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.min.js" integrity="sha512-odNmoc1XJy5x1TMVMdC7EMs3IVdItLPlCeL5vSUPN2llYKMJ2eByTTAIiiuqLg+GdNr9hF6z81p27DArRFKT7A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="app">
<h1>List </h1>
<ul>
<li v-for="item of items" :key="item.id">
<a #click="removeItem(item)">{{item.id}} - {{item.title}}</a>
</li>
</ul>
</div>
<template>
<div>
<v-data-table
:items="agents"
hide-default-footer
class="agent-table"
v-bind:pagination.sync="pagination">
<template slot="item" slot-scope="props">
<tr>
<td>{{ props.item.first_name }} {{ props.item.last_name }}</td>
<td>{{ props.item.email }}</td>
<td>{{ props.item.phone }}</td>
</tr>
</template>
</v-data-table>
<div >
<v-pagination v-model="pagination.page" :length="pages" :total-visible="7"></v-pagination>
</div>
</div>
<template>
<script>
export default {
data: function() {
return {
pagination: {
rowsPerPage: 15,
page: 1
},
agents:[]
}
},
computed: {
pages () {
return this.pagination.rowsPerPage && this.agents.length !== 0 ? Math.ceil(this.agents.length / this.pagination.rowsPerPage) : 0
},
},
created() {
this.fetchAgents();
}
methods: {
fetchAgentss() {
var that = this;
this.$axios.get('agents.json')
.then(response => {
that.agents = response.data.agents;
});
}
}
}
</script>
I am upgrading from vuetify version 1.0.5 to 2.3.10 and I am using v-pagination for custom pagination but I am getting this error
[breaking] 'pagination' has been removed, use 'options' instead
Please help me find where I am going wrong
Instead of using v-bind:pagination.sync use v-bind:options.sync
{
page: number,
itemsPerPage: number,
sortBy: string[],
sortDesc: boolean[],
groupBy: string[],
groupDesc: boolean[],
multiSort: boolean,
mustSort: boolean
}
Refer Official API
For Example
I've some problems with list rendering and filtering the data with computed properties
Instead of hardcoded row.age value, I'd like to use filterKey to filter row.age.
How to archieve this? I just don't get it.
Here's my example:
template:
<button type="button" class="btn btn-t1-secondary" v-on: click="filterKey = '15'">11</button>
<button type="button" class="btn btn-t1-secondary" v-on: click="filterKey = '30'">8</button>
<table>
<thead>
<tr>
<th>Category</th>
<th>Age</th>
<th>Food</th>
</tr>
</thead>
<tbody>
<tr v-for="row in filteredCategory">
<td>{{ row.category }}</td>
<td>{{ row.age }}</td>
<td>{{ row.food }}</td>
</tr>
</tbody>
</table>
JavaScript:
<script>
var app = new Vue({
el: '#app',
data: {
filterKey: '',
filterCategory: '',
dataToFilter: [
{
category: 'dog',
age: '11',
food: 'bone'
},
{
category: 'cat',
age: '8',
food: 'fish'
}
//etc.
]
},
computed: {
filteredCategory() {
return this.dataToFilter.filter(function (row) {
return row.category === 'dog'
})
.filter(function (row) {
console.log(this.filterKey)
return row.age === '15'
})
},
}
})
</script>
Solution
As #Sadraque_Santos suggested, I used arrow functions.
Code
filteredCategory() {
return this.dataToFilter.filter( r => r.category === 'dog' && r.age === this.filterKey);
}
Also, I have to support IE11 so I just use Babel to compile the code for me.
To have access to this inside a filter, map or another useful method you must learn about arrow functions, they allow you to create a function without the this bound to that object, so instead of using:
filteredCategory () {
return this.dataToFilter.filter(function (row) {
return row.category === 'dog'
})
.filter(function (row) {
console.log(this.filterKey)
return row.age === '15'
})
}
Your code should be like this:
filteredCategory () {
return this.dataToFilter
.filter((row) => row.category === this.filterCategory)
.filter((row) => row.age === this.filterKey)
}
I have following main instance of Vue:
let App = new Vue({
el: '#app-container',
data: {
countries: []
},
created() {
this.getCountries()
},
methods: {
getCountries() {
let self = this;
axios.get('/admin/countries')
.then(function (response) {
self.countries = response.data;
})
.catch(function (error) {
console.log(error);
});
},
filterCountries(event) {
let name = event.target.value;
let self = this;
if(name.length > 2) {
axios.get('/country/search', {
params: {
name: name
}
})
.then(function (response) {
self.countries = response.data;
})
.catch(function (error) {
console.log(error);
});
}
if((event.keyCode === 8 && name.length == 2) || !name.length){
this.getCountries();
}
},
updateCountry(event) {
let parent = event.target.closest('.parent');
let countryName = parent.getElementsByClassName('country-name')[0].value;
let countryOrder = parent.getElementsByClassName('country-order')[0].value;
axios.post('/country/insert', {
countryName: countryName,
countryOrder: countryOrder
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
}
})
I have this template which is working:
Vue.component('country-list', {
template: `
<tbody>
<tr is="country" v-for="country in countries.data">
<td>
<input
type="text"
name="name"
class="form-control country-name"
:value="country.name"
>
</td>
<td>{{country.show? 'Yes' : 'No'}}</td>
<td>
<input
type="text"
name="order"
class="form-control country-order"
:value="country.order"
>
</td>
<td>
<button class="btn btn-primary">{{ country.show ? "Hide" : "Show" }}</button>
<button class="btn btn-success"
#click="updateCountry"
:data-id="country.id">Update</button>
</td>
</tr>
</tbody>
`,
props: ['countries'],
methods: {
updateCountry(event) {
let countryID = event.target.dataset.id;
let parent = event.target.closest('.parent');
let countryName = parent.getElementsByClassName('country-name')[0].value;
let countryOrder = parent.getElementsByClassName('country-order')[0].value;
axios.post('/country/insert', {
id: countryID,
name: countryName,
order: countryOrder
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
}
});
Vue.component('country', {
template: `<tr class=parent><slot></slot></tr>`
});
I am trying to make another template with the same prop (countries) but I am getting nothing (in this case I have following error:
vendor.js:753 [Vue warn]: Error in render function: "TypeError: Cannot read property 'current_page' of undefined"
found in
---> <PaginationList>
<Root>
):
Vue.component('pagination-list', {
template: `
<tfoot>
<tr>
<td>{{countries.current_page}}</td>
</tr>
</tfoot>
`,
props: ['countries']
});
HTML code where the template is used:
<table class="table table-striped table-hover">
<thead>
<tr>
<td>
<input
class="form-control"
type="text"
id="country-filter"
#keyup="filterCountries"
placeholder="Filter countries by name">
</td>
</tr>
<tr>
<td>Country Name</td>
<td>Visible</td>
<td>Order</td>
<td>Actions</td>
</tr>
</thead>
<tbody is="country-list" :countries="countries"></tbody>
<tfoot is="pagination-list"></tfoot>
</table>
console.log(self.countries) data:
Object {…}
current_page:1
data:Array(20)
from:1
last_page:13
next_page_url:"http://smuvajse.app/admin/countries?page=2"
path:"http://smuvajse.app/admin/countries"
per_page:20
prev_page_url:null
to:20
total:249
__ob__:Observer
get current_page:function reactiveGetter()
set current_page:function reactiveSetter(newVal)
get data:function reactiveGetter()
set data:function reactiveSetter(newVal)
get from:function reactiveGetter()
set from:function reactiveSetter(newVal)
get last_page:function reactiveGetter()
set last_page:function reactiveSetter(newVal)
get next_page_url:function reactiveGetter()
set next_page_url:function reactiveSetter(newVal)
get path:function reactiveGetter()
set path:function reactiveSetter(newVal)
get per_page:function reactiveGetter()
set per_page:function reactiveSetter(newVal)
get prev_page_url:function reactiveGetter()
set prev_page_url:function reactiveSetter(newVal)
get to:function reactiveGetter()
set to:function reactiveSetter(newVal)
get total:function reactiveGetter()
set total:function reactiveSetter(newVal)
__proto__:Object
You are not passing the prop through your template:
<tfoot is="pagination-list"></tfoot>
should be:
<tfoot is="pagination-list" :countries="countries"></tfoot>
Hi everyone.
I have a question about looping over a component in vuejs.
I defined a component and also a template tag which contains a table that fetches some data from database(in laravel framework).now i need to loop over this component more than 10 times and don't know how to do this!.
i used v-for in template tag but didn't work
<div id="app">
<csgo><csgo>
</div>
<template id="match-id" >
<table style="border: 2px solid black">
<tr >
<th>Ticket</th>
<th>Number</th>
<th>Match Type</th>
<th>Date</th>
<th>Time</th>
<th>Price</th>
<th>Sold</th>
</tr>
<tr>
<td> <button #click='buy({{$user->profile->account_money}})' v-bind:style="objectStyle" :disabled=Bstate >BUY</button> </td>
<td><input type="number" min="1" max="10" step="1" v-model="ticketNumber"></td>
<td>{{$matches[0]->matchType}}</td>
<td>{{$matches[0]->matchDate}}</td>
<td>{{$matches[0]->matchTime}}</td>
<td>{{$matches[0]->price}}</td>
<td>#{{soldTicket}}#{{sold}}</td>
</tr>
</table>
</template>
<script>
Vue.component('csgo', {
template: '#match-id',
data: function () {
return {
money: '',
sold: '',
state: false,
Estate: false,
Bstate: false,
error: '',
ticketNumber: 1,
objectStyle: {
background: 'lightgreen'
},
}
},
props: ['matches'],
methods: {
buy: function (num) {
tempNum = num
num -= 1000
if (num < 0) {
this.money = tempNum
}
vm = this
axios.post('/matches/csgo-buy-ticket', {tickets:
Math.floor(vm.ticketNumber)}).then(function (response) {
if (typeof (response.data) == 'string') {
vm.error = response.data
vm.state = false
vm.Estate = !vm.state
vm.Bstate = false
}
else {
vm.money = response.data[0]
vm.sold = response.data[1]
vm.state = true
vm.Estate = !vm.state
vm.Bstate = true
vm.objectStyle.background = 'darkred'
}
})
},
},
computed: {
soldTicket: function () {
vm = this
axios.get('/sold-ticket').then(function (response) {
return vm.sold = response.data
})
},
account_money: function () {
var vm = this
axios.get('/user-account-money').then(function
(response) {
vm.money = response.data
})
},
},
})
new Vue({
el:'#app',
data:{
list:[''],
},
created:function () {
vm = this
axios.get('/csgo-matches').then(function (response) {
console.log(response.data)
vm.list = response.data
})
},
})
</script>