1
votes

I have a parent component in Vue.js which looks like this:

<template>
<ul class="list-group">
    <li class="list-group-item" v-for="item in items">
        <div class="row">
            <div class="col-md-6">
                {{ item.title }}
            </div>
            <div class="col-md-6 text-right">
                <a href="#" class="btn btn-primary btn-sm">
                    <span class="glyphicon glyphicon-pencil"></span>
                </a>
                <a href="#" class="btn btn-success btn-sm">
                    <span class="glyphicon glyphicon-link"></span>
                </a>
                <a href="#" class="btn btn-danger btn-sm">
                    <span class="glyphicon glyphicon-remove"></span>
                </a>
            </div>

            <div class="col-md-12">
                <preview></preview>
            </div>
        </div>
    </li>
</ul>
</template>

The script:

<script>

import Preview from './Preview.vue';

export default {

    data() {
        return {
            items: '',
            template: []
        }
    },

    created() {
        this.fetchItems();
        this.$on('preview-build', function (child) {
            console.log('new preview: ')
            console.log(child)
        })
    },

    components: {
        Preview
    },

    methods: {

        fetchItems: function () {
            var resource = this.$resource('api/preview');

            resource.get({}).then((response) => {
                this.items = response.body.item;
            }, (response) => {
                console.log('Error fetching tasks');
            }).bind(this);
        },

    }

 }
 </script>

The child component "preview" has a template-like structure, for example {{ item.title }} again. The preview is loaded correct but it's not rendered.

I really do not know if it is possible in Vue 2.0 but hopefully someone had the same problem and can help me here.

EDIT (thanks Patrick):

<template>
   <textarea rows="20" class="form-control">
     {{ template.content }}
   </textarea>
</template>

<script>
    export default {

        data() {
            return {
                template: [],
            }
        },

        created() {
            this.fetchTemplate();
        },

        methods: {

            fetchTemplate: function () {
                var resource = this.$resource('api/preview');

                resource.get({}).then((response) => {
                    this.template = response.body.template;
                }, (response) => {
                    console.log('Error fetching template');
                }).bind(this);
            },

        }

    }
</script>

This is the Preview.vue content which is similar to the Item.vue content. As a little explanation:

The template data comes from an database as predefined html content including the {{ item.title }} and some other placeholder. I want this to be rendered with the specific stuff coming from the item.

1
Please add the preview.vue file to your question.PatrickSteele

1 Answers

2
votes

In Vue.js, components can't directly access data from their parent. If you want preview to be able to render {{ item.title }}, you'll have to pass item down to it as a prop. So in preview.vue, declare it like this:

export default {
    ...
    props: ['item']
}

Then, in your parent component's template, you can v-bind that item prop to something from the parent's items array:

<li class="list-group-item" v-for="item in items">
    ...
    <preview v-bind:item="item"></preview>
    ...
</li>

Now your preview component has an item that it can render in its template as if it were part of the data object.