web-dev-qa-db-ja.com

プロパティをVueコンポーネントに動的に追加する

表示するコンポーネントのタイプを駆動するデータベースからデータをロードしています

AJAX呼び出しがオフになり、データが返されます(これは必要に応じて再構築できます)

{
  component_type: 'list-item',
  props: {
    name: 'test',
    value: 'some value'
  }
}

これは私の親オブジェクトでアクセス可能ですcomponentという変数

親オブジェクトのテンプレート内に、次のものがあります

<component :is="component.component_type" ></component>

これは正常に機能し、期待どおりにコンポーネントをロードします。

次に、データオブジェクトのプロパティもこのタグに追加します

<component :is="component.component_type" {{ component.props }} ></component>

これは機能せず、{{を含むタグの書き込みを拒否します。よくわかりませんが、これはVueではなくブラウザによってスローされたエラーだと思います。

参考までに、出力を実際に次のようにしたいと思います。

<component :is="component.component_type" name='test' value='some value' ></component>

これらのプロパティを渡すにはどうすればよいですか?理想的には、データベースで簡単に変更でき、それに応じてUIが変更されるように、これらを親のデータ/小道具に関連付けて表示したいと思います。

最悪の場合、すべてをサーバー側で生成しますが、現在実行しようとしているように、ajaxを介して生成したいと思います。

7
Jon Taylor

これに続いて thread 、これを行うための2つのオプションがあります。

1つは、それ自体がオブジェクトである単一の小道具を渡し、子コンポーネントで使用できる関連するすべてのキー値を渡すことです。次のようになります。

<component :is="component. component_type"
        :options="component.props"
</component>

言及されている他の解決策は、オブジェクトを渡すと、そのオブジェクトのキーである属性を対応する値に設定するディレクティブを持つことです。これは、作業で確認できます ここ

Vue.directive('props', {
        priority: 3000,
    bind() {

        // set the last component child as the current
        let comp = this.vm.$children[this.vm.$children.length - 1];
        let values = null;
        if(this._scope && this._scope.$eval) {
            values = this._scope.$eval(this.expression);
        } else {
            values = this.vm.$eval(this.expression);
        }
        if(typeof values !== 'object' || values instanceof Array) {
            values = { data: values };
        }

        // apply properties to component data
        for(let key in values) {
            if(values.hasOwnProperty(key)) {
                let hkey = this.hyphenate(key);
                let val = values[key];
                if(typeof val === 'string') {
                    comp.$options.el.setAttribute(hkey, values[key]);
                } else {
                    comp.$options.el.setAttribute(':' + hkey, values[key]);
                }
            }
        }

                console.log(comp.$options.el.outerHTML);
        comp._initState();
    },

    /*
     * Hyphenate a camelCase string.
     */
    hyphenate(str) {
        let hyphenateRE = /([a-z\d])([A-Z])/g;
        return str.replace(hyphenateRE, '$1-$2').toLowerCase();
    }
});

次のように使用します。

<div class="app">
    <component is="component.component_type" v-props="component.props"></component>
</div>
4
Saurabh

Vue 2を使用してこれを行う方法を誰かが疑問に思っている場合は、オブジェクトをv-bindに渡すことができます。

<template>
    <component :is="componentType" v-bind="props"></component>
</template>

<script>
    export default {
        data() {
            return {
                componentType: 'my-component',
                props: {
                    foo: 'foofoo',
                    bar: 'barbar'
                }
            }
        }
    }
</script>
8
Mr_Chimp

私の知る限り、Vue.jsテンプレートには残りの小道具(スプレッド小道具)の構文はありません。

考えられる解決策はレンダリング関数です。レンダリング関数を使用する場合はJavaScriptをフルに活用できるため、次のようなことができます。

render (h) {
  return h('foo', {
    props: {
      ...yourData
    }
  })
}

ここで簡単な例を作成しました: http://codepen.io/CodinCat/pen/bgoVrw?editors=101

コンポーネントタイプ(fooなど)と小道具はどちらも動的にすることができます(ただし、propの可能なすべてのフィールド(abc)子コンポーネント内)

別の解決策はJSXです。

JSX babelプラグインを使用します: https://github.com/vuejs/babel-plugin-transform-vue-jsx

次に、spreadprops構文を使用できます。

return <foo {...{yourData}}></foo>
3
CodinCat