vue-loader中引入模板预处理器的实现
vue-loader是一个webpack的loader,可以将指定格式编写的Vue组件转换为JavaScript模块
同时,vue-loader支持使用非默认语言,通过设置语言块的lang属性,就可以使用指定的预处理器,比如最常见的sass语法:
...
这里重点讨论使用不同的js模板引擎作为预处理器,
下面示例使用了pug模板引擎
div h1Helloworld!
1.支持哪些模板引擎
v14或更低版本使用consolidate来编译
在vue-loader/preprocessor.js文件里面,
//loaderforpre-processingtemplateswithe.g.pug constcons=require('consolidate') constloaderUtils=require('loader-utils') const{loadOptions}=require('../utils/options-cache') module.exports=function(content){ constcallback=this.async() constopt=loaderUtils.getOptions(this)||{} if(!cons[opt.engine]){ returncallback( newError( "Templateengine'"+ opt.engine+ "'"+ "isn'tavailableinConsolidate.js" ) ) } //allowpassingoptionstothetemplatepreprocessorvia`template`option constvueOptions=loadOptions(opt.optionsId) if(vueOptions.template){ Object.assign(opt,vueOptions.template) } //forrelativeincludes opt.filename=this.resourcePath cons[opt.engine].render(content,opt,(err,html)=>{ if(err){ returncallback(err) } callback(null,html) }) }
可以看到,使用consolidate进行预处理。
v15及以上版本,允许对vue组件中的每个部分使用其他的webpackloader,可以正常使用各种模板引擎。
使用@vue/component-compiler-utils工具编译模板,实际在component-compiler-utils中编译template时,也把consolidate作为预处理器,使用consolidate.render编译成字符串。
2.引入pug
需安装pug-plain-loader,利用它返回一个编译好的HTML字符串,
在最新的vue-cli@3.x配置中,默认已配置好pug的相关loader,所以安装完可以直接在中使用,
/*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里面手动配置loader,配置规则跟引入pug类似,修改相关loader即可。
还有一点比较特殊,该模板引擎对应的loader,必须返回字符串,
比如我们使用dotjs-loader,来解析dotjs模板,就会报错,然后查看dotjs-loader,发现
return'exportdefault'+doT.template(source);
最后返回导出结果,doT.template(source)执行成功后,返回一个匿名函数,
所以想要返回最终的字符串,只有传入数据,执行函数doT.template(source)(data)。
直接使用dotjs-loader无法达到上面的要求,只有修改loader中的返回格式,具体可以参考pug-plain-loader,逻辑比较简单,传入模板引擎相关参数,options对应webpack配置中的options参数,最后返回编译后的字符串。
constpug=require('pug') constloaderUtils=require('loader-utils') module.exports=function(source){ constoptions=Object.assign({ filename:this.resourcePath, doctype:'html', compileDebug:this.debug||false },loaderUtils.getOptions(this)) consttemplate=pug.compile(source,options) template.dependencies.forEach(this.addDependency) returntemplate(options.data||{}) }
这里可以发现问题,上面代码中options.data只是在webpack配置时传入的,并不是正式的下发数据,使用预处理模板引擎,为了返回字符串,编译函数执行在loader中进行,没有办法传入数据data,参与编译。
而且模板引擎的相关语法,不能与vue的模板语法冲突,这样会导致js模板引擎解析后,再进行vue模板解析时报错
如果只是纯静态页面,可以直接把需要经过模板引擎编译的内容部分抽离出去,使用require引入时,webpack会自动对应loader,解析完成后,只需在当前组件中传入data,通过v-html把生成的字符串当成HTML标签解析后输出。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。