├── .gitignore
├── v-runtime-template.d.ts
├── .vscode
└── settings.json
├── Test.vue
├── main.js
├── vue.config.js
├── test.plugin.js
├── LICENSE
├── package.json
├── App.vue
├── dist
├── v-runtime-template.es.js
├── v-runtime-template.js
├── v-runtime-template.umd.js
├── v-runtime-template.js.map
├── v-runtime-template.es.js.map
└── v-runtime-template.umd.js.map
├── index.js
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/v-runtime-template.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'v-runtime-template'
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": false,
3 | }
--------------------------------------------------------------------------------
/Test.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App.vue";
3 |
4 | import testPlugin from "./test.plugin.js"; //testing mixins
5 |
6 | Vue.use(testPlugin);
7 |
8 | new Vue({
9 | render: h => h(App)
10 | }).$mount("#app");
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | // vue.config.js
2 |
3 | module.exports = {
4 | runtimeCompiler: true,
5 | configureWebpack: {
6 | resolve: {
7 | alias: {
8 | vue$: "vue/dist/vue.common"
9 | }
10 | }
11 | }
12 | };
--------------------------------------------------------------------------------
/test.plugin.js:
--------------------------------------------------------------------------------
1 | //https://vuejs.org/v2/guide/plugins.html
2 | //https://dev.to/nkoik/writing-a-very-simple-plugin-in-vuejs---example-8g8
3 | // This exports the plugin object.
4 |
5 | import Test from "./Test.vue"
6 |
7 | export default {
8 | // The install method will be called with the Vue constructor as
9 | // the first argument, along with possible options
10 | install(Vue) {
11 | Vue.mixin({
12 | components:{Test},
13 | props: {
14 | testingProp: {
15 | default: "mixinTest: testingProp"
16 | }
17 | },
18 | data() {
19 | return {
20 | testingData: "mixinTest: testingData"
21 | };
22 | },
23 | computed: {
24 | testingComputed() {
25 | return "mixinTest: testingComputed";
26 | }
27 | },
28 | methods: {
29 | testingMethod() {
30 | return "mixinTest: testingMethod";
31 | }
32 | }
33 | }); //end mixin
34 |
35 | Vue.prototype.$testProto = function (str) {
36 | return "mixinTest: testingProto=" + str;
37 | }; //end $testProto
38 |
39 | }
40 | };
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Alex Jover
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "v-runtime-template",
3 | "version": "1.10.0",
4 | "description": "Create Vue components by compiling templates on the fly",
5 | "main": "dist/v-runtime-template.umd.js",
6 | "scripts": {
7 | "prepublishOnly": "npm run build",
8 | "build": "microbundle index.js",
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/alexjoverm/v-runtime-template.git"
14 | },
15 | "keywords": [
16 | "vuejs",
17 | "dynamic",
18 | "runtime",
19 | "template"
20 | ],
21 | "author": {
22 | "name": "Alex J",
23 | "email": "alexjovermorales@gmail.com"
24 | },
25 | "license": "MIT",
26 | "devDependencies": {
27 | "microbundle": "^0.11.0"
28 | },
29 | "bugs": {
30 | "url": "https://github.com/alexjoverm/v-runtime-template/issues"
31 | },
32 | "homepage": "https://github.com/alexjoverm/v-runtime-template#readme",
33 | "module": "dist/v-runtime-template.es.js",
34 | "unpkg": "dist/v-runtime-template.umd.js",
35 | "browser": "dist/v-runtime-template.es.js",
36 | "types": "v-runtime-template.d.ts"
37 | }
38 |
--------------------------------------------------------------------------------
/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
53 |
54 |
56 |
--------------------------------------------------------------------------------
/dist/v-runtime-template.es.js:
--------------------------------------------------------------------------------
1 | var t=function(t,o,e){if(!o.hasOwnProperty(e)){var r=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(o,e,r)}};export default{props:{template:String,parent:Object,templateProps:{type:Object,default:function(){return{}}}},render:function(o){if(this.template){var e=this.parent||this.$parent,r=e.$data;void 0===r&&(r={});var n=e.$props;void 0===n&&(n={});var a=e.$options;void 0===a&&(a={});var c=a.components;void 0===c&&(c={});var p=a.computed;void 0===p&&(p={});var i=a.methods;void 0===i&&(i={});var s=this.$data;void 0===s&&(s={});var d=this.$props;void 0===d&&(d={});var v=this.$options;void 0===v&&(v={});var f=v.methods;void 0===f&&(f={});var m=v.computed;void 0===m&&(m={});var u=v.components;void 0===u&&(u={});var h={$data:{},$props:{},$options:{},components:{},computed:{},methods:{}};Object.keys(r).forEach(function(t){void 0===s[t]&&(h.$data[t]=r[t])}),Object.keys(n).forEach(function(t){void 0===d[t]&&(h.$props[t]=n[t])}),Object.keys(i).forEach(function(t){void 0===f[t]&&(h.methods[t]=i[t])}),Object.keys(p).forEach(function(t){void 0===m[t]&&(h.computed[t]=p[t])}),Object.keys(c).forEach(function(t){void 0===u[t]&&(h.components[t]=c[t])});var O=Object.keys(h.methods||{}),$=Object.keys(h.$data||{}),b=Object.keys(h.$props||{}),j=Object.keys(this.templateProps),y=$.concat(b).concat(O).concat(j),k=(E=e,P={},O.forEach(function(o){return t(E,P,o)}),P),l=function(o){var e={};return o.forEach(function(o){o&&Object.getOwnPropertyNames(o).forEach(function(r){return t(o,e,r)})}),e}([h.$data,h.$props,k,this.templateProps]);return o({template:this.template||"
",props:y,computed:h.computed,components:h.components},{props:l})}var E,P}};
2 | //# sourceMappingURL=v-runtime-template.es.js.map
3 |
--------------------------------------------------------------------------------
/dist/v-runtime-template.js:
--------------------------------------------------------------------------------
1 | var t=function(t,o,e){if(!o.hasOwnProperty(e)){var r=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(o,e,r)}},o={props:{template:String,parent:Object,templateProps:{type:Object,default:function(){return{}}}},render:function(o){if(this.template){var e=this.parent||this.$parent,r=e.$data;void 0===r&&(r={});var n=e.$props;void 0===n&&(n={});var a=e.$options;void 0===a&&(a={});var c=a.components;void 0===c&&(c={});var p=a.computed;void 0===p&&(p={});var i=a.methods;void 0===i&&(i={});var s=this.$data;void 0===s&&(s={});var d=this.$props;void 0===d&&(d={});var v=this.$options;void 0===v&&(v={});var m=v.methods;void 0===m&&(m={});var u=v.computed;void 0===u&&(u={});var f=v.components;void 0===f&&(f={});var h={$data:{},$props:{},$options:{},components:{},computed:{},methods:{}};Object.keys(r).forEach(function(t){void 0===s[t]&&(h.$data[t]=r[t])}),Object.keys(n).forEach(function(t){void 0===d[t]&&(h.$props[t]=n[t])}),Object.keys(i).forEach(function(t){void 0===m[t]&&(h.methods[t]=i[t])}),Object.keys(p).forEach(function(t){void 0===u[t]&&(h.computed[t]=p[t])}),Object.keys(c).forEach(function(t){void 0===f[t]&&(h.components[t]=c[t])});var O=Object.keys(h.methods||{}),$=Object.keys(h.$data||{}),b=Object.keys(h.$props||{}),j=Object.keys(this.templateProps),y=$.concat(b).concat(O).concat(j),k=(E=e,P={},O.forEach(function(o){return t(E,P,o)}),P),l=function(o){var e={};return o.forEach(function(o){o&&Object.getOwnPropertyNames(o).forEach(function(r){return t(o,e,r)})}),e}([h.$data,h.$props,k,this.templateProps]);return o({template:this.template||"
",props:y,computed:h.computed,components:h.components},{props:l})}var E,P}};module.exports=o;
2 | //# sourceMappingURL=v-runtime-template.js.map
3 |
--------------------------------------------------------------------------------
/dist/v-runtime-template.umd.js:
--------------------------------------------------------------------------------
1 | !function(t,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):t.vRuntimeTemplate=o()}(this,function(){var t=function(t,o,e){if(!o.hasOwnProperty(e)){var n=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(o,e,n)}};return{props:{template:String,parent:Object,templateProps:{type:Object,default:function(){return{}}}},render:function(o){if(this.template){var e=this.parent||this.$parent,n=e.$data;void 0===n&&(n={});var r=e.$props;void 0===r&&(r={});var p=e.$options;void 0===p&&(p={});var c=p.components;void 0===c&&(c={});var i=p.computed;void 0===i&&(i={});var a=p.methods;void 0===a&&(a={});var s=this.$data;void 0===s&&(s={});var d=this.$props;void 0===d&&(d={});var v=this.$options;void 0===v&&(v={});var f=v.methods;void 0===f&&(f={});var u=v.computed;void 0===u&&(u={});var m=v.components;void 0===m&&(m={});var h={$data:{},$props:{},$options:{},components:{},computed:{},methods:{}};Object.keys(n).forEach(function(t){void 0===s[t]&&(h.$data[t]=n[t])}),Object.keys(r).forEach(function(t){void 0===d[t]&&(h.$props[t]=r[t])}),Object.keys(a).forEach(function(t){void 0===f[t]&&(h.methods[t]=a[t])}),Object.keys(i).forEach(function(t){void 0===u[t]&&(h.computed[t]=i[t])}),Object.keys(c).forEach(function(t){void 0===m[t]&&(h.components[t]=c[t])});var y=Object.keys(h.methods||{}),O=Object.keys(h.$data||{}),$=Object.keys(h.$props||{}),b=Object.keys(this.templateProps),j=O.concat($).concat(y).concat(b),l=(E=e,P={},y.forEach(function(o){return t(E,P,o)}),P),k=function(o){var e={};return o.forEach(function(o){o&&Object.getOwnPropertyNames(o).forEach(function(n){return t(o,e,n)})}),e}([h.$data,h.$props,l,this.templateProps]);return o({template:this.template||"
",props:j,computed:h.computed,components:h.components},{props:k})}var E,P}}});
2 | //# sourceMappingURL=v-runtime-template.umd.js.map
3 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const defineDescriptor = (src, dest, name) => {
2 | if (!dest.hasOwnProperty(name)) {
3 | const descriptor = Object.getOwnPropertyDescriptor(src, name);
4 | Object.defineProperty(dest, name, descriptor);
5 | }
6 | };
7 |
8 | const merge = objs => {
9 | const res = {};
10 | objs.forEach(obj => {
11 | obj &&
12 | Object.getOwnPropertyNames(obj).forEach(name =>
13 | defineDescriptor(obj, res, name)
14 | );
15 | });
16 | return res;
17 | };
18 |
19 | const buildFromProps = (obj, props) => {
20 | const res = {};
21 | props.forEach(prop => defineDescriptor(obj, res, prop));
22 | return res;
23 | };
24 |
25 | export default {
26 | props: {
27 | template: String,
28 | parent: Object,
29 | templateProps: {
30 | type: Object,
31 | default: () => ({})
32 | }
33 | },
34 | render(h) {
35 | if (this.template) {
36 | const parent = this.parent || this.$parent
37 | const {
38 | $data: parentData = {},
39 | $props: parentProps = {},
40 | $options: parentOptions = {}
41 | } = parent;
42 | const {
43 | components: parentComponents = {},
44 | computed: parentComputed = {},
45 | methods: parentMethods = {}
46 | } = parentOptions;
47 | const {
48 | $data = {},
49 | $props = {},
50 | $options: { methods = {}, computed = {}, components = {} } = {}
51 | } = this;
52 | const passthrough = {
53 | $data: {},
54 | $props: {},
55 | $options: {},
56 | components: {},
57 | computed: {},
58 | methods: {}
59 | };
60 |
61 | //build new objects by removing keys if already exists (e.g. created by mixins)
62 | Object.keys(parentData).forEach(e => {
63 | if (typeof $data[e] === "undefined")
64 | passthrough.$data[e] = parentData[e];
65 | });
66 | Object.keys(parentProps).forEach(e => {
67 | if (typeof $props[e] === "undefined")
68 | passthrough.$props[e] = parentProps[e];
69 | });
70 | Object.keys(parentMethods).forEach(e => {
71 | if (typeof methods[e] === "undefined")
72 | passthrough.methods[e] = parentMethods[e];
73 | });
74 | Object.keys(parentComputed).forEach(e => {
75 | if (typeof computed[e] === "undefined")
76 | passthrough.computed[e] = parentComputed[e];
77 | });
78 | Object.keys(parentComponents).forEach(e => {
79 | if (typeof components[e] === "undefined")
80 | passthrough.components[e] = parentComponents[e];
81 | });
82 |
83 | const methodKeys = Object.keys(passthrough.methods || {});
84 | const dataKeys = Object.keys(passthrough.$data || {});
85 | const propKeys = Object.keys(passthrough.$props || {});
86 | const templatePropKeys = Object.keys(this.templateProps);
87 | const allKeys = dataKeys.concat(propKeys).concat(methodKeys).concat(templatePropKeys);
88 | const methodsFromProps = buildFromProps(parent, methodKeys);
89 | const finalProps = merge([
90 | passthrough.$data,
91 | passthrough.$props,
92 | methodsFromProps,
93 | this.templateProps
94 | ]);
95 | const provide = this.$parent._provided;
96 |
97 | const dynamic = {
98 | template: this.template || "
",
99 | props: allKeys,
100 | computed: passthrough.computed,
101 | components: passthrough.components,
102 | provide: provide
103 | };
104 |
105 | return h(dynamic, { props: finalProps });
106 | }
107 | }
108 | };
109 |
--------------------------------------------------------------------------------
/dist/v-runtime-template.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"v-runtime-template.js","sources":["../index.js"],"sourcesContent":["const defineDescriptor = (src, dest, name) => {\n if (!dest.hasOwnProperty(name)) {\n const descriptor = Object.getOwnPropertyDescriptor(src, name);\n Object.defineProperty(dest, name, descriptor);\n }\n};\n\nconst merge = objs => {\n const res = {};\n objs.forEach(obj => {\n obj &&\n Object.getOwnPropertyNames(obj).forEach(name =>\n defineDescriptor(obj, res, name)\n );\n });\n return res;\n};\n\nconst buildFromProps = (obj, props) => {\n const res = {};\n props.forEach(prop => defineDescriptor(obj, res, prop));\n return res;\n};\n\nexport default {\n props: {\n template: String,\n parent: Object,\n templateProps: {\n type: Object,\n default: () => ({})\n }\n },\n render(h) {\n if (this.template) {\n const parent = this.parent || this.$parent\n const {\n $data: parentData = {},\n $props: parentProps = {},\n $options: parentOptions = {}\n } = parent;\n const {\n components: parentComponents = {},\n computed: parentComputed = {},\n methods: parentMethods = {}\n } = parentOptions;\n const {\n $data = {},\n $props = {},\n $options: { methods = {}, computed = {}, components = {} } = {}\n } = this;\n const passthrough = {\n $data: {},\n $props: {},\n $options: {},\n components: {},\n computed: {},\n methods: {}\n };\n\n //build new objects by removing keys if already exists (e.g. created by mixins)\n Object.keys(parentData).forEach(e => {\n if (typeof $data[e] === \"undefined\")\n passthrough.$data[e] = parentData[e];\n });\n Object.keys(parentProps).forEach(e => {\n if (typeof $props[e] === \"undefined\")\n passthrough.$props[e] = parentProps[e];\n });\n Object.keys(parentMethods).forEach(e => {\n if (typeof methods[e] === \"undefined\")\n passthrough.methods[e] = parentMethods[e];\n });\n Object.keys(parentComputed).forEach(e => {\n if (typeof computed[e] === \"undefined\")\n passthrough.computed[e] = parentComputed[e];\n });\n Object.keys(parentComponents).forEach(e => {\n if (typeof components[e] === \"undefined\")\n passthrough.components[e] = parentComponents[e];\n });\n\n const methodKeys = Object.keys(passthrough.methods || {});\n const dataKeys = Object.keys(passthrough.$data || {});\n const propKeys = Object.keys(passthrough.$props || {});\n const templatePropKeys = Object.keys(this.templateProps);\n const allKeys = dataKeys.concat(propKeys).concat(methodKeys).concat(templatePropKeys);\n const methodsFromProps = buildFromProps(parent, methodKeys);\n const finalProps = merge([\n passthrough.$data,\n passthrough.$props,\n methodsFromProps,\n this.templateProps\n ]);\n\n const dynamic = {\n template: this.template || \"
\",\n props: allKeys,\n computed: passthrough.computed,\n components: passthrough.components\n };\n\n return h(dynamic, { props: finalProps });\n }\n }\n};\n"],"names":["const","defineDescriptor","src","dest","name","hasOwnProperty","descriptor","Object","getOwnPropertyDescriptor","defineProperty","props","template","String","parent","templateProps","type","default","render","h","this","$parent","passthrough","$data","$props","$options","components","computed","methods","keys","parentData","forEach","e","parentProps","parentMethods","parentComputed","parentComponents","methodKeys","dataKeys","propKeys","templatePropKeys","allKeys","concat","methodsFromProps","obj","res","prop","finalProps","objs","getOwnPropertyNames","merge"],"mappings":"AAAAA,IAAMC,WAAoBC,EAAKC,EAAMC,OAC9BD,EAAKE,eAAeD,GAAO,KACxBE,EAAaC,OAAOC,yBAAyBN,EAAKE,GACxDG,OAAOE,eAAeN,EAAMC,EAAME,OAqBvB,CACbI,MAAO,CACLC,SAAUC,OACVC,OAAQN,OACRO,cAAe,CACbC,KAAMR,OACNS,+BAGJC,gBAAOC,MACDC,KAAKR,SAAU,KACXE,EAASM,KAAKN,QAAUM,KAAKC,iCAEb,kCACE,oCACI,sCAGK,oCACJ,mCACF,UAMvBD,0BAHM,UAGNA,2BAFO,UAEPA,6BAD2D,IAAnD,+BAAY,oCAAe,sCAAiB,QAElDE,EAAc,CAClBC,MAAO,GACPC,OAAQ,GACRC,SAAU,GACVC,WAAY,GACZC,SAAU,GACVC,QAAS,IAIXpB,OAAOqB,KAAKC,GAAYC,iBAAQC,QACN,IAAbT,EAAMS,KACfV,EAAYC,MAAMS,GAAKF,EAAWE,MAEtCxB,OAAOqB,KAAKI,GAAaF,iBAAQC,QACN,IAAdR,EAAOQ,KAChBV,EAAYE,OAAOQ,GAAKC,EAAYD,MAExCxB,OAAOqB,KAAKK,GAAeH,iBAAQC,QACP,IAAfJ,EAAQI,KACjBV,EAAYM,QAAQI,GAAKE,EAAcF,MAE3CxB,OAAOqB,KAAKM,GAAgBJ,iBAAQC,QACP,IAAhBL,EAASK,KAClBV,EAAYK,SAASK,GAAKG,EAAeH,MAE7CxB,OAAOqB,KAAKO,GAAkBL,iBAAQC,QACP,IAAlBN,EAAWM,KACpBV,EAAYI,WAAWM,GAAKI,EAAiBJ,UAG3CK,EAAa7B,OAAOqB,KAAKP,EAAYM,SAAW,IAChDU,EAAW9B,OAAOqB,KAAKP,EAAYC,OAAS,IAC5CgB,EAAW/B,OAAOqB,KAAKP,EAAYE,QAAU,IAC7CgB,EAAmBhC,OAAOqB,KAAKT,KAAKL,eACpC0B,EAAUH,EAASI,OAAOH,GAAUG,OAAOL,GAAYK,OAAOF,GAC9DG,GArEYC,EAqEsB9B,EApEtC+B,EAAM,GAoEwCR,EAnE9CN,iBAAQe,UAAQ5C,EAAiB0C,EAAKC,EAAKC,KAC1CD,GAmEGE,WAjFEC,OACNH,EAAM,UACZG,EAAKjB,iBAAQa,GACXA,GACEpC,OAAOyC,oBAAoBL,GAAKb,iBAAQ1B,UACtCH,EAAiB0C,EAAKC,EAAKxC,OAG1BwC,EAyEgBK,CAAM,CACvB5B,EAAYC,MACZD,EAAYE,OACZmB,EACAvB,KAAKL,uBAUAI,EAPS,CACdP,SAAUQ,KAAKR,UAAY,cAC3BD,MAAO8B,EACPd,SAAUL,EAAYK,SACtBD,WAAYJ,EAAYI,YAGR,CAAEf,MAAOoC,QApFTH,EAChBC"}
--------------------------------------------------------------------------------
/dist/v-runtime-template.es.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"v-runtime-template.es.js","sources":["../index.js"],"sourcesContent":["const defineDescriptor = (src, dest, name) => {\n if (!dest.hasOwnProperty(name)) {\n const descriptor = Object.getOwnPropertyDescriptor(src, name);\n Object.defineProperty(dest, name, descriptor);\n }\n};\n\nconst merge = objs => {\n const res = {};\n objs.forEach(obj => {\n obj &&\n Object.getOwnPropertyNames(obj).forEach(name =>\n defineDescriptor(obj, res, name)\n );\n });\n return res;\n};\n\nconst buildFromProps = (obj, props) => {\n const res = {};\n props.forEach(prop => defineDescriptor(obj, res, prop));\n return res;\n};\n\nexport default {\n props: {\n template: String,\n parent: Object,\n templateProps: {\n type: Object,\n default: () => ({})\n }\n },\n render(h) {\n if (this.template) {\n const parent = this.parent || this.$parent\n const {\n $data: parentData = {},\n $props: parentProps = {},\n $options: parentOptions = {}\n } = parent;\n const {\n components: parentComponents = {},\n computed: parentComputed = {},\n methods: parentMethods = {}\n } = parentOptions;\n const {\n $data = {},\n $props = {},\n $options: { methods = {}, computed = {}, components = {} } = {}\n } = this;\n const passthrough = {\n $data: {},\n $props: {},\n $options: {},\n components: {},\n computed: {},\n methods: {}\n };\n\n //build new objects by removing keys if already exists (e.g. created by mixins)\n Object.keys(parentData).forEach(e => {\n if (typeof $data[e] === \"undefined\")\n passthrough.$data[e] = parentData[e];\n });\n Object.keys(parentProps).forEach(e => {\n if (typeof $props[e] === \"undefined\")\n passthrough.$props[e] = parentProps[e];\n });\n Object.keys(parentMethods).forEach(e => {\n if (typeof methods[e] === \"undefined\")\n passthrough.methods[e] = parentMethods[e];\n });\n Object.keys(parentComputed).forEach(e => {\n if (typeof computed[e] === \"undefined\")\n passthrough.computed[e] = parentComputed[e];\n });\n Object.keys(parentComponents).forEach(e => {\n if (typeof components[e] === \"undefined\")\n passthrough.components[e] = parentComponents[e];\n });\n\n const methodKeys = Object.keys(passthrough.methods || {});\n const dataKeys = Object.keys(passthrough.$data || {});\n const propKeys = Object.keys(passthrough.$props || {});\n const templatePropKeys = Object.keys(this.templateProps);\n const allKeys = dataKeys.concat(propKeys).concat(methodKeys).concat(templatePropKeys);\n const methodsFromProps = buildFromProps(parent, methodKeys);\n const finalProps = merge([\n passthrough.$data,\n passthrough.$props,\n methodsFromProps,\n this.templateProps\n ]);\n\n const dynamic = {\n template: this.template || \"
\",\n props: allKeys,\n computed: passthrough.computed,\n components: passthrough.components\n };\n\n return h(dynamic, { props: finalProps });\n }\n }\n};\n"],"names":["const","defineDescriptor","src","dest","name","hasOwnProperty","descriptor","Object","getOwnPropertyDescriptor","defineProperty","props","template","String","parent","templateProps","type","default","render","h","this","$parent","passthrough","$data","$props","$options","components","computed","methods","keys","parentData","forEach","e","parentProps","parentMethods","parentComputed","parentComponents","methodKeys","dataKeys","propKeys","templatePropKeys","allKeys","concat","methodsFromProps","obj","res","prop","finalProps","objs","getOwnPropertyNames","merge"],"mappings":"AAAAA,IAAMC,WAAoBC,EAAKC,EAAMC,OAC9BD,EAAKE,eAAeD,GAAO,KACxBE,EAAaC,OAAOC,yBAAyBN,EAAKE,GACxDG,OAAOE,eAAeN,EAAMC,EAAME,mBAqBvB,CACbI,MAAO,CACLC,SAAUC,OACVC,OAAQN,OACRO,cAAe,CACbC,KAAMR,OACNS,+BAGJC,gBAAOC,MACDC,KAAKR,SAAU,KACXE,EAASM,KAAKN,QAAUM,KAAKC,iCAEb,kCACE,oCACI,sCAGK,oCACJ,mCACF,UAMvBD,0BAHM,UAGNA,2BAFO,UAEPA,6BAD2D,IAAnD,+BAAY,oCAAe,sCAAiB,QAElDE,EAAc,CAClBC,MAAO,GACPC,OAAQ,GACRC,SAAU,GACVC,WAAY,GACZC,SAAU,GACVC,QAAS,IAIXpB,OAAOqB,KAAKC,GAAYC,iBAAQC,QACN,IAAbT,EAAMS,KACfV,EAAYC,MAAMS,GAAKF,EAAWE,MAEtCxB,OAAOqB,KAAKI,GAAaF,iBAAQC,QACN,IAAdR,EAAOQ,KAChBV,EAAYE,OAAOQ,GAAKC,EAAYD,MAExCxB,OAAOqB,KAAKK,GAAeH,iBAAQC,QACP,IAAfJ,EAAQI,KACjBV,EAAYM,QAAQI,GAAKE,EAAcF,MAE3CxB,OAAOqB,KAAKM,GAAgBJ,iBAAQC,QACP,IAAhBL,EAASK,KAClBV,EAAYK,SAASK,GAAKG,EAAeH,MAE7CxB,OAAOqB,KAAKO,GAAkBL,iBAAQC,QACP,IAAlBN,EAAWM,KACpBV,EAAYI,WAAWM,GAAKI,EAAiBJ,UAG3CK,EAAa7B,OAAOqB,KAAKP,EAAYM,SAAW,IAChDU,EAAW9B,OAAOqB,KAAKP,EAAYC,OAAS,IAC5CgB,EAAW/B,OAAOqB,KAAKP,EAAYE,QAAU,IAC7CgB,EAAmBhC,OAAOqB,KAAKT,KAAKL,eACpC0B,EAAUH,EAASI,OAAOH,GAAUG,OAAOL,GAAYK,OAAOF,GAC9DG,GArEYC,EAqEsB9B,EApEtC+B,EAAM,GAoEwCR,EAnE9CN,iBAAQe,UAAQ5C,EAAiB0C,EAAKC,EAAKC,KAC1CD,GAmEGE,WAjFEC,OACNH,EAAM,UACZG,EAAKjB,iBAAQa,GACXA,GACEpC,OAAOyC,oBAAoBL,GAAKb,iBAAQ1B,UACtCH,EAAiB0C,EAAKC,EAAKxC,OAG1BwC,EAyEgBK,CAAM,CACvB5B,EAAYC,MACZD,EAAYE,OACZmB,EACAvB,KAAKL,uBAUAI,EAPS,CACdP,SAAUQ,KAAKR,UAAY,cAC3BD,MAAO8B,EACPd,SAAUL,EAAYK,SACtBD,WAAYJ,EAAYI,YAGR,CAAEf,MAAOoC,QApFTH,EAChBC"}
--------------------------------------------------------------------------------
/dist/v-runtime-template.umd.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"v-runtime-template.umd.js","sources":["../index.js"],"sourcesContent":["const defineDescriptor = (src, dest, name) => {\n if (!dest.hasOwnProperty(name)) {\n const descriptor = Object.getOwnPropertyDescriptor(src, name);\n Object.defineProperty(dest, name, descriptor);\n }\n};\n\nconst merge = objs => {\n const res = {};\n objs.forEach(obj => {\n obj &&\n Object.getOwnPropertyNames(obj).forEach(name =>\n defineDescriptor(obj, res, name)\n );\n });\n return res;\n};\n\nconst buildFromProps = (obj, props) => {\n const res = {};\n props.forEach(prop => defineDescriptor(obj, res, prop));\n return res;\n};\n\nexport default {\n props: {\n template: String,\n parent: Object,\n templateProps: {\n type: Object,\n default: () => ({})\n }\n },\n render(h) {\n if (this.template) {\n const parent = this.parent || this.$parent\n const {\n $data: parentData = {},\n $props: parentProps = {},\n $options: parentOptions = {}\n } = parent;\n const {\n components: parentComponents = {},\n computed: parentComputed = {},\n methods: parentMethods = {}\n } = parentOptions;\n const {\n $data = {},\n $props = {},\n $options: { methods = {}, computed = {}, components = {} } = {}\n } = this;\n const passthrough = {\n $data: {},\n $props: {},\n $options: {},\n components: {},\n computed: {},\n methods: {}\n };\n\n //build new objects by removing keys if already exists (e.g. created by mixins)\n Object.keys(parentData).forEach(e => {\n if (typeof $data[e] === \"undefined\")\n passthrough.$data[e] = parentData[e];\n });\n Object.keys(parentProps).forEach(e => {\n if (typeof $props[e] === \"undefined\")\n passthrough.$props[e] = parentProps[e];\n });\n Object.keys(parentMethods).forEach(e => {\n if (typeof methods[e] === \"undefined\")\n passthrough.methods[e] = parentMethods[e];\n });\n Object.keys(parentComputed).forEach(e => {\n if (typeof computed[e] === \"undefined\")\n passthrough.computed[e] = parentComputed[e];\n });\n Object.keys(parentComponents).forEach(e => {\n if (typeof components[e] === \"undefined\")\n passthrough.components[e] = parentComponents[e];\n });\n\n const methodKeys = Object.keys(passthrough.methods || {});\n const dataKeys = Object.keys(passthrough.$data || {});\n const propKeys = Object.keys(passthrough.$props || {});\n const templatePropKeys = Object.keys(this.templateProps);\n const allKeys = dataKeys.concat(propKeys).concat(methodKeys).concat(templatePropKeys);\n const methodsFromProps = buildFromProps(parent, methodKeys);\n const finalProps = merge([\n passthrough.$data,\n passthrough.$props,\n methodsFromProps,\n this.templateProps\n ]);\n\n const dynamic = {\n template: this.template || \"
\",\n props: allKeys,\n computed: passthrough.computed,\n components: passthrough.components\n };\n\n return h(dynamic, { props: finalProps });\n }\n }\n};\n"],"names":["const","defineDescriptor","src","dest","name","hasOwnProperty","descriptor","Object","getOwnPropertyDescriptor","defineProperty","props","template","String","parent","templateProps","type","default","render","h","this","$parent","passthrough","$data","$props","$options","components","computed","methods","keys","parentData","forEach","e","parentProps","parentMethods","parentComputed","parentComponents","methodKeys","dataKeys","propKeys","templatePropKeys","allKeys","concat","methodsFromProps","obj","res","prop","finalProps","objs","getOwnPropertyNames","merge"],"mappings":"+KAAAA,IAAMC,WAAoBC,EAAKC,EAAMC,OAC9BD,EAAKE,eAAeD,GAAO,KACxBE,EAAaC,OAAOC,yBAAyBN,EAAKE,GACxDG,OAAOE,eAAeN,EAAMC,EAAME,WAqBvB,CACbI,MAAO,CACLC,SAAUC,OACVC,OAAQN,OACRO,cAAe,CACbC,KAAMR,OACNS,+BAGJC,gBAAOC,MACDC,KAAKR,SAAU,KACXE,EAASM,KAAKN,QAAUM,KAAKC,iCAEb,kCACE,oCACI,sCAGK,oCACJ,mCACF,UAMvBD,0BAHM,UAGNA,2BAFO,UAEPA,6BAD2D,IAAnD,+BAAY,oCAAe,sCAAiB,QAElDE,EAAc,CAClBC,MAAO,GACPC,OAAQ,GACRC,SAAU,GACVC,WAAY,GACZC,SAAU,GACVC,QAAS,IAIXpB,OAAOqB,KAAKC,GAAYC,iBAAQC,QACN,IAAbT,EAAMS,KACfV,EAAYC,MAAMS,GAAKF,EAAWE,MAEtCxB,OAAOqB,KAAKI,GAAaF,iBAAQC,QACN,IAAdR,EAAOQ,KAChBV,EAAYE,OAAOQ,GAAKC,EAAYD,MAExCxB,OAAOqB,KAAKK,GAAeH,iBAAQC,QACP,IAAfJ,EAAQI,KACjBV,EAAYM,QAAQI,GAAKE,EAAcF,MAE3CxB,OAAOqB,KAAKM,GAAgBJ,iBAAQC,QACP,IAAhBL,EAASK,KAClBV,EAAYK,SAASK,GAAKG,EAAeH,MAE7CxB,OAAOqB,KAAKO,GAAkBL,iBAAQC,QACP,IAAlBN,EAAWM,KACpBV,EAAYI,WAAWM,GAAKI,EAAiBJ,UAG3CK,EAAa7B,OAAOqB,KAAKP,EAAYM,SAAW,IAChDU,EAAW9B,OAAOqB,KAAKP,EAAYC,OAAS,IAC5CgB,EAAW/B,OAAOqB,KAAKP,EAAYE,QAAU,IAC7CgB,EAAmBhC,OAAOqB,KAAKT,KAAKL,eACpC0B,EAAUH,EAASI,OAAOH,GAAUG,OAAOL,GAAYK,OAAOF,GAC9DG,GArEYC,EAqEsB9B,EApEtC+B,EAAM,GAoEwCR,EAnE9CN,iBAAQe,UAAQ5C,EAAiB0C,EAAKC,EAAKC,KAC1CD,GAmEGE,WAjFEC,OACNH,EAAM,UACZG,EAAKjB,iBAAQa,GACXA,GACEpC,OAAOyC,oBAAoBL,GAAKb,iBAAQ1B,UACtCH,EAAiB0C,EAAKC,EAAKxC,OAG1BwC,EAyEgBK,CAAM,CACvB5B,EAAYC,MACZD,EAAYE,OACZmB,EACAvB,KAAKL,uBAUAI,EAPS,CACdP,SAAUQ,KAAKR,UAAY,cAC3BD,MAAO8B,EACPd,SAAUL,EAAYK,SACtBD,WAAYJ,EAAYI,YAGR,CAAEf,MAAOoC,QApFTH,EAChBC"}
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # v-runtime-template
2 |
3 | [](https://www.npmjs.com/package/v-runtime-template)
4 | [](https://www.npmjs.com/package/v-runtime-template)
5 | [](https://paypal.me/AJoverMorales)
6 |
7 | A Vue.js components that makes easy compiling and interpreting a Vue.js template at runtime by using a `v-html` like API.
8 |
9 | > Do you know **[VueDose](https://vuedose.tips)**? It's where you can learn tips about the Vue.js ecosystem in a concise format, perfect for busy devs! 🦄
10 |
11 | *[See Demo on CodeSandbox](https://codesandbox.io/s/884v9kq790)*
12 |
13 | ## Motivation
14 |
15 | This library solves the case where you get a vue-syntax template string on runtime, usually from a server. Think of a feature where you allow the user to create their own interfaces and structures. You save that as a vue template in your database, which your UI will request later. While components are pre-compiled at build time, this case isn't (since the template is received at runtime) and needs to be compiled at runtime.
16 |
17 | v-runtime-template compiles that template and attaches it to the scope of the component that uses it, so it has access to its data, props, methods and computed properties.
18 |
19 | Think of it as the `v-html` equivalent that also understands vue template syntax (while `v-html` is just for plain HTML).
20 |
21 | ## Getting Started
22 |
23 | Install it:
24 |
25 | ```
26 | npm install v-runtime-template
27 | ```
28 |
29 | You must **use the with-compiler Vue.js version**. This is needed in order to compile on-the-fly Vue.js templates. For that, you can set a webpack alias for `vue` to the `vue/dist/vue.common` file.
30 |
31 | For example, if you use the [Vue CLI](https://github.com/vuejs/vue-cli), create or modify the `vue.config.js` file adding the following alias:
32 |
33 | ```js
34 | // vue.config.js
35 | module.exports = {
36 | runtimeCompiler: true
37 | };
38 | ```
39 |
40 | And in [Nuxt](http://nuxtjs.org/), open the `nuxt.config.js` file and extend the webpack config by adding the following line to the `extend` key:
41 |
42 | ```js
43 | // nuxt.config.js
44 | {
45 | build: {
46 | extend(config, { isDev, isClient }) {
47 | config.resolve.alias["vue"] = "vue/dist/vue.common";
48 | // ...
49 | ```
50 |
51 | ## Usage
52 |
53 | You just need to import the `v-runtime-template` component, and pass the template you want:
54 |
55 | ```html
56 |
57 |
58 |
59 |
60 |
61 |
62 |
79 | ```
80 |
81 | The template you pass **have access to the parent component instance**. For example, in the last example we're using the `AppMessage` component and accessing the `{{ name }}` state variable.
82 |
83 | But you can access computed properties and methods as well from the template:
84 |
85 | ```js
86 | export default {
87 | data: () => ({
88 | name: "Mellow",
89 | template: `
90 |
91 |
Hello {{ name }}!
92 |
Say Hi!
93 |
{{ someComputed }}
94 |
95 | `,
96 | }),
97 | computed: {
98 | someComputed() {
99 | return "Wow, I'm computed";
100 | },
101 | },
102 | methods: {
103 | sayHi() {
104 | console.log("Hi");
105 | },
106 | },
107 | };
108 | ```
109 |
110 | ## Limitations
111 |
112 | Keep in mind that the template can only access the instance properties of the component who is using it. Read [this issue](https://github.com/alexjoverm/v-runtime-template/issues/9) for more information.
113 |
114 | ## Comparison
115 |
116 | ### v-runtime-template VS v-html
117 |
118 | _TL;DR: If you need to interpret only HTML, use `v-html`. Use this library otherwise._
119 |
120 | They both have the same goal: to interpret and attach a piece of structure to a scope at runtime. The difference is, `[v-html](https://vuejs.org/v2/api/#v-html)` doesn't understand vue template syntax, but only HTML. So, while this code works:
121 |
122 | ```html
123 |
124 |
125 |
126 |
127 |