如何在vue.js 2.0中公开组件上的属性

时间:2016-12-15 05:25:30

标签: vue.js

我正在考虑如何在vue.js组件上实现验证。

最初的想法是组件验证并返回错误代码,例如:“require”,“min”,“max”等。另一个组件将根据此错误代码显示全文消息。

因为错误消息可能并不总是显示在组件的模板中。我需要两个独立的组件。

伪代码是这样的。

<div>
<mycomponent ref="salary" errcode="ErrorCode"></mycomponent>
</div>
.....
<div>
<errormessage watchcomponent="salary" message="salaryErrorMessages"></errormessage>
</div>

salaryErrorMessages是代码和消息的哈希值。例如: {“require”:“请输入工资”, “min”:“最低工资值为10000”}

Vue对组件有ref属性。我不知道是否可以使用ref引用属性中的组件。

我考虑的其他解决方案:

  1. 在页面模型中添加错误对象,并传递给using:sync binding。可以监视同一个对象。 这需要在模型中声明错误消息。
  2. 如果我考虑要求页面在发回之前还需要知道是否有错误。可能需要全局错误对象。

    1. 使用事件总线或Vuex。 这似乎是官方解决方案,但我不知道。
    2. 当一个页面有多个实例时,它们将触发相同的事件。所有实例都将监视同一事件。

2 个答案:

答案 0 :(得分:1)

你绝对应该使用Vuex。它不仅可以解决您的问题,还可以为您的项目提供巨大的可扩展性。

答案 1 :(得分:0)

你正在倒退。 Vue是关于将数据从父级传递给子级,而不是将子属性公开给父组件。

  

在页面模型中添加错误对象,并传递给using:sync binding。可以监视同一个对象。这需要在模型中声明错误消息。

sync已从Vue v2中消失,但这个想法基本上是正确的:父组件包含一个对象,子组件作为props传递它的块,父对象在父进程中自动更新在孩子身上发生了变化。它不一定是根组件。

  

使用事件总线或Vuex。这似乎是官方解决方案,但我不知道。

如果你的应用程序需要管理很多与状态相关的恶作剧,那么Vuex几乎总是正确的解决方案。

  

当一个页面有多个实例时,它们将触发相同的事件。所有实例都将监视同一事件。

Vue会经常使用data must be a function的警告污染您的控制台。这就是为什么!

这是一个删节版本,我最近为熟人做了一件非常可耻的hackjob 为熟人做的:

在我的辩护中,将内容放入__proto__是一种非常快速的方法,可以使它们不可枚举。

Vue.component('error', {
  template: '#error',
  props: ['condition', 'errorMessage']
})

Vue.component('comp', {
  template: '#comp',
  props: ['errorMessage', 'model'],
})

Vue.component('app', {
  template: '#app',
  data() {
    return {
      models: {
        nameForm: {
          firstName: '',
          lastName: '',
          __proto__: {
            validator: function(value) {
              return _(value).every(x => x.length > 2)
            }
          }
        },
        otherForm: {
          notVeryInterestingField: 'There are words here',
          veryImportantField: 0,
          __proto__: {
            validator: function(value) {
              return value.veryImportantField > 20
            }
          }
        },
        __proto__: {
          validator: function(value) {
            return _(value).every(x => x.validator(x))
          }
        }
      }
    }
  }
})

const vm = new Vue({
  el: '#root'
})
.error {
  background: orange
}
.alright {
  background: mediumaquamarine
}
 section > div, pre {
  padding: 6px;
}
section {
  flex: 1;
}
#root {
  display: flex;
  flex-direction: column;
}
<script src="https://unpkg.com/vue@2.1.6/dist/vue"></script>
<script src="https://unpkg.com/lodash"></script>

<template id="comp">
  <div :class="[model.validator(model) ? 'alright' : 'error']" style="display: flex; border-bottom: 2px solid rgba(0,0,0,0.4)">
    <section>
      <div v-for="(field, fieldName) in model">
        {{_.startCase(fieldName)}}:
        <input v-model="model[fieldName]">
        <br>
      </div>
      <error :condition="!model.validator(model)" :error-message="errorMessage"></error>
    </section>
    <section>
      <pre>props: {{$options.propsData}}</pre>
    </section>
  </div>

</template>

<template id="error">
  <div v-if="condition">
    {{ errorMessage || 'Oh no! An error!' }}
  </div>
</template>

<template id="app">
  <div :class="[models.validator(models) ? 'alright' : 'error']">
    <comp :model="model" error-message="Mistakes were made." v-for="model in models"></comp>
    <pre>data: {{$data}}</pre>
  </div>
</template>

<div id="root">
  <app></app>
</div>