简体   繁体   中英

Compiling Vue.js component while rendering Laravel Blade partial view

I have a simple component in Vue.js which is used in a partial view - question.blade.php :

{{--HTML code--}}

<my-component type='question'>
    <div class="question">[Very long text content...]</div>
</my-component>

{{--more HTML code--}}

The idea behind the component is to create a "show more - show less" logic around the question content.

The component is compiled and renders just fine on page load. However, there are cases where I need to dynamically load a question via Ajax . For this, I make a simple jQuery Ajax call, retrieve the HTML of the question.blade.php and append it in the DOM. The problem is, the component is not compiled .

How do I make sure the component is always compiled when the partial view gets rendered, independently of whether it occurs on page load or via Ajax call?

Full component code:

{% verbatim %}
<template>
    <div>
        <div v-bind:class="cssClasses" v-html="content"></div>

        <div v-if="activateShowMore && !isShown" class="sml-button closed" v-on:click="toggleButton()">
            <span class="sml-ellipsis">...</span><span class="sml-label">{{$t('show_more')}}</span>
        </div>
        <div v-if="activateShowMore && isShown" class="sml-button open" v-on:click="toggleButton()">
            <span class="sml-label">{{$t('show_less')}}</span>
        </div>
    </div>
</template>

<style lang="sass" scoped>
    /*styles*/
</style>

<script type="text/babel">
    export default {
        props: ['content', 'type'],

        data() {
            return {
                activateShowMore: false,
                isShown: false,
                cssClasses: this.getCssClasses()
            }
        },

        locales: {
            en: {
                'show_more': 'show more',
                'show_less': 'show less'
            },
            de: {
                'show_more': 'mehr anzeigen',
                'show_less': 'weniger anzeigen'
            }
        },

        mounted() {
            this.checkShowMore();
        },

        watch: {
            isShown: function(shouldBeShown) {
                this.cssClasses = this.getCssClasses(shouldBeShown);
            }
        },

        methods: {
            checkShowMore: function() {
                let $element = $(this.$el);
                let visibleHeight = $element.outerHeight();
                let realHeight = $element.find('.text-area-read').first().outerHeight();
                let maxHeight = this.getMaxHeight();

                this.activateShowMore = (visibleHeight === maxHeight) && (visibleHeight < realHeight);
            },
            getMaxHeight: function() {
                switch (this.type) {
                    case 'question':
                        return 105;
                    case 'answer':
                        return 64;
                }
            },
            toggleButton: function() {
                this.isShown = !this.isShown;
            },
            getCssClasses: function(shouldBeShown) {
                if (undefined === shouldBeShown || !shouldBeShown) {
                    return 'sml-container' + ' sml-' + this.type + ' sml-max-height';
                }

                return 'sml-container' + ' sml-' + this.type;
            }
        }
    }
</script>

I don't think this is the best way but it should do the trick. But I had to deal with vue and jquery communication before.

What I did is created a hidden input and changed the value with jquery after the ajax call finished and then triggered the change event with jquery. Then you already listening to the event inside vue and you will know you need to update the content. This should get you going with some modification to your vue component and should be able to update. If you need to send the content to vue you might need to send it in the input hidden value. I did a quick demo code to explain what I mean. Here's the link .

var app = new Vue({
          el: '#app',
          data(){
            return{
              content: 'hi there',
            }
          },
          methods: {
            onChangeHandler: function(e){
              this.content = e.target.value
            }
          },
       });

       $('#me').on('click',function(){
         $('#update').val('Good Day!')
         $('#update').trigger("click")
      });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM