반응형
커밋하지 않고 상태가 Vuex에서 업데이트됨
좀 답답한 문제가 있는데, 어떤 항목을 선택한 다음 모달이 열리고 Add / update to table을 클릭하기만 하면 "itemstabla" 상태로 커밋되지만, 결과적으로 테이블의 항목을 편집하기 위해 그것을 주고 모델이 열리며, 수량을 다른 숫자로 변경하게 된다.커밋을 실행하지 않고 상태 "instabla"가 업데이트되며, 모달 버튼을 클릭할 때만 실행되어야 한다.
내 가게:
let store = {
state: {
token: localStorage.getItem('access_token') || null,
items: [],
itemstabla: [],
monedas: [],
impuestos: [],
venta: [],
estadotienda: '',
},
getters: {
loggedIn(state) {
return state.token !== null
},
},
mutations: {
EliminarItemTabla(state, item) {
var index = state.itemstabla.findIndex(c => c.id == item);
state.itemstabla.splice(index, 1);
},
retrieveToken(state, token) {
state.token = token
},
setmonedas(state, monedas) {
state.monedas = monedas
},
setventa(state, venta) {
state.venta = venta
},
setitemstabla(state, items) {
let found = state.itemstabla.find(item => item.id == items.id);
if(found) {
if(items.accion=='agregar') {
found.cantidad = parseInt(found.cantidad) + parseInt(items.cantidad)
}
else {
found.cantidad = parseInt(items.cantidad)
}
}
else {
state.itemstabla.push(items)
}
},
actualizaritemstabla(state) {
state.itemstabla.forEach(function (item) {
if ((state.venta.moneda_id == 'S/' && item.moneda == 'S/') || (state.venta.moneda_id == '$' && item.moneda == '$')) {
item.precio = parseFloat(item.precio).toFixed(2)
}
else if(state.venta.moneda_id == '$' && item.moneda == 'S/') {
item.moneda = '$'
item.precio = parseFloat(parseFloat(item.precio) / parseFloat(state.venta.tipocambio)).toFixed(2)
}
else if(state.venta.moneda_id == 'S/' && item.moneda == '$') {
item.moneda = 'S/'
item.precio = parseFloat(parseFloat(item.precio) * parseFloat(state.venta.tipocambio)).toFixed(2)
}
});
},
setimpuestos(state, impuestos) {
state.impuestos = impuestos
},
setmonedaid(state, moneda_id) {
state.venta.moneda_id = moneda_id
},
settipocambio(state, tipocambio) {
state.venta.tipocambio = tipocambio
},
destroyToken(state) {
state.token = null
}
},
actions: {
retrieveToken(context, credentials) {
return new Promise((resolve, reject) => {
axios.post('/api/login', {
username: credentials.username,
password: credentials.password,
})
.then(response => {
const token = response.data.access_token
localStorage.setItem('access_token', token)
context.commit('retrieveToken', token)
resolve(response)
})
.catch(error => {
reject(error)
})
})
},
destroyToken(context) {
if (context.getters.loggedIn){
return new Promise((resolve, reject) => {
axios.post('/api/logout', '', {
headers: { Authorization: "Bearer " + context.state.token }
})
.then(response => {
localStorage.removeItem('access_token')
context.commit('destroyToken')
resolve(response)
})
.catch(error => {
localStorage.removeItem('access_token')
context.commit('destroyToken')
reject(error)
})
})
}
}
}
}
export default store
내 파일 Vue:
<template>
<div>
<!-- MODAL PARA EDITAR ITEM -->
<div class="modal fade" id="editarItem" tabindex="-1" role="dialog" aria-labelledby="editarItem" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Editar ítem</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group row">
<label for="cantidadEdit" class="col-sm-4 col-form-label col-form-label-sm font-weight-bold">Cantidad</label>
<div class="col-sm-8">
<div class="input-group">
<input v-model="item.cantidad" type="number" class="form-control text-center font-weight-bold h2" min="1" tabindex="1" onfocus="this.select();">
</div>
</div>
</div>
<div class="form-group row">
<label for="itemEdit" class="col-sm-4 col-form-label col-form-label-sm">Stock</label>
<div class="col-sm-8">
<input type="text" class="form-control text-center font-weight-bold h2" v-model="item.stock" disabled>
</div>
</div>
<div class="form-group row">
<label for="precioEdit" class="col-sm-4 col-form-label col-form-label-sm">Precio unitario<small class="text-muted" id="porcentajefinalprecio">+ {{item.primer_margen}}%</small></label>
<div class="col-sm-8">
<input v-model="item.precio" type="text" class="form-control font-weight-bold" tabindex="2" onfocus="this.select();">
</div>
</div>
<div class="form-group row">
<label for="" class="col-sm-4 col-form-label col-form-label-sm">Tipo de impuesto</label>
<div class="col-sm-8">
<select v-model="item.impuesto" class="imp custom-select" id="imp">
<option v-for="imp in impuestos" v-bind:key="imp.id" v-bind:value="imp.id">{{ imp.nombre }}</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="precioTotalEdit" class="col-sm-4 col-form-label col-form-label-sm">Subtotal <small id="simboloparatodos" class="text-muted">{{item.moneda_id}}</small></label>
<div class="col-sm-8">
<input type="text" v-model="subtotal" class="form-control form-control-sm" id="precioTotalEdit" onfocus="this.select();" readonly>
</div>
</div>
<div class="form-group row">
<label for="precioigvEdit" class="col-sm-4 col-form-label col-form-label-sm">I.G.V. </label>
<div class="col-sm-8">
<input type="text" v-model="igv" class="form-control form-control-sm" id="precioigvEdit" readonly>
</div>
</div>
<div class="form-group row">
<label for="descuentoEdit" class="col-sm-4 col-form-label col-form-label-sm">Descuento</label>
<div class="col-sm-8">
<input v-model="item.descuento" type="text" class="form-control form-control-sm" id="descuentoEdit" data-toggle="popover" data-placement="top" data-html="true" data-content="Para montos. Ej: 10<br>Para porcentajes agrega %. Ej: 10%" data-trigger="hover" tabindex="4" onfocus="this.select();">
</div>
</div>
<div class="form-group row">
<label for="precioSubtotalEdit" class="col-sm-4 col-form-label col-form-label-sm">Total <small id="simboloparatodos" class="text-muted">{{ moneda_id }}</small></label>
<div class="col-sm-8">
<input v-model="total" type="text" class="form-control font-weight-bold" id="precioSubtotalEdit" value="0" tabindex="5" onfocus="this.select();">
</div>
</div>
<div class="form-group row">
<label for="precio20Edit" class="col-sm-4 col-form-label col-form-label-sm">Precio <small class="text-muted" id="porcentajeinicial">+ {{item.primer_margen}}%</small></label>
<div class="col-sm-8">
<div id="margeninicialx">{{ item.masprimermargen }}</div>
</div>
</div>
<div class="form-group row">
<label for="precio35Edit" class="col-sm-4 col-form-label col-form-label-sm">Precio <small class="text-muted" id="porcentajefinal">+ {{item.segundo_margen}}%</small></label>
<div class="col-sm-8">
<div id="margenfinalx"> {{ item.massegundomargen }}</div>
</div>
</div>
<div class="form-group row">
<label for="itemEdit" class="col-sm-4 col-form-label col-form-label-sm">Item</label>
<div class="col-sm-8">
<small id="marcaEdit">{{ item.marca }}</small> <a href="#" title="" target="_blank" id="itemEdit" style="text-transform: capitalize;">{{ item.nombre }}</a><br><span class="text-muted small" title="códigos" id="codigoedit" v-for="cod in codigos" v-bind:key="cod.id">{{ cod.nombre_codigo }}-{{ cod.pivot.nombre }}<br></span>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Cancelar</button>
<button type="button" class="btn btn-sm btn-primary" tabindex="5" @click="anadiritem">Añadir</button>
</div>
</div>
</div>
</div>
<!-- FIN DE MODAL PARA EDITAR ITEM -->
<!-- SECCION SELECCIONAR ITEM Y AGREGAR A LA TABLA -->
<div class="">
<div class="input-group input-group-sm mb-3">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fas fa-search"></i></span>
</div>
<div class="prefetch">
<input type="text" id="item" class="form-control typeahead" placeholder="Buscar item (Ctrl+.)" v-model.trim="q" @keyup.enter="buscaritem">
</div>
<div class="input-group-append">
<button class="btn btn-outline-secondary" id="button-addon2" disabled></button>
</div>
</div>
</div>
<table class="table table-striped table-hover table-sm table-responsive-md text-nowrap mt-3" id="detailFactura">
<thead>
<tr>
<th>Ítem</th>
<th class="text-right">Cnt.</th>
<th class="text-right">Costo U.</th>
<th></th>
<th class="text-right text-nowrap">
SubTotal
</th>
<th class="text-right text-nowrap">
I.G.V
</th>
<th class="text-right text-nowrap"><span class="text-muted">
Total
<div id="monedaText"></div>
</span></th>
</tr>
</thead>
<tbody>
<tr v-for="itemtabla in itemstabla" v-bind:key="itemtabla.id">
<td class="overflow-hidden" style="max-width: 299px; text-overflow: ellipsis"><a href="#" title="" target="_blank">{{ item.nombre }}</a> <small class="text-muted">({{ itemtabla.marca }})</small> </td>
<td class="text-right"><small class="text-muted mr-1" title="Unidades">{{ itemtabla.unidad }}</small>{{ itemtabla.cantidad }}</td>
<td class="text-right">{{ itemtabla.precio }}</td>
<td class="text-right">
<a href="javascript:void(0);" class="edt" v-on:click="editaritem(itemtabla)"><i class="fas fa-pencil-alt mr-2"></i></a>
<a href="javascript:void(0);" class="borrar" v-on:click="deleteitem(itemtabla.id)"><i class="far fa-trash-alt"></i></a>
</td>
<td class="text-right">{{ preciosegunmoneda(itemtabla.precio, itemtabla.moneda, itemtabla.cantidad, itemtabla.impuesto, itemtabla.descuento).subtotal }}</td>
<td class="text-right">{{ preciosegunmoneda(itemtabla.precio, itemtabla.moneda, itemtabla.cantidad, itemtabla.impuesto, itemtabla.descuento).igv }}</td>
<td class="text-right">{{ preciosegunmoneda(itemtabla.precio, itemtabla.moneda, itemtabla.cantidad, itemtabla.impuesto, itemtabla.descuento).total }}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2" class="text-right" id="cantidadItems">{{ itemstabla.length }} </td>
<td class="small font-weight-bolder">ítem(s)</td>
</tr>
</tfoot>
</table>
<!-- FIN DE SECCION SELECCIONAR ITEM Y AGREGAR A LA TABLA -->
</div>
</template>
<script>
import {
required,
minLength,
maxLength,
between
} from 'vuelidate/lib/validators'
import Bloodhound from 'corejs-typeahead/dist/bloodhound';
import typeahead from 'corejs-typeahead/dist/typeahead.jquery';
export default {
name: 'tabla-item',
props: {
tienda: Number,
},
data() {
return {
resource: 'venta',
error: false,
submitStatus: null,
isLoading: false,
fullPage: true,
q: '',
suggestions: null,
item: {},
}
},
created() {
},
mounted() {
let contextoVue = this
// Cargar los datos del typeahead en items
this.suggestions = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
identify: function (item) {
return item.id;
},
remote: {
url: '/item/records/' + this.tienda + '/' + '%QUERY',
wildcard: '%QUERY'
}
});
let inputEl = $('.prefetch input');
inputEl.typeahead({
minLength: 1,
highlight: true,
}, {
name: 'suggestions',
source: this.suggestions,
limit: 20,
display: 'label',
templates: {
suggestion: (data) => {
let codigos = data.codigos
let nuevoscodigos = ""
codigos.forEach(function (valor, indice, array) {
nuevoscodigos = nuevoscodigos + valor.pivot.nombre + ','
});
let nuevoprecio = ((parseFloat(contextoVue.preciosegunmoneda(data.precio, data.moneda,'1',data.impuesto_id).precio) * parseFloat(data.primer_margen) / 100) + parseFloat(contextoVue.preciosegunmoneda(data.precio, data.moneda,'1',data.impuesto_id).precio)).toFixed(2)
return `<div class="ss-suggestion">
<div class="codigos">
${data.nombre_marca} <span title="Código global"> - ${nuevoscodigos}</span>
<span title="Código de barras"></span>
</div>
<div class="searchproducto" style="text-transform: capitalize;">
<strong>${data.nombre}</strong>
</div>
<div class="d-flex mt-1"><div class="searchprice text-primary">${contextoVue.moneda_id}
<span id="pricechange">${nuevoprecio}</span></div>
<div class="searchstock flex-grow-1 text-danger"><b>Stock</b>:
<b style="color: red;">${data.stock}</b><b></b></div></div></div>`;
}
}
});
// Cuando se hace click en un item
$('.prefetch input').bind('typeahead:selected', function (evt, suggestion) {
$('#editarItem').modal('show')
let preciosegunmoneda = ((parseFloat(contextoVue.preciosegunmoneda(suggestion.precio, suggestion.moneda, '1', suggestion.impuesto_id).precio) * parseFloat(suggestion.primer_margen) / 100) + parseFloat(contextoVue.preciosegunmoneda(suggestion.precio, suggestion.moneda, '1', suggestion.impuesto_id).precio)).toFixed(2)
let massegundomargen = ((parseFloat(contextoVue.preciosegunmoneda(suggestion.precio, suggestion.moneda, '1', suggestion.impuesto_id).precio) * parseFloat(suggestion.segundo_margen) / 100) + parseFloat(contextoVue.preciosegunmoneda(suggestion.precio, suggestion.moneda, '1', suggestion.impuesto_id).precio)).toFixed(2)
contextoVue.item = {
id: suggestion.id,
stock: suggestion.stock,
nombre: suggestion.nombre,
precio: preciosegunmoneda,
marca: suggestion.nombre_marca,
impuesto: suggestion.impuesto_id,
primer_margen: suggestion.primer_margen,
segundo_margen: suggestion.segundo_margen,
masprimermargen: preciosegunmoneda,
massegundomargen: massegundomargen,
codigos: suggestion.codigos,
cantidad: '1',
descuento: '0',
moneda: contextoVue.moneda_id,
unidad: suggestion.nombre_unidad,
}
});
// Fin typeahead items
},
updated() {
},
computed: {
total() {
return this.item.precio * this.item.cantidad - this.item.descuento
},
igv() {
if(this.item.impuesto=="1") {
return (parseFloat(this.total) * 18/100).toFixed(2)
}
else {
return 0
}
},
subtotal() {
return (parseFloat(this.total) - this.igv).toFixed(2)
},
tipocambio: {
get() {
return this.$store.state.venta.tipocambio
},
set(value) {
this.$store.commit('settipocambio', value)
}
},
moneda_id: {
get() {
return this.$store.state.venta.moneda_id
},
set(value) {
this.$store.commit('setmonedaid', value)
}
},
itemstabla: {
get() {
return this.$store.state.itemstabla
},
},
impuestos: {
get() {
return this.$store.state.impuestos
},
},
},
watch: {
moneda_id: function (val) {
//this.$store.commit('actualizaritemstabla')
},
},
methods: {
submit() {},
preciosegunmoneda(precio, moneda, cantidad, impuesto, descuento) {
let total,nuevoprecio,subtotal,igv = 0
if ((this.moneda_id == 'S/' && moneda == 'S/') || (this.moneda_id == '$' && moneda == '$')) {
nuevoprecio = parseFloat(precio).toFixed(2)
total = parseFloat((parseFloat(precio) * cantidad) - descuento).toFixed(2)
igv = parseFloat((parseFloat(total) * (impuesto=='1' ? 18/100 : 0))).toFixed(2)
subtotal = parseFloat(total - igv).toFixed(2)
return {precio: nuevoprecio, total: total, igv: igv, subtotal: subtotal }
}
else if (this.moneda_id == 'S/' && moneda == '$') {
nuevoprecio = parseFloat(precio * this.tipocambio).toFixed(2)
total = parseFloat((parseFloat(precio * this.tipocambio) * cantidad) - descuento).toFixed(2)
igv = parseFloat((parseFloat(total) * (impuesto=='1' ? 18/100 : 0))).toFixed(2)
subtotal = parseFloat(total - igv).toFixed(2)
return {precio: nuevoprecio, total: total, igv: igv, subtotal: subtotal }
}
else if (this.moneda_id == '$' && moneda == 'S/') {
nuevoprecio = parseFloat(precio / this.tipocambio).toFixed(2)
total = parseFloat((parseFloat(precio / this.tipocambio) * cantidad) - descuento).toFixed(2)
igv = parseFloat((parseFloat(total) * (impuesto=='1' ? 18/100 : 0))).toFixed(2)
subtotal = parseFloat(total - igv).toFixed(2)
return {precio: nuevoprecio, total: total, igv: igv, subtotal: subtotal }
}
},
deleteitem(i) {
this.$store.commit('EliminarItemTabla', i);
},
editaritem(item) {
$('#editarItem').modal('show')
this.item = item
},
anadiritem(event) {
$('#editarItem').modal('hide')
this.$store.commit('setitemstabla', this.item )
},
},
validations: {
form: {
nombre_codigo: {
required,
},
}
}
}
</script>
의 사용으로editaritem
너처럼, 내 생각엔 네가 실제로 그 물건을 전달하고 있는 것 같아. 그래서 참고사항인 만큼 수정되는 거야.
editaritem(item) {
$('#editarItem').modal('show')
this.item = { ...item } // or some way to copy the object
}
그리고 편집을 마친 후 편집된 객체의 실제 업데이트를 수행하십시오.
참조URL: https://stackoverflow.com/questions/63400864/i-do-not-commit-and-the-state-is-updated-in-vuex
반응형
'programing' 카테고리의 다른 글
VueJs 로컬 자산 경로 (0) | 2022.04.13 |
---|---|
VueJS에서 템플릿에 추가된 구성 요소를 동적으로 컴파일하는 방법 (0) | 2022.04.13 |
vuejs 2의 watch 메서드가 isAuth 값을 업데이트하지 않음 (0) | 2022.04.13 |
소품 기능을 아동 구성 요소에 전달하고, 거기서부터 전화를 거는 방법을 Vue에서? (0) | 2022.04.12 |
비동기 인증 상태 요청에 대한 Vuejs 경로 탐색 가드 (0) | 2022.04.12 |