"属性未在实例上定义"即使它是定义的

时间:2017-11-01 17:05:16

标签: javascript vue.js

我想通过分支vue-play为新组件添加一些自己的方案。

我在更复杂的vue-select案例中遇到问题,尤其是双向价值同步。

进入这种情况最终会发出警告:

  

vue.esm.js:571 [Vue警告]:财产或方法" syncedVal"不是   在实例上定义但在渲染期间引用。

并且预先选择了下拉列表中的任何选项。尽管在组件的道具中定义了syncedVal,但我仍然无法理解为什么我会继续收到此警告。 我已将两个文件添加到vue-play/play

VSelect.vue

<template>
    <v-select v-model="selected" :options="options"></v-select>
</template>

<script>
    import Vue from 'vue'
    import vSelect from 'vue-select'

    Vue.component('v-select', vSelect);

    export default {
        props: {
            options: {
                default: function() { return ['one', 'two'] },
                type: Array
            },
            onchangeCallback: {
                default: () => () => null
            },
            // doesn't seem to work:
            syncedVal: {
                default: 'one',
                type: String
            }
        },
        data() {
            return {
                selected: null
            }
        }
    }
</script>

VSelect.play.js

import {play} from '../src/play'
import VSelect from './VSelect.vue'

play(VSelect)
    .name('VSelect')
    .displayName('VSelect')
    .add('default', '<v-select />')
    .add('multiple', '<v-select multiple />')
    .add('custom options', `<v-select :options="['custom1','custom2']" />`)
    .add('custom options with labels', `<v-select :options='[{value: "CA", label: "Canada"}, {value: "UK", label: "United Kingdom"}]' />`)
    .add('2-way value sync', `<v-select :value.sync="syncedVal" />`) // doesn't seem to work

1 个答案:

答案 0 :(得分:3)

请注意v-select中的VSelect.play.js组件为VSelect.vue

所以有一些错误:

  1. .add('multiple', '<v-select multiple />')
    • VSelect.vue没有多个道具,因此此倍数不会按预期工作
    • FIX:为您的组件添加道具,并将其绑定到v-select
  2. .add('2-way value sync', )
    • 你在组件的道具中定义syncedVal,但是你在其他组件(vue-play&#39; s组件)上使用它,它们有不同的范围!
    • FIX:使用vue-play演示此功能,您需要编写完整的组件,以便绑定数据(请参阅下面的示例代码)
    • VSelect.vue未实施同步(https://vuejs.org/v2/guide/components.html#sync-Modifier),因此此处不会发生任何事情
  3. 我从你的组件中做了一个例子并玩,我希望这会对你有所帮助:)。

      

    这是我如何修复它们:

    SelectFramework.vue

    <template>
      <v-select
        v-model="selected"
        :options="options"
        :multiple="multiple">
      </v-select>
    </template>
    
    <script>
    export default {
      name: "SelectFramework",
      props: {
        options: {
          default: () => ["Vue.js", "React", "Angular"],
          type: Array
        },
        value: String, // to support v-model
        foo: String, // to support :foo.sync
        multiple: false // to support multiple select
      },
      data() {
        return {
          selected: this.value,
        };
      },
      watch: {
        selected () {
          this.$emit('input', this.selected) // update v-model
          this.$emit('update:foo', this.selected) // update foo.sync
        },
        value () {
          this.selected = this.value // update from v-model
        },
        foo () {
          this.selected = this.foo // update from foo.sync
        }
      }
    };
    </script>
    

    play/index.js

    import { play } from 'vue-play'
    import Vue from 'vue'
    import vSelect from 'vue-select'
    Vue.component('v-select', vSelect)
    
    
    import SelectFramework from '../src/SelectFramework.vue'
    
    play(SelectFramework)
      .name('SelectFramework')
      .displayName('Select Framework')
      .add('default', '<select-framework />')
      .add('multiple', '<select-framework multiple />')
      .add('custom options', `<select-framework :options="['custom1','custom2']" />`)
      .add('custom options with labels', `<select-framework :options='[{value: "CA", label: "Canada"}, {value: "UK", label: "United Kingdom"}]' />`)
      // full component to demo v-model and :foo.sync
      .add('v-model', {
        data() {
          return {
            selected: null,
            syncedVal: null
          }
        },
        template: `
          <div>
            <p>selected: {{selected}} </p>
            <p>syncedVal: {{syncedVal}} </p>
            <select-framework
              v-model="selected"
              :foo.sync="syncedVal">
            </select-framework>
            <p>
              <button @click="selected = 'Vue.js'">Set selected to Vue.js</button>
              <button @click="syncedVal = 'React'">Set syncedVal to React</button>
            </p>
          </div>
        `
      })
      // .add('2-way value sync', `<select-framework :value.sync="syncedVal" />`) // doesn't seem to work