問(wèn)題
成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比衡陽(yáng)縣網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式衡陽(yáng)縣網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋衡陽(yáng)縣地區(qū)。費(fèi)用合理售后完善,十余年實(shí)體公司更值得信賴。
在我們的 vue 項(xiàng)目中(特別是后臺(tái)系統(tǒng)),總會(huì)出現(xiàn)一些需要多業(yè)務(wù)線共同開(kāi)發(fā)同一個(gè)項(xiàng)目的場(chǎng)景,如果各業(yè)務(wù)團(tuán)隊(duì)向項(xiàng)目中提供一些公共業(yè)務(wù)組件,但是這些組件并不能和項(xiàng)目一起打包,因?yàn)轫?xiàng)目中不能因?yàn)槟硞€(gè)私有模塊的頻繁變更而重復(fù)構(gòu)建發(fā)布。
^_^不建議在生產(chǎn)環(huán)境使用,代碼包含eval
思路
在這種場(chǎng)景下我們需要將公共的業(yè)務(wù)組件部署到服務(wù)端,由客戶端請(qǐng)求并渲染組件。
服務(wù)端解析.vue文件
使用vue-template-compiler 模板解析器,解析SFC(單文件組件)
const compile = require('vue-template-compiler') // 獲取sfc組件的源碼 const str = fs.readFileSync(path.resolve(__dirname, `../components/sfc.vue`), 'utf-8') // vue-loader內(nèi)置,現(xiàn)在用來(lái)解析SFC(單文件組件) let sfc = compile.parseComponent(str) // 獲取sfc組件配置 let sfcOptions = getComponentOption(sfc)
getComponentOption 獲取sfc組件配置
import { uuid } from 'utilscore' import stylus from 'stylus' import sass from 'sass' import less from 'less' const getComponentOption = sfc => { // 生成data-u-id const componentId = uuid(8, 16).toLocaleLowerCase() // 標(biāo)簽添加data-u-id屬性 const template = sfc.template ? tagToUuid(sfc.template.content, componentId) : '' // 轉(zhuǎn)化style(less、sass、stylus) let styles = [] sfc.styles.forEach(sty => { switch (sty.lang) { case 'stylus': stylus.render(sty.content, (err, css) => styles.push(formatStyl(sty, css, componentId))) break; case 'sass': case 'scss': styles.push(formatStyl(sty, sass.renderSync({ data: sty.content }).css.toString(), componentId)) break; case 'less': less.render(sty.content, (err, css) => styles.push(formatStyl(sty, css, componentId))) break; } }) let options = { script: sfc.script ? $require(null, sfc.script.content) : {}, styles, template } return JSON.stringify(options, (k, v) => { if(typeof(v) === 'function') { let _fn = v.toString() return /^function()/.test(_fn) ? _fn : fn.replace(/^/,'function ') } return v }) }
tagToUuid 給template 中的標(biāo)簽追加data-u-id
const tagToUuid = (tpl, id) => { var pattern = /<[^\/]("[^"]*"|'[^']*'|[^'">])*>/g return tpl.replace(pattern, $1 => { return $1.replace(/<([\w\-]+)/i, ($2, $3) => `<${$3} data-u-${id}`) }) }
formatStyl 處理樣式的scoped
const formatStyl = (sty, css, componentId) => { let cssText = css if (sty.scoped) { cssText = css.replace(/[\.\w\>\s]+{/g, $1 => { if (/>>>/.test($1)) return $1.replace(/\s+>>>/, `[data-u-${componentId}]`) return $1.replace(/\s+{/g, $2 => `[data-u-${componentId}]${$2}`) }) } return cssText }
$require 執(zhí)行其中的的 JavaScript 代碼,并返回值
const $require = (filepath, scriptContext) => { const filename = path.resolve(__dirname, `../${filepath}`); const module = { exports: {} } let code = scriptContext ? scriptContext : fs.readFileSync(filename, 'utf-8') let exports = module.exports code = `(function($require,module,exports,__dirname,filename){$[code]})($require,module,exports,__dirname,filename)` eval(code) return module.exports }
客戶端請(qǐng)求組件并渲染
封裝前端遠(yuǎn)程組件-remote.vue
遠(yuǎn)程組件實(shí)踐
服務(wù)端sfc組件,注意javascript塊要使用module.exports導(dǎo)出,引入腳本使用$require
遠(yuǎn)程組件--{{msg}}--{{text}}
客戶端渲染
// temolate// script methods:{ handleClick(v){ console.log(v) // 點(diǎn)我 } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。