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 = { loaded:{}, css:{}, base: { props:["value"], data(){return {val:{}}}, created() { this.$vmodel("val");}, }, initMain() { this.vue = new Vue ({ mixins:[{methods:UTIL}], el:"#main", template: '', data: { width:0, comp: null, props: {}, }, created() { this.loadCoreComp(); window.onpopstate = ()=> this.$emit("onPathChange", N.decodePath()); window.onresize = ()=> this.updateWidth() }, mounted() { this.$emit("onPathChange", N.decodePath()); this.updateWidth() }, computed: { onMobile() { 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; // Use the reactive 'this.width' property var w = this.width; var h = window.innerHeight; var ratio = w/h var res = mobile || (w <= 1270 && ratio<1); return res; }, }, methods: { loadCoreComp() { var el = document.querySelector(this.$options.el); if (el) { // 2. Read the attributes from it this.comp = 'core-b-comp'; this.props = { start_comp: el.getAttribute('start_comp'), default_tab: el.getAttribute('default_tab') }; // 3. Set the component to load } else { console.error("Root element '#main' not found."); } }, updateWidth() { this.width = window.innerWidth; }, }, }); 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(); var comp = {}; if(json) { COMP.loaded[tag] = json try { eval(json); } catch (error) { console.log(error); console.log(path,tag); resolv(comp) } if(template) comp.template = template; if(newStyle) { if(!style) { COMP.css[tag] = newStyle; const head = document.head; const styleId = tag; const styleTag = document.getElementById(styleId); if (styleTag) { styleTag.innerHTML += newStyle; } else { const newStyleTag = document.createElement('style'); newStyleTag.id = styleId; newStyleTag.innerHTML = newStyle; head.appendChild(newStyleTag); } } } 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 comp.data = function() { var d = this.__data ? this.__data() : {}; d.tag = tag; return d }; resolv(comp) } else console.log("No Json"); } else console.log("No Json"); } } catch (error) { console.log("tag error",tag,error); reject(error) } }, } COMP.initMain();