zoukankan      html  css  js  c++  java
  • Vue学习(十三)模版引擎算是预处理器吗?

    前言

    今天在看vue-loader预处理器配置相关的内容,突然看到了Pug,然后有了一个疑问:模版引擎原来是预处理器吗?

    答案是:YES

    说明

    这里重点讨论使用不同的js模板引擎作为预处理器,

    下面示例使用了pug模板引擎

    <template lang="pug">
     div
     h1 Hello world!
    </template>

    1. 支持哪些模板引擎

    v14 或更低版本使用 consolidate 来编译 <template lang="xxx">, 所以支持的模板引擎,从consolidate的支持列表中可以找到,包括了大部分引擎,

    vue-loader/preprocessor.js 文件里面

    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 进行预处理。

    v15 及以上版本,允许对vue组件中的每个部分使用其他的webpack loader,可以正常使用各种模板引擎。

    使用@vue/component-compiler-utils 工具编译模板,实际在component-compiler-utils中编译template时,也把consolidate作为预处理器,使用consolidate.render编译成字符串。

    2. 引入pug

    需安装pug-plain-loader,利用它返回一个编译好的 HTML 字符串,

    在最新的vue-cli@3.x 配置中,默认已配置好pug的相关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 里面手动配置loader, 配置规则跟引入pug类似,修改相关loader即可。

    还有一点比较特殊,该模板引擎对应的loader, 必须返回字符串,

    比如我们使用dotjs-loader,来解析dotjs模板,就会报错,然后查看dotjs-loader,发现

    return 'export default ' + doT.template(source);

    最后返回导出结果, doT.template(source)执行成功后,返回一个匿名函数,

    所以想要返回最终的字符串,只有传入数据,执行函数 doT.template(source)(data)。

    直接使用dotjs-loader无法达到上面的要求,只有修改loader中的返回格式,具体可以参考pug-plain-loader, 逻辑比较简单,传入模板引擎相关参数,options对应webpack 配置中的options参数,最后返回编译后的字符串。

            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 || {})
            }    

    这里可以发现问题,上面代码中options.data只是在webpack配置时传入的,并不是正式的下发数据,使用预处理模板引擎,为了返回字符串,编译函数执行在loader中进行,没有办法传入数据data,参与编译。

    而且模板引擎的相关语法,不能与vue 的模板语法冲突,这样会导致js模板引擎解析后,再进行vue 模板解析时报错

    如果只是纯静态页面,可以直接把需要经过模板引擎编译的内容部分抽离出去,使用require引入时,webpack会自动对应loader,解析完成后,只需在当前组件中传入data,通过v-html把生成的字符串当成HTML标签解析后输出。

    参考

    vue-loader中引入模板预处理器的实现

  • 相关阅读:
    事后诸葛亮
    OVS常用命令
    阿里云部署杂记
    Alpha冲刺总结
    测试随笔
    Alpha冲刺集合
    项目Alpha冲刺Day12
    项目Alpha冲刺Day11
    项目Alpha冲刺Day10
    MySQL修改密码
  • 原文地址:https://www.cnblogs.com/kunmomo/p/13526831.html
Copyright © 2011-2022 走看看