将自定义发出的事件作为道具传递给VueJs中新创建的组件

时间:2018-06-29 18:47:31

标签: javascript events vue.js

我的应用包含:

一个名为

的组件
<consl :output="output" @submit-to-vue><consl>

其中包含一个输入,当按下Enter键时,该输入将调用commit()方法。

<div> 
    <output v-html="output"></output>
    <div id="input-line" class="input-line">
        <div class="prompt">{{ prompt }}</div>
        <div>
        <input class="cmdline" autofocus 
            v-model.trim="command" 
            @keyup.enter="submit"  
            :readonly="submited" />
        </div>
    </div>

然后方法submit()向父方法@submit-to-vue发出事件submitv(),该事件创建相同组件的实例并将其添加到DOM。

//........
methods: {
    submit: function () {
        this.$emit('submit-to-vue')
        this.submited = true
    }
},

//......
methods: {
    submitv: function () {
        var ComponentClass = Vue.extend(consl)
        var instance = new ComponentClass({
            propsData: { output: this.output }
        })
        instance.$mount() // pass nothing
        this.$refs.container.appendChild(instance.$el)

我想完成什么?

我想创建一个新的consl组件,并在每次提交旧组件时将其添加到DOM中。 (我希望我的应用模仿终端)

问题

提交后,新创建的组件不包含@submit-to-vue事件监听器,这使其无法调用submitv()方法。

问题

  • 我该如何解决这个问题?
  • 这是在VueJs中做事的正确方法,还是有一种更优雅的方法?

1 个答案:

答案 0 :(得分:0)

在父组件中,声明一个数据属性= childs,它将包括所有已创建的子项。

因此,一旦父组件收到event = submit-to-vue,然后将一个新的子代添加到this.childs

最后使用v-for渲染这些子组件。

诀窍:始终考虑以数据为主导的方式,不要直接操纵dom。

下面是一个简单的演示

Vue.config.productionTip = false

Vue.component('child', {

  template: `
  <div> 
    <div>Label:<span>{{output}}</span></div>
    <div>Value:<span>{{command}}</span></div>
    <div id="input-line" class="input-line">
        <div class="prompt">{{ prompt }}</div>
        <div>
        <input class="cmdline" autofocus 
            v-model.trim="command" 
            @keyup.enter="submit"  
            :readonly="submited" />
        </div>
    </div>
  </div>`,
  props: ['output'],
  data() {
    return {
      submited: false,
      command: ''
    }
  },
  computed: {
    prompt: function () {
      return this.submited ? 'Already submitted, input is ready-only now' : ''
    }
  },
  methods: {
    submit: function () {
      this.$emit('submit-to-vue')
      this.submited = true
    }
  }
})

app = new Vue({
  el: "#app",
  data: {
    childs: [{'output':'default:'}]
  },
  methods: {
    addChild: function () {
      this.childs.push({'output': this.childs.length})
    }
  }
})
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="app">
  <div>
    <ul>
      <li v-for="(child, index) in childs" :key="index">
        <child :output="child.output" @submit-to-vue="addChild()"></child>
      </li>
    </ul>
  </div>
</div>