前提・実現したいこと
Vue.jsのX-templateのソースコードから、単一ファイルコンポーネントのソースコードに書き換えたいです。
発生している問題・エラーメッセージ
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
元のx-templateコード(このソースを書き換えたい!)
<template> <div id="vue"> <h2>These are some examples of how to do two-way bindings</h2> <child v-model="stuff" /> {{ stuff }} <hr> <selector v-model="selected" /> --> {{ selected }} <hr> <multi-sync :first_name.sync="user.first_name" :second_name.sync="user.second_name" :third_name.sync="user.third_name" :forth_name.sync="user.forth_name" :fifth_name.sync="user.fifth_name"> </muti-sync> {{ user }} <hr> <multi-field v-model="user2" /> {{ user2 }} </multi-sync> </div> </template> <script> export default { components: { child: { props: ['value'], template: '<input v-model="interface">', computed: { interface: { get () { return this.value }, set (val) { this.$emit('input', val) } } } }, selector: { props: { value: { type: Array, default: [] // value for multi-select must be array, not undefined } }, template: '<select v-model="interface" multiple><option>A</option><option>B</option><option>C</option></select>', computed: { interface: { get () { return this.value }, set (val) { this.$emit('input', val) } } } }, //! ここが重要! multiSync: { props: ['', '', '', '', ''], ????template: ` <div> <input v-model="sync_first_name"> <input v-model="sync_second_name"> <input v-model="sync_third_name"> <input v-model="sync_forth_name"> <input v-model="sync_fifth_name"> </div>`, computed: { sync_first_name: { get () { return this.first_name }, set (val) { this.$emit('update:first_name', val) } }, sync_second_name: { get () { return this.second_name }, set (val) { this.$emit('update:second_name', val) } }, sync_third_name: { get () { return this.third_name }, set (val) { this.$emit('update:third_name', val) } }, sync_forth_name: { get () { return this.forth_name }, set (val) { this.$emit('update:forth_name', val) } }, sync_fifth_name: { get () { return this.fifth_name }, set (val) { this.$emit('update:fifth_name', val) } } } }, multiField: { props: { value: { type: Object, default: { first_name: '', second_name: '', third_name: '', forth_name: '', fifth_name: '' } } }, ????template: ` <div> <input v-model="buffer.first_name" @input="$emit('input', buffer)"> <input v-model="buffer.second_name" @input="$emit('input', buffer)"> <input v-model="buffer.third_name" @input="$emit('input', buffer)"> <input v-model="buffer.forth_name" @input="$emit('input', buffer)"> <input v-model="buffer.fifth_name" @input="$emit('input', buffer)"> </div>`, data () { return { buffer: Object.assign({}, this.value) } }, watch: { value: { handler () { this.buffer = Object.assign({}, this.value) }, deep: true } } } }, data () { return { stuff: '', selected: [], user: { }, user2: { } } } } </script> <style> </style>
試したこと
【Vue.js】コンポーネントのtemplateの書き方まとめこちらの記事を参考に、
以下のソースコードに変換してみましたが、逆にエラーが増加して解決に至りませんでした。
<template> <div id="vue"> <h2>These are some examples of how to do two-way bindings</h2> <child v-model="stuff" /> {{ stuff }} <hr> <selector v-model="selected" /> {{ selected }} <hr> <div> <input v-model="sync_first_name"> <input v-model="sync_second_name"> <input v-model="sync_third_name"> <input v-model="sync_forth_name"> <input v-model="sync_fifth_name"> </div> <multi-sync :first_name.sync="user.first_name" :second_name.sync="user.second_name" :third_name.sync="user.third_name" :forth_name.sync="user.forth_name" :fifth_name.sync="user.fifth_name"> </muti-sync> {{ user }} <hr> <div> <input v-model="buffer.first_name" @input="$emit('input', buffer)"> <input v-model="buffer.second_name" @input="$emit('input', buffer)"> <input v-model="buffer.third_name" @input="$emit('input', buffer)"> <input v-model="buffer.forth_name" @input="$emit('input', buffer)"> <input v-model="buffer.fifth_name" @input="$emit('input', buffer)"> </div> <multi-field v-model="user2" /> {{ user2 }} </multi-sync> </div> </template> <script> export default { components: { child: { props: ['value'], template: '<input v-model="interface">', computed: { interface: { get () { return this.value }, set (val) { this.$emit('input', val) } } } }, selector: { props: { value: { type: Array, default: [] // value for multi-select must be array, not undefined } }, template: '<select v-model="interface" multiple><option>A</option><option>B</option><option>C</option></select>', computed: { interface: { get () { return this.value }, set (val) { this.$emit('input', val) } } } }, //! ここが重要! multiSync: { props: ['', '', '', '', ''], computed: { sync_first_name: { get () { return this.first_name }, set (val) { this.$emit('update:first_name', val) } }, sync_second_name: { get () { return this.second_name }, set (val) { this.$emit('update:second_name', val) } }, sync_third_name: { get () { return this.third_name }, set (val) { this.$emit('update:third_name', val) } }, sync_forth_name: { get () { return this.forth_name }, set (val) { this.$emit('update:forth_name', val) } }, sync_fifth_name: { get () { return this.fifth_name }, set (val) { this.$emit('update:fifth_name', val) } } } }, multiField: { props: { value: { type: Object, default: { first_name: '', second_name: '', third_name: '', forth_name: '', fifth_name: '' } } }, data () { return { buffer: Object.assign({}, this.value) } }, watch: { value: { handler () { this.buffer = Object.assign({}, this.value) }, deep: true } } } }, data () { return { stuff: '', selected: [], user: { }, user2: { } } } } </script> <style> </style>
補足情報(FW/ツールのバージョンなど)
元のx-templateコード がすでにまともに動作しなさそうな気がしますが、この段階では動いていましたか?
ご回答いただきありがとうございます!
codepenから抜粋したものなので、動作いたします。
こちらが元のソースコードで、https://jsfiddle.net/Herteby/qt0aqa9g/
こちらが上記ソースコードでございます! https://codepen.io/torish/pen/XWJOzWg?editors=1010
上返信でリンクされている Codepen のスクリプトは x-template を利用したものではありません。引用されている Qiita の記事の括りで言うなら、1.文字列 の方法ではないでしょうか。
質問で提示された最初のスクリプトは<template> から始まっており、 単一ファイルコンポーネントとして処理しないと動作しないはずで、やはり x-template を利用したものではありません。そして codepen 上のコードとは異なる物に見えます。
ちょっと質問の意図やコメント返信で提示いただいたソースとの関連等、色々読み取れず何を回答していいのかわかりません。このあたり整理して質問を編集いただくと、回答が付きやすいと思います。
失礼いたしました????
いま見返しますと、元のコードは「x-template」を利用したものではなく、ご指摘頂きました「文字列」でした!
また、該当ソースコードも私が手を加えたものでまったく別物でございました。。
すぐに訂正いたします❗️
あなたの回答
tips
プレビュー