Vue.prototype.$vmodel = function(vn) { this[vn] = this.value; this.$watch('value',(nv, ov)=>{ if(nv!=ov) this[vn] = nv;}); this.$watch(vn,(nv, ov)=>{ if(nv!=ov) this.$emit("input",nv);}); } var COMP = { host : "localhost", css:[], loaded:{},//loaded comps object to prevent unnecessary calls to fetch comp templates base: { props:["value"], data(){return {val:{}}}, created() { this.$vmodel("val");}, }, initMain() { this.vue = new Vue ({ el:"#main", mixins:[{methods:UTIL}], data: { comp:"", comp_props:null, width:0, }, created() { window.onhashchange = ()=>this.$emit("onHash",UTIL.decodeHash()) window.onresize = ()=> this.isMobile() }, mounted() { document.addEventListener("keypress",(event)=> { if(event.key == "Enter") this.$emit("onEnterKey") }); this.$emit("onHash",UTIL.decodeHash()); this.isMobile() }, computed: { onMobile() { return this.isMobile(); }, }, methods: { log(val) { console.log(val); }, isMobile() { var isMobileDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); var isTouchScreen = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; var mobile = isMobileDevice || isTouchScreen; var w = window.innerWidth; var h = window.innerHeight; this.width = 0; var ratio = w/h var res = mobile || (this.width <= 1270 && ratio<1); if(this.width!=w) { this.width=w; } // console.log(this.width); return res; }, triggerEvent(el, eventName) { var event = new Event(eventName); el.dispatchEvent(event); } }, }); Vue.directive('DynamicEvents', { bind: (el, binding, vnode) => { const allEvents = binding.value; if(allEvents) { Object.keys(allEvents).forEach((event) => { vnode.componentInstance.$on(event, (eventData) => { const targetEvent = allEvents[event]; if(typeof targetEvent == "function") targetEvent(eventData) }); }); } }, unbind: function (el, binding, vnode) { vnode.componentInstance.$off(); }, }); }, Load(comp,comp_path,props,events) { if(!comp) { console.info("No Comp"); return; } if(!comp_path) { console.info("No Path"); return; } comp.comp = ""; comp.comp_props = {}; comp.events = {}; if(comp_path.substr(0,1)=="/") comp_path = comp_path.replace(/\//g,"-"); comp.comp = comp_path; comp.comp_props = props; if(!UTIL.Empty(events))comp.events = events; }, async externLoadComponent (resolv, reject, tag) { var path = "./comp.php?comp="+tag; try { if(COMP) { var json = COMP.loaded[tag]; var style = COMP.css[tag]; if(!json) { var response = await fetch(path); json = await response.text(); if(json) { COMP.loaded[tag] = json try { eval(json); } catch (error) { console.log(error); console.log(path,tag); resolv(comp) } if(newStyle) { if(!style) COMP.css[tag] = newStyle; var div = document.createElement("DIV"); div.setAttribute("id", tag); div.innerHTML = ""; document.body.appendChild(div); } if(!comp.methods) comp.methods = {}; if(comp.data && typeof(comp.data)=='function') comp.methods.__data = comp.data; // create a backup of the original data function try { loaded = JSON.parse(loaded); } catch (error) { loaded = {}; console.log(error); } comp.data = function() { var d = this.__data ? this.__data() : {}; d.tag = tag; return UTIL.deepMerge(d,loaded); }; resolv(comp) } else console.log("No Json"); } else console.log("No Json"); } } catch (error) { console.log("tag error",tag,error); reject(error) } }, } COMP.initMain(); //{"name":"aquatics","message":"database created successfully"}