1

但是,我想使用条件字段动态创建表单。表单的定义在一个对象 Q 中。下面的例子是一个 Vue 组件,使用 bootstrap-vue。

<template>
    <div>
        <div v-for="q of Q">
            <br/>
            <template v-if="q.type == 'input'">
                {{ q.question }}
                <em v-if="q.comment"><br />{{ q.comment }}</em>
                <b-form-input v-model="q.value" :type="q.subtype" :placeholder="q.placeholder"></b-form-input>
                Value: {{ q.value }}
            </template>

            <template v-if="q.type == 'radio'">
                {{ q.question }}
                <em v-if="q.comment"><br />{{ q.comment }}</em>
                <b-form-group>
                    <b-form-radio-group buttons
                                        stacked
                                        v-model="q.value"
                                        :options="q.options"/>
                </b-form-group>

                Value: {{ q.value }}
            </template>

        </div>
    </div>
</template>

<script>
    export default {
        name: 'Questionnaire',
        data() {
            return {
                locale: 'en',
                Q: [
                    {
                        name: 'age',
                        value: null,
                        question: 'How old are you?',
                        placeholder: 'Your age...',
                        comment: 'years since you were born',
                        type: 'input',
                        subtype: 'number',
                        range: [18, 99],
                    },
                    {
                        name: 'cq',
                        value: null,
                        question: 'Conditional Question?',
                        type: 'radio',
                        options: [
                            {text: 'Yes', value: '0'},
                            {text: 'No', value: '1'},
                        ],
                        if: [{object: 'age', largerthan: 30}],
                    },
                ]
            };
        },
        methods: {
            onChange: function(){
                alert('test');
            },
        },
    }
</script>

我只想在年龄 > 30 时显示“条件问题”。

  • 在对象 Q 中,我无法访问this.Q(因为它还不存在)。
  • v-on:change="onChange" 可以工作,但这违背了 Vue 的全部要点

我不受对象的这种结构的约束,但是它将使用 AJAX 获得...

问题:有没有办法观看this.Q[0].value?或仅当第一个问题具有一定价值时才使第二个问题可用的其他方法?

4

2 回答 2

2

正如@Stephan-v 所说,我将对象更改为键:值对象,而不是数组。从@Radovan-Šurlák 的帖子中可以看出,不需要观察者。请注意,计算对象只能在“beforeCreate”和方法中创建,变量尚未初始化。将变量从 beforeCreate 传递给对象似乎相当困难。

因此,使用@Radovan-Šurlák 作为基础,并稍微改进它会导致:

<template>
    <div>
        <div v-for="(q, name) of Q" v-if="doShow( name )">
            <br/>
            <template v-if="q.type == 'input'">
                <b>{{ q.question }}</b>
                <em v-if="q.comment"><br/>{{ q.comment }}</em>
                <b-form-input v-model="q.value" :type="q.subtype" :placeholder="q.placeholder"></b-form-input>
            </template>

            <template v-if="q.type == 'radio'">
                <b>{{ q.question }}</b>
                <em v-if="q.comment"><br/>{{ q.comment }}</em>
                <b-form-group>
                    <b-form-radio-group buttons
                                        stacked
                                        v-model="q.value"
                                        :options="q.options"/>
                </b-form-group>
            </template>

        </div>
    </div>
</template>

<script>
    export default {
        name: 'Questionnaire',
        data() {
            return {
                locale: 'en',
                Q: {
                    age: {
                        value: null,
                        question: 'How old are you?',
                        placeholder: 'Your age...',
                        comment: 'years since you were born',
                        type: 'input',
                        subtype: 'number',
                        range: [18, 99],
                    },
                    cq: {
                        value: null,
                        question: 'Conditional Question?',
                        type: 'radio',
                        options: [
                            {text: 'Yes', value: '0'},
                            {text: 'No', value: '1'},
                        ],
                        if: [{object: 'age', largerthan: 30, smallerthan: 35, equals: 31, notequal: 32}],
                    },
                },
            };
        },
        methods: {
            doShow: function( field ) {
                for( var obj in this.Q[ field ].if )
                {
                    var ifObj = this.Q[ field ].if[ obj ];
                    if( ifObj.equals !== undefined && this.Q[ ifObj.object ].value != ifObj.equals )
                        return false;
                    if( ifObj.notequal !== undefined && this.Q[ ifObj.object ].value == ifObj.notequal )
                        return false;
                    if( ifObj.largerthan !== undefined && this.Q[ ifObj.object ].value <= ifObj.largerthan )
                        return false;
                    if( ifObj.smallerthan !== undefined && this.Q[ ifObj.object ].value >= ifObj.smallerthan )
                        return false;
                }
                return true;
            },
            submit: function () {
                console.log('Submit form, send back data via Axios')
            },
        },
        mounted() {
            // Axios call
        }
    }
</script>
于 2018-02-16T12:32:06.230 回答
2

我通过在模板中的第二个 div 上使用“v-if”指令来创建效果。

然后我通过空数组初始化了“Q”数组,并在“created()”生命周期钩子中通过 setTimeout 模拟了 AJAX 请求。

<template>
  <div>
    <div v-if="!(q.if) || Q[0].value > q.if[0].largerthan" v-for="q of Q">
        <br/>
        <template v-if="q.type == 'input'">
            {{ q.question }}
            <em v-if="q.comment"><br />{{ q.comment }}</em>
            <b-form-input v-model="q.value" :type="q.subtype" :placeholder="q.placeholder"></b-form-input>
            Value: {{ q.value }}
        </template>

        <template v-if="q.type == 'radio'">
            {{ q.question }}
            <em v-if="q.comment"><br />{{ q.comment }}</em>
            <b-form-group>
                <b-form-radio-group buttons
                                    stacked
                                    v-model="q.value"
                                    :options="q.options"/>
            </b-form-group>

            Value: {{ q.value }}
        </template>

    </div>
  </div>
</template>

<script>
  export default {
    name: 'Questionnaire',
    data() {
        return {
            locale: 'en',
            Q: [],
        };
    },
    created() {
      setTimeout( _ => this.Q = [
                {
                    name: 'age',
                    value: null,
                    question: 'How old are you?',
                    placeholder: 'Your age...',
                    comment: 'years since you were born',
                    type: 'input',
                    subtype: 'number',
                    range: [18, 99],
                },
                {
                    name: 'cq',
                    value: null,
                    question: 'Conditional Question?',
                    type: 'radio',
                    options: [
                        {text: 'Yes', value: '0'},
                        {text: 'No', value: '1'},
                    ],
                    if: [{object: 'age', largerthan: 30}],
                },
                {
                    name: 'age',
                    value: null,
                    question: 'How old are you?',
                    placeholder: 'Your age...',
                    comment: 'years since you were born',
                    type: 'input',
                    subtype: 'number',
                    range: [18, 99],
                },
         ], 500)
    },
}

于 2018-02-16T13:42:44.673 回答