2

I need to show components that are passed through props and output them through v-html. I found a render solution. But I can't figure out how to apply this in a local component, because I'm using nuxt. Vue.compile(this.vcontent); give an error

enter image description here

<script>
export default {
  props: ['vcontent'],
  data() {
    return {
      templateRender: null,
    }
  },
  render(h) {
    if (!this.templateRender) {
      return h('div', 'loading...');
    } else { // If there is a template, I'll show it
      return this.templateRender();
    }
  },
  watch: {

    vcontent:{
        immediate: true, // makes the watcher fire on first render, too.
      handler() {
        var res = Vue.compile(this.vcontent);

        this.templateRender = res.render;
        
        // staticRenderFns belong into $options, 
        // appearantly
        this.$options.staticRenderFns = []
        
        // clean the cache of static elements
        // this is a cache with the results from the staticRenderFns
        this._staticTrees = []
        
        // Fill it with the new staticRenderFns
        for (var i in res.staticRenderFns) {
          //staticRenderFns.push(res.staticRenderFns[i]);
          this.$options.staticRenderFns.push(res.staticRenderFns[i])
        }
      }
    }
  },
}
</script>


enter image description here

if im trying to import Vue in component, webpack gives an error vue__WEBPACK_IMPORTED_MODULE_0___default.a.compile is not a function

2 Answers 2

2

nuxt.config.js

    // if you are using webpack
    build: {
        extend(config, ctx){
            config.resolve.alias['vue'] = 'vue/dist/vue.common';
        }
    },
    
    // if you are using vite
    vite: {
        resolve: {
            alias: {
                'vue': 'vue/dist/vue.common'
            }
        },
    }

In your component which has component string in content my-component.js

import Btn from '~/components/btn.vue';
export default{
    props: ['vcontent'],
    render(h){
        let self = this;
        return h({
            components: {
                Btn
            },
            template: self.vcontent
        });
    }
}

2023/06/09 updated:

could be a vanilla and SSR-friendly solution

Sign up to request clarification or add additional context in comments.

Comments

0

By default, the Vue compiler is not included, so Vue.compile is not defined, but you can enable it in your Nuxt config by aliasing vue to the "full" build:

// nuxt.config.js
export default {
  build: {
    extend(config, ctx) {
      config.resolve.alias['vue'] = 'vue/dist/vue.common'
    }
  }
}

It also seems the watch handler needs to wait until the $nextTick before actually calling Vue.compile:

// MyComponent.vue
export default {
  watch: {
    vcontent: {
      immediate: true,
      async handler() {
        await this.$nextTick()
        const res = Vue.compile(this.vcontent)
        //...
      }
    }
  }
}

demo

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.