Это мой первый проект в Vue, представляющий собой преобразование приложения, написанного на JQuery.
У меня есть SPA, который по сути состоит из 4 форм в мастере.У меня есть все состояние приложения в главном контроллере, и каждая форма создается как отдельный компонент для разделения кода, но тесно связана с приложением и не может использоваться повторно.Первая форма имеет четыре автозаполнения с опережением ввода, которые являются универсальным компонентом.опережающий тип v-связывает массив объектов в качестве списка поиска, v-связывает свойство объекта для поиска и испускает выбранный объект с помощью this.$emit
, мне нужно обновить определенное свойство в данных родительского (корневого) объектаобъект, но свойство в выбранном элементе будет отличаться для каждого обновления.В настоящее время я делаю это с помощью v-bind другой опоры для типа вперед: метод event_to_emit and the selected()
затем выполняет this.$emit(this.event_to_emit,this.selected)
, а для компонента формы (родительского) у меня есть прослушиватель событий для этого конкретного события, и в этом случае я делаюthis.$parent.datafield = event.field_i_am_interested_in
.
Это допустимое использование this.$parent
, так как форма тесно связана с корнем или это анти-шаблон.Буду ли я лучше делать this.$emit('update_parent',{field_to_update:'parent_field', value:event.field})
.это чувствует себя чище, но требует большего развития и обслуживания.Или я получил конструкцию этого совершенно неправильно?
Обратите внимание, что на данный момент все это приложение находится в одном теге, и я не использую vuex, модуль импорта / экспорта или веб-пакет на бэк-конец, как я переписываю приложение, которое в настоящее время находится в JQuery.Он используется только в интрасети, поэтому размер пакета и время рендеринга не имеют значения для этого доказательства концепции.
Код:
var app = new Vue({
el:"#vueapp",
data:{
style:{
name:"",
description:"",
supplier:"",
supplierRef:"",
garmentCategory:"",
brand:"",
priceList:"",
sizeType:"",
colours:[
],
sizes:[
],
skus:[
]
}
}
Vue.component('style-header',{
props:[],
data(){
return {
styleName:"",
styleDescription:"",
supplier:"",
supplierID:"",
supplierCode:"",
supplierRef:"",
garmentCategory:"",
brand:"",
priceList:""
}
template:'#style-header',
methods:{
/*typeAhead event listeners*/
updateSupplier(event){ /*fires when the correct t-a is updated*/
console.log("updateSupplier: ", event);
this.supplierName = event.desc;
this.supplierID = event.ID;
this.$parent.style.supplierID = event.id; /* <-- is this a code smell? */
this.$parent.style.supplier = event.desc;
}
}
}
Vue.component('type-ahead',{
template:"#auto-complete",
props: {
items: {
default: ()=> {return []},
type: Array
}
,return_event:{
type: String
}
,
filterby: {
type: String
},
title: {
default: 'Select One...',
type: String
},
should_reset: {
type: Boolean,
default: true
},
return_id:{
type:String
}
,return_value:{
type:String
}
},
methods: {
selectItem() {
if (!this.matches.length) {
return;
}
this.selectedItem = this.matches[this.selected];
this.visible = false;
if (this.should_reset) {
this.query = '';
this.selected = 0;
}
this.$emit(this.return_event, JSON.parse(JSON.stringify(this.selectedItem)));
}
}
фрагмент кода типа в шаблоне # style-header:
<type-ahead
v-bind:items="this.$parent.suppliers"
v-bind:return_event="'style_supplier'" <!-- links this t-a to the @ event -->
v-bind:title="'Suppliers'"
v-bind:filterby="'desc'"
v-bind:should_reset="true"
@style_supplier="updateSupplier" <!-- fires the correct update on the style-header -->
></type-ahead>