vue-loader 是一個(gè) webpack 的 loader,可以將指定格式編寫的 Vue 組件轉(zhuǎn)換為 JavaScript模塊
同時(shí),vue-loader 支持使用非默認(rèn)語言,通過設(shè)置語言塊的lang屬性,就可以使用指定的預(yù)處理器,比如最常見的sass 語法:
<style lang="sass"> ... </style>
這里重點(diǎn)討論使用不同的js模板引擎作為預(yù)處理器,
下面示例使用了pug模板引擎
<template lang="pug"> div h1 Hello world! </template>
1. 支持哪些模板引擎
v14 或更低版本使用 consolidate 來編譯 <template lang="xxx">, 所以支持的模板引擎,從consolidate的支持列表中可以找到,包括了大部分引擎,
在vue-loader/preprocessor.js 文件里面,
// loader for pre-processing templates with e.g. pug const cons = require('consolidate') const loaderUtils = require('loader-utils') const { loadOptions } = require('../utils/options-cache') module.exports = function (content) { const callback = this.async() const opt = loaderUtils.getOptions(this) || {} if (!cons[opt.engine]) { return callback( new Error( "Template engine '" + opt.engine + "' " + "isn't available in Consolidate.js" ) ) } // allow passing options to the template preprocessor via `template` option const vueOptions = loadOptions(opt.optionsId) if (vueOptions.template) { Object.assign(opt, vueOptions.template) } // for relative includes opt.filename = this.resourcePath cons[opt.engine].render(content, opt, (err, html) => { if (err) { return callback(err) } callback(null, html) }) }
可以看到,使用consolidate 進(jìn)行預(yù)處理。
v15 及以上版本,允許對(duì)vue組件中的每個(gè)部分使用其他的webpack loader,可以正常使用各種模板引擎。
使用@vue/component-compiler-utils 工具編譯模板,實(shí)際在component-compiler-utils中編譯template時(shí),也把consolidate作為預(yù)處理器,使用consolidate.render編譯成字符串。
2. 引入pug
需安裝pug-plain-loader,利用它返回一個(gè)編譯好的 HTML 字符串,
在最新的vue-cli@3.x 配置中,默認(rèn)已配置好pug的相關(guān)loader, 所以安裝完可以直接在<template/>中使用,
/* config.module.rule('pug') */ { test: /\.pug$/, oneOf: [ /* config.module.rule('pug').oneOf('pug-vue') */ { resourceQuery: /vue/, use: [ /* config.module.rule('pug').oneOf('pug-vue').use('pug-plain-loader') */ { loader: 'pug-plain-loader' } ] }, /* config.module.rule('pug').oneOf('pug-template') */ { use: [ /* config.module.rule('pug').oneOf('pug-template').use('raw') */ { loader: 'raw-loader' }, /* config.module.rule('pug').oneOf('pug-template').use('pug-plain') */ { loader: 'pug-plain-loader' } ] } ] },
3. 引入dotjs或其他模板引擎,
需在vue.confg.js 里面手動(dòng)配置loader, 配置規(guī)則跟引入pug類似,修改相關(guān)loader即可。
還有一點(diǎn)比較特殊,該模板引擎對(duì)應(yīng)的loader, 必須返回字符串,
比如我們使用dotjs-loader,來解析dotjs模板,就會(huì)報(bào)錯(cuò),然后查看dotjs-loader,發(fā)現(xiàn)
return 'export default ' + doT.template(source);
最后返回導(dǎo)出結(jié)果, doT.template(source)執(zhí)行成功后,返回一個(gè)匿名函數(shù),
所以想要返回最終的字符串,只有傳入數(shù)據(jù),執(zhí)行函數(shù) doT.template(source)(data)。
直接使用dotjs-loader無法達(dá)到上面的要求,只有修改loader中的返回格式,具體可以參考pug-plain-loader, 邏輯比較簡(jiǎn)單,傳入模板引擎相關(guān)參數(shù),options對(duì)應(yīng)webpack 配置中的options參數(shù),最后返回編譯后的字符串。
const pug = require('pug') const loaderUtils = require('loader-utils') module.exports = function (source) { const options = Object.assign({ filename: this.resourcePath, doctype: 'html', compileDebug: this.debug || false }, loaderUtils.getOptions(this)) const template = pug.compile(source, options) template.dependencies.forEach(this.addDependency) return template(options.data || {}) }
這里可以發(fā)現(xiàn)問題,上面代碼中options.data只是在webpack配置時(shí)傳入的,并不是正式的下發(fā)數(shù)據(jù),使用預(yù)處理模板引擎,為了返回字符串,編譯函數(shù)執(zhí)行在loader中進(jìn)行,沒有辦法傳入數(shù)據(jù)data,參與編譯。
而且模板引擎的相關(guān)語法,不能與vue 的模板語法沖突,這樣會(huì)導(dǎo)致js模板引擎解析后,再進(jìn)行vue 模板解析時(shí)報(bào)錯(cuò)
如果只是純靜態(tài)頁面,可以直接把需要經(jīng)過模板引擎編譯的內(nèi)容部分抽離出去,使用require引入時(shí),webpack會(huì)自動(dòng)對(duì)應(yīng)loader,解析完成后,只需在當(dāng)前組件中傳入data,通過v-html把生成的字符串當(dāng)成HTML標(biāo)簽解析后輸出。
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com