【问题标题】:Vuejs copy dynamic components methodsVuejs 复制动态组件方法
【发布时间】:2020-06-17 11:05:54
【问题描述】:

我正在尝试对组件库进行可视化表示。我正在使用动态<component>s 来渲染每个组件。但是,当我使用其插槽填充组件时,由于缺少父方法,我遇到了问题。

我希望组件可用(演示),因此我需要补偿this.$parent 不工作。

<template>
  <component v-bind:is="'s-' + comp.name" v-bind="props" ref="comp">  <!-- this is the corrent parent-->
    <div v-if="comp.slots">
      <div
        v-for="(slot, i) in comp.slots"
        v-bind:key="i"
        v-bind:slot="slot.name"
      >
        <div v-if="slot.type == 'component'">                         <!-- childs parent -->
          <de-mo v-bind:comp="slot" />                                <!-- this is the child calling a method on the parent -->
        </div>
        <div v-html="slot.value" v-else></div>
      </div>
    </div>
  </component>
</template>

<script>
export default {
  name: 'deMo',
  computed: {
    props() {
      if (this.comp.props) {
        return this.comp.props.reduce((a, r) => {
          a[r.name] = r.value
          return a
        }, {})
      }
    }
  },
  props: {
    comp: {
      type: Object,
      required: true
    }
  },
  methods: this.$ref.comp.methods,                               //<-- this is an error
  mounted(){
    console.log(this.$ref.comp.methods)
  }
},

</script>

<style></style>

1) 有没有办法通过ref attr 将父级的方法复制到这个“演示”组件中 2) 或者,有没有更好的方法来产生相同的结果?

谢谢

【问题讨论】:

  • 组件库应该使用 Inject 提供,这是推荐的方式,而不是直接的树父子关系,如果子元素在中间元素内则不起作用

标签: vue.js vuejs2 vue-component nuxt.js


【解决方案1】:

您可以尝试在 beforeCreate 生命周期中传播父方法,因为此时您的父级将被创建并且您的组件将注册其所有方法,

beforeCreate() {
    this.$options.methods = { ...this.$parent.$options.methods };
  },

但是您不能访问其中的任何引用,因为引用仅在组件挂载后注册。

注意:任何库都应该使用提供和注入来与其组件通信,而不是直接引用父组件。

【讨论】:

    【解决方案2】:

    您可以使用事件总线在彼此不直接相关的组件之间进行通信。此外,这是推荐在 Vue 中从孩子到父母的沟通方式。

    bus.js

    import Vue from 'vue'
    export default new Vue()
    

    demo.vue // 想要调用父级方法的子组件

    import Bus from './bus.js'
    export default {
     mounted () {
      // [1] child component will emit an event in the bus when it want to call a method of parent 
      Bus.$emit('invoke-parent-fn', 'param')
     }
    }
    

    parent.vue // 要动态渲染其他组件的父组件

    import Bus from './bus.js'
    export default {
     methods: {
      fn (param) {
       console.log('// do something ' + param)
      }
     },
     mounted () {
      // [2] parent will be listening to the bus event, when child will emit an event, the handler passed in to the listener will be invoked
      // [3] invoke the required method in the handler
      Bus.$on('invoke-parent-fn', param => this.fn(param))
     }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-05-30
      • 2017-11-20
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 2019-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多