Излучение с компонентом: есть - PullRequest
0 голосов
/ 07 ноября 2018

Я создаю приложение для панели инструментов, где пользователи смогут выбирать виджеты, которые появляются в определенных позициях. Я делаю это, используя

<component :is="name-of-component">

Все работает хорошо, но я хочу, чтобы пользователь мог редактировать компонент и отправлять изменения родительскому элементу. При редактировании, скажем, например, 1 компонент отображает приветственное сообщение, которое пользователь может изменить.

Прямо сейчас у меня есть следующее

Dashboard.vue

<template>
  <component :is="name-of-component"></component>
</template>
<script>
  data () {
    return {
      name-of-component: 'selected-component-name'
    }
  }
</script>

В сценарии есть вычисленные, смонтированные и т. Д., Которые, я думаю, не имеют отношения к вопросу.

Так как я использую компонент: я нахожу сложным передавать реквизиты и генерировать изменения. В моем магазине у меня есть 2 реквизита для компонента (заголовок и субтитры) в массиве. Я могу жестко кодировать: props = "welcomeMessage", но я не хочу жестко кодировать, так как я использую: is, и позиция виджетов может измениться.

Эмит также вызывает у меня проблему. Я могу, конечно, излучать путем жесткого кодирования вызова компонента, но поскольку я использую: это не сработает для меня.

Вот что работает, но мне нужно сделать его динамическим, как любой компонент: хочу ли он содержать какой-либо виджет. Есть идеи?

<component 
  :is="welcomeMessage" 
  :props="dashboard.welcomeMessage" 
  @update-welcomeMessage="welcomeMessage(e)">
</component>

OR

<component 
  :is="busStops" 
  :props="dashboard.myBusStop" 
  @update-busStop="busStop(e)">
</component>

Мне бы хотелось иметь компоненты, чтобы я мог разобраться с различными проблемами, и чтобы каждый из них был больше похож на этот, где «имя компонента» может использоваться для заполнения: is,: props и @update:

<component 
  :is="name-of-component" 
  :props="dashboard.name-of-component" 
  @update-name-of-component="name-of-component(e)">
</component>

1 Ответ

0 голосов
/ 07 ноября 2018

Вы можете использовать возможности v-bind и v-on и использовать вычисляемые свойства, как вы уже это делаете. Я объясню себе:

<some-component @some-event="doThis" foo="bar"></some-component>

- это то же самое, что и запись:

<some-component v-bind="{foo: 'bar'}" v-on="{'some-event': doThis}"></some-component>

Это означает, что вы можете написать вычисленные свойства, чтобы вычислить, какие слушатели и атрибуты вы хотите использовать для вашего динамического компонента.

Я написал полный пример на jsFiddle, если вы хотите: https://jsfiddle.net/tsc2pmrx/

Шаблон:

<div id="app">
  <component :is="componentToUse" v-on="listeners" v-bind="attributes"></component>
</div>

JS:

Vue.component('greeting', {
    props: ['name'],
  template: '<h1>Welcome {{ name }} !</h1>',
  mounted () {
    setTimeout(() => {
        this.$emit('some-event')
    }, 2000)
  }
});

Vue.component('other-component', {
    template: '<h1>Welcome to Other Component</h1>'
})

// create a new Vue instance and mount it to our div element above with the id of app
var vm = new Vue({
  el: '#app',
  data: {
    componentToUse: 'greeting'
  },
  methods: {
    handleOtherComponentEvent () {
        console.log('Hello World from other component listener')
    },
    handleGreetingComponentEvent () {
        console.log('Hello World from greeting component event listener')
    }
  },
  computed: {
    listeners () {
        if (this.componentToUse === 'greeting') {
        return {
            'some-event': this.handleOtherComponentEvent
        }
      } else if (this.componentToUse === 'other-component') {
        return {
            'some-greeting-event': this.handleGreetingComponentEvent
        }
      }

      return {}
    },
    attributes () {
        if (this.componentToUse === 'greeting') {
        return {
            'name': 'Hammerbot'
        }
      }

      return {}
    }
  }
});
...