html頁(yè)面引入vue組件之http-vue-loader.js解讀
html頁(yè)面引入vue組件之http-vue-loader.js
首先這種方法不推薦,日常工作中也不會(huì)在html里面引入一個(gè)vue文件,只是為了有時(shí)候方便測(cè)試才會(huì)這么做
1.創(chuàng)建my-component.vue
<template> ? ? <div class="hello">Hello {{who}}</div> </template> ? <script> module.exports = { ? ? data: function() { ? ? ? ? return { ? ? ? ? ? ? who: 'world' ? ? ? ? } ? ? } } </script> ? <style> .hello { ? ? background-color: #ffe; } </style>
2.創(chuàng)建index.html
<!DOCTYPE html> <html> <head> ? ? <meta charset="UTF-8"> ? ? <!-- 引入樣式 --> ? ? <link rel="stylesheet" rel="external nofollow" > ? ? <!-- 先引入 Vue --> ? ? <script src="https://unpkg.com/vue/dist/vue.js"></script> ? ? <!-- 引入 http-vue-loader --> ? ? <script src="https://unpkg.com/http-vue-loader"></script> </head> <body> ? ? <div id="app"> ? ? ? ? <my-component></my-component> ? ? </div> </body> <!-- 引入組件庫(kù) --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <script> ? ? // 使用httpVueLoader ? ? Vue.use(httpVueLoader); ? ? new Vue({ ? ? ? ? el: '#app', ? ? ? ? data: function () { ? ? ? ? ? ? return { visible: false } ? ? ? ? }, ? ? ? ? components: { ? ? ? ? ? ? // 將組建加入組建庫(kù) ? ? ? ? ? ? 'my-component': 'url:./component/my-component.vue' ? ? ? ? } ? ? }) </script> </html>
這樣就可以直接在html頁(yè)面里面引用vue文件,而不需要從頭開(kāi)始創(chuàng)建一個(gè)新的vue項(xiàng)目,方便日常測(cè)試使用
httpVueLoader的其他組件載入方式可查看這里
單頁(yè)面vue項(xiàng)目注冊(cè)使用組件(使用httpVueloader)
主要是最近寫的項(xiàng)目涉及到,就順便記錄一下,
使用的概率不是很大啊畢竟現(xiàn)在大部分都是直接搭的項(xiàng)目組件正常方式使用組件即可
安裝并引入插件插件
既然是單頁(yè)面使用,最簡(jiǎn)單快捷的就是直接script引用了,這里我就直接把文件放出來(lái)自取好了,今天百度網(wǎng)盤有點(diǎn)卡分享不出來(lái),文件又比較長(zhǎng),就放文章最末尾吧
<script src="./lib/httpVueLoader.js" type="text/javascript" charset="utf-8"></script>
準(zhǔn)備組件
隨便畫個(gè)組件反正也就測(cè)試用用
<template> <div class="test"> <p>{{name}}</p> <p>{{state}}</p> </div> </template> <script> module.exports = { name:'test', data(){ return{ name:222 } }, props:{ state:{ type:String } } } </script> <style> </style>
引用
引用方法有好幾種 這里我就拿我用的來(lái)舉例吧,直接上父組件代碼,首先是html頁(yè)面
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="renderer" content="webkit|ie-comp|ie-stand"> <title></title> <link rel="stylesheet" type="text/css" href="PCdemo/src/js&css/mainPage.css" rel="external nofollow" /> </head> <body> <!-- 容器 --> <div id="mainpage"> <p>這是父組件頁(yè)面</p> <!--組件測(cè)試 --> <test></test> </div> <!-- vue2.6.11 --> <script src="./lib/vue.js"></script> <!-- 組件測(cè)試 --> <script src="./lib/httpVueLoader.js" type="text/javascript" charset="utf-8"></script> <!-- 自定義js --> <script src="PCdemo/src/js&css/mainPage.js" type="text/javascript" charset="utf-8"></script> </body> </html>
然后是js頁(yè)面,當(dāng)然全寫一個(gè)html也行啊看個(gè)人喜好,這里因?yàn)轫?xiàng)目需求兼容ie,所以寫的比較原始
var appVue = new Vue({ el: "#mainpage", components:{ 'test': httpVueLoader('../PCdemo/src/components/test.vue') }, data: function() { return { state:'1111' } } })
那么效果就完成了
插件的其他注冊(cè)使用組件方法
組件官網(wǎng) 還提供了其他注冊(cè)引入方法,講的比較細(xì)致啊這里就不贅述了 有興趣可以自己去看看
插件js文件
(function umd(root,factory){ if(typeof module==='object' && typeof exports === 'object' ) module.exports=factory() else if(typeof define==='function' && define.amd) define([],factory) else root.httpVueLoader=factory() })(this,function factory() { 'use strict'; var scopeIndex = 0; StyleContext.prototype = { withBase: function(callback) { var tmpBaseElt; if ( this.component.baseURI ) { // firefox and chrome need the <base> to be set while inserting or modifying <style> in a document. tmpBaseElt = document.createElement('base'); tmpBaseElt.href = this.component.baseURI; var headElt = this.component.getHead(); headElt.insertBefore(tmpBaseElt, headElt.firstChild); } callback.call(this); if ( tmpBaseElt ) this.component.getHead().removeChild(tmpBaseElt); }, scopeStyles: function(styleElt, scopeName) { function process() { var sheet = styleElt.sheet; var rules = sheet.cssRules; for ( var i = 0; i < rules.length; ++i ) { var rule = rules[i]; if ( rule.type !== 1 ) continue; var scopedSelectors = []; rule.selectorText.split(/\s*,\s*/).forEach(function(sel) { scopedSelectors.push(scopeName+' '+sel); var segments = sel.match(/([^ :]+)(.+)?/); scopedSelectors.push(segments[1] + scopeName + (segments[2]||'')); }); var scopedRule = scopedSelectors.join(',') + rule.cssText.substr(rule.selectorText.length); sheet.deleteRule(i); sheet.insertRule(scopedRule, i); } } try { // firefox may fail sheet.cssRules with InvalidAccessError process(); } catch (ex) { if ( ex instanceof DOMException && ex.code === DOMException.INVALID_ACCESS_ERR ) { styleElt.sheet.disabled = true; styleElt.addEventListener('load', function onStyleLoaded() { styleElt.removeEventListener('load', onStyleLoaded); // firefox need this timeout otherwise we have to use document.importNode(style, true) setTimeout(function() { process(); styleElt.sheet.disabled = false; }); }); return; } throw ex; } }, compile: function() { var hasTemplate = this.template !== null; var scoped = this.elt.hasAttribute('scoped'); if ( scoped ) { // no template, no scopable style needed if ( !hasTemplate ) return; // firefox does not tolerate this attribute this.elt.removeAttribute('scoped'); } this.withBase(function() { this.component.getHead().appendChild(this.elt); }); if ( scoped ) this.scopeStyles(this.elt, '['+this.component.getScopeId()+']'); return Promise.resolve(); }, getContent: function() { return this.elt.textContent; }, setContent: function(content) { this.withBase(function() { this.elt.textContent = content; }); } }; function StyleContext(component, elt) { this.component = component; this.elt = elt; } ScriptContext.prototype = { getContent: function() { return this.elt.textContent; }, setContent: function(content) { this.elt.textContent = content; }, compile: function(module) { var childModuleRequire = function(childURL) { return httpVueLoader.require(resolveURL(this.component.baseURI, childURL)); }.bind(this); var childLoader = function(childURL, childName) { return httpVueLoader(resolveURL(this.component.baseURI, childURL), childName); }.bind(this); try { Function('exports', 'require', 'httpVueLoader', 'module', this.getContent()).call(this.module.exports, this.module.exports, childModuleRequire, childLoader, this.module); } catch(ex) { if ( !('lineNumber' in ex) ) { return Promise.reject(ex); } var vueFileData = responseText.replace(/\r?\n/g, '\n'); var lineNumber = vueFileData.substr(0, vueFileData.indexOf(script)).split('\n').length + ex.lineNumber - 1; throw new (ex.constructor)(ex.message, url, lineNumber); } return Promise.resolve(this.module.exports) .then(httpVueLoader.scriptExportsHandler.bind(this)) .then(function(exports) { this.module.exports = exports; }.bind(this)); } }; function ScriptContext(component, elt) { this.component = component; this.elt = elt; this.module = { exports:{} }; } TemplateContext.prototype = { getContent: function() { return this.elt.innerHTML; }, setContent: function(content) { this.elt.innerHTML = content; }, getRootElt: function() { var tplElt = this.elt.content || this.elt; if ( 'firstElementChild' in tplElt ) return tplElt.firstElementChild; for ( tplElt = tplElt.firstChild; tplElt !== null; tplElt = tplElt.nextSibling ) if ( tplElt.nodeType === Node.ELEMENT_NODE ) return tplElt; return null; }, compile: function() { return Promise.resolve(); } }; function TemplateContext(component, elt) { this.component = component; this.elt = elt; } Component.prototype = { getHead: function() { return document.head || document.getElementsByTagName('head')[0]; }, getScopeId: function() { if ( this._scopeId === '' ) { this._scopeId = 'data-s-' + (scopeIndex++).toString(36); this.template.getRootElt().setAttribute(this._scopeId, ''); } return this._scopeId; }, load: function(componentURL) { return httpVueLoader.httpRequest(componentURL) .then(function(responseText) { this.baseURI = componentURL.substr(0, componentURL.lastIndexOf('/')+1); var doc = document.implementation.createHTMLDocument(''); // IE requires the <base> to come with <style> doc.body.innerHTML = (this.baseURI ? '<base href="'+this.baseURI+'" rel="external nofollow" >' : '') + responseText; for ( var it = doc.body.firstChild; it; it = it.nextSibling ) { switch ( it.nodeName ) { case 'TEMPLATE': this.template = new TemplateContext(this, it); break; case 'SCRIPT': this.script = new ScriptContext(this, it); break; case 'STYLE': this.styles.push(new StyleContext(this, it)); break; } } return this; }.bind(this)); }, _normalizeSection: function(eltCx) { var p; if ( eltCx === null || !eltCx.elt.hasAttribute('src') ) { p = Promise.resolve(null); } else { p = httpVueLoader.httpRequest(eltCx.elt.getAttribute('src')) .then(function(content) { eltCx.elt.removeAttribute('src'); return content; }); } return p .then(function(content) { if ( eltCx !== null && eltCx.elt.hasAttribute('lang') ) { var lang = eltCx.elt.getAttribute('lang'); eltCx.elt.removeAttribute('lang'); return httpVueLoader.langProcessor[lang.toLowerCase()].call(this, content === null ? eltCx.getContent() : content); } return content; }.bind(this)) .then(function(content) { if ( content !== null ) eltCx.setContent(content); }); }, normalize: function() { return Promise.all(Array.prototype.concat( this._normalizeSection(this.template), this._normalizeSection(this.script), this.styles.map(this._normalizeSection) )) .then(function() { return this; }.bind(this)); }, compile: function() { return Promise.all(Array.prototype.concat( this.template && this.template.compile(), this.script && this.script.compile(), this.styles.map(function(style) { return style.compile(); }) )) .then(function() { return this; }.bind(this)); } }; function Component(name) { this.name = name; this.template = null; this.script = null; this.styles = []; this._scopeId = ''; } function identity(value) { return value; } function parseComponentURL(url) { var comp = url.match(/(.*?)([^/]+?)\/?(\.vue)?(\?.*|#.*|$)/); return { name: comp[2], url: comp[1] + comp[2] + (comp[3] === undefined ? '/index.vue' : comp[3]) + comp[4] }; } function resolveURL(baseURL, url) { if (url.substr(0, 2) === './' || url.substr(0, 3) === '../') { return baseURL + url; } return url; } httpVueLoader.load = function(url, name) { return function() { return new Component(name).load(url) .then(function(component) { return component.normalize(); }) .then(function(component) { return component.compile(); }) .then(function(component) { var exports = component.script !== null ? component.script.module.exports : {}; if ( component.template !== null ) exports.template = component.template.getContent(); if ( exports.name === undefined ) if ( component.name !== undefined ) exports.name = component.name; exports._baseURI = component.baseURI; return exports; }); }; }; httpVueLoader.register = function(Vue, url) { var comp = parseComponentURL(url); Vue.component(comp.name, httpVueLoader.load(comp.url)); }; httpVueLoader.install = function(Vue) { Vue.mixin({ beforeCreate: function () { var components = this.$options.components; for ( var componentName in components ) { if ( typeof(components[componentName]) === 'string' && components[componentName].substr(0, 4) === 'url:' ) { var comp = parseComponentURL(components[componentName].substr(4)); var componentURL = ('_baseURI' in this.$options) ? resolveURL(this.$options._baseURI, comp.url) : comp.url; if ( isNaN(componentName) ) components[componentName] = httpVueLoader.load(componentURL, componentName); else components[componentName] = Vue.component(comp.name, httpVueLoader.load(componentURL, comp.name)); } } } }); }; httpVueLoader.require = function(moduleName) { return window[moduleName]; }; httpVueLoader.httpRequest = function(url) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.responseType = 'text'; xhr.onreadystatechange = function() { if ( xhr.readyState === 4 ) { if ( xhr.status >= 200 && xhr.status < 300 ) resolve(xhr.responseText); else reject(xhr.status); } }; xhr.send(null); }); }; httpVueLoader.langProcessor = { html: identity, js: identity, css: identity }; httpVueLoader.scriptExportsHandler = identity; function httpVueLoader(url, name) { var comp = parseComponentURL(url); return httpVueLoader.load(comp.url, name); } return httpVueLoader; });
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue開(kāi)發(fā)中遇到的問(wèn)題總結(jié)
在本篇文章里小編給大家分享的是關(guān)于vue開(kāi)發(fā)中遇到的問(wèn)題總結(jié),有興趣的朋友們可以學(xué)習(xí)參考下。2020-04-04Vue項(xiàng)目中使用jsonp抓取跨域數(shù)據(jù)的方法
這篇文章主要介紹了Vue項(xiàng)目中使用jsonp抓取跨域數(shù)據(jù)的方法,本文通過(guò)實(shí)例代碼講解的非常詳細(xì),需要的朋友可以參考下2019-11-11vue項(xiàng)目拍照或上傳圖片并實(shí)現(xiàn)轉(zhuǎn)化為base64格式
這篇文章主要介紹了vue項(xiàng)目拍照或上傳圖片并實(shí)現(xiàn)轉(zhuǎn)化為base64格式方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11Vue組件庫(kù)Element-常見(jiàn)組件表格示例代碼
對(duì)于Element組件的使用,最主要的就是明確自己想要達(dá)到的效果,從官網(wǎng)中將對(duì)應(yīng)代碼復(fù)制粘貼即可,最重要的是要讀懂不同組件官網(wǎng)中提供的文檔,以便實(shí)現(xiàn)自己想要的效果,本文給大家介紹Vue組件庫(kù)Element-常見(jiàn)組件表格,感興趣的朋友一起看看吧2023-10-10Vuejs2 + Webpack框架里,模擬下載的實(shí)例講解
今天小編就為大家分享一篇Vuejs2 + Webpack框架里,模擬下載的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09Vue3進(jìn)階主題Composition API使用詳解
這篇文章主要為大家介紹了Vue3進(jìn)階主題Composition API使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Vue項(xiàng)目通過(guò)network的ip地址訪問(wèn)注意事項(xiàng)及說(shuō)明
這篇文章主要介紹了Vue項(xiàng)目通過(guò)network的ip地址訪問(wèn)注意事項(xiàng)及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09項(xiàng)目遷移vite引入圖片資源報(bào)require?is?not?defined問(wèn)題的解決辦法
這篇文章主要給大家介紹了關(guān)于項(xiàng)目遷移vite引入圖片資源報(bào)require?is?not?defined問(wèn)題的解決辦法,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vite具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-01-01Vue mixin實(shí)現(xiàn)組件功能復(fù)用示例詳解
這篇文章主要為大家介紹了Vue mixin實(shí)現(xiàn)組件功能復(fù)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10