обновить объект данных дедушки из компонента grandchild в vue2 - PullRequest
0 голосов
/ 15 февраля 2019

Это мой первый проект в 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>
...