vue webpack 网页标题_前后端分离之vue2.0+webpack2 实战项目 -- html模板拼接

对于前后端分离,如何把一个页面的公共部分比如head, header, footer, content等组合成一个完整的html 是一个值得考虑的地方。

对于php,我们可以利用include加载其他页面,像yii框架,可以利用render将输出的内容嵌入到父模板,从而形成一个完整的页面。

那对于纯静态的html我们如何拼接呢?

可以想到市面上的多种模板引擎,比如artTemplate, doT, ejs等,他们可以使用require或include等特殊标记的语法来引入其他模块。但如果每个页面我们都去写若干个require,比如:

require('head.html')

require('header.html')

...

require('side-bar.html')

require('footer.html')

是不是略显麻烦?另外head内的title如何自定义?对于要求head内根据不同页面有不同引用的icon或者css甚至js,该如何配置呢?

这时我们就想着去寻找一套自动化的拼接和可配置的灵活方案,html-webpack-plugin 就可以帮我们完成这些。

var HtmlWebpackPlugin = require('html-webpack-plugin');var webpackConfig ={

entry:'index.js',

output: {

path:'dist',

filename:'bundle.js'},

plugins: [newHtmlWebpackPlugin(

title:'this is mytitle a',

_html:'this is content a.',

filename:'index.html',

template:'index.ejs',

)

],

};

html-webpack-plugin的基本使用方法如上,它可以把模板template index.ejs转化成html,命名为index.html,并把bundle.js引入index.html。

html-webpack-plugin默认集成了ejs模板引擎,所以我们可以直接使用ejs模板。当然我们也可以引入其他模板,包括handlebars等都可以使用。

title,  _html为自定义的一些属性,你还可以增加比如content, data等等你想要的数据传到模板。传到模板后,ejs可以直接获取到传过来的值,获取方法如下:

this is header.

this is footer.

 用来引入变量

 用来执行js判断语句

这样我们就可以自定义一些内容输入到模板页面中,但我们如果有很多个模板,如何挨个生成呢?

官网给出的解决方案就是有几个模板就声明几次插件:

plugins: [

new HtmlWebpackPlugin(

title: 'this is mytitle a',

_html: 'this is content a.',

filename: 'index_a.html',

template: 'index_a.ejs',

),

new HtmlWebpackPlugin(

title: 'this is mytitle b',

_html: 'this is content b.',

filename: 'index_b.html',

template: 'index_b.ejs',

),

new HtmlWebpackPlugin(

title: 'this is mytitle c',

_html: 'this is content c.',

filename: 'index_c.html',

template: 'index_c.ejs',

)

],

多个模板的问题解决了,但对于每个模板内部,如何抽离出公共部分(head等),我们每次写页面只关注内容部分呢?

正式构建模板布局框架

既然html-webpack-plugin的template可以接受多个模板,那我们也可以传给它一个js,只要js返回一个模板文件就可以,这样我们拼接的工作都可以用js和ejs完成。

在此之前我们说下html-webpack-plugin的 chunks 属性

{

entry: {

a:'./a.js',

b:'./b.js',

c:'./c.js'},

output: {

path:'dist',

filename:'js/[name].js'},

plugins: [newHtmlWebpackPlugin({

title:'My App',

filename:'assets/admin.html',

chunks: ['a','b']

})

]

}

chunks: 规定需要引入的模块。在这里例子中,只有a和b被插入到html中,c并不会被引入。

ok,接下来我们就可以针对不同的模板指定引入不同的js了。

先看下流程(如下示意图),假如现在要做income.html页面,我们只关注income.ejs,它是body中的内容部分,html-webpack-plugin 的 template 为 html/income.js,它会把我们的页面内容 income.ejs 传给 html/layout.js,在 layout.js 内,我们会引入html的各个公共部分,并把html/income.js 中定义的各种参数传给页面的各个部分,然后把这些公共部分传给 html/layout.ejs 组合并返回。html-webpack-plugin 就把返回的完整的模板转化为 目标html

14a2287f040874ef41d5b892ed64309d.png

代码如下:

/***** 生成组合后的html *****/

var pages = getEntry('./html/src/**/*.ejs')for (var pathname inpages) {var conf ={

filename: path.resolve(__dirname,'./html/dist/' + pathname + '.html'), //html文件输出路径

template: path.resolve(__dirname, './html/src/' + pathname + '/' + pathname + '.js'), //模板路径

inject: true,

cache:true, //只改动变动的文件

minify: {

removeComments:true,

collapseWhitespace:false}

}if (pathname inmodule.exports.entry) {

conf.chunks= [pathname, 'vendors', 'manifest']

}

module.exports.plugins.push(newhtmlWebpackPlugin(conf))

}

inject: ture/body 将js引用插入到body内,head将js引用插入到head内,false为不插入

cache:是否值编译改动的文件

minify: 压缩html

removeComments: 去除注释

collapseWhitespace: 去除空格

chunks: 自动引入公共模块 js 以及 当前 pathname 对应的 js 文件

template: 为入口js文件对应的用于拼接模板的js

这个js就有点像php的controller,可以定义当前页面的title等信息,并规定使用哪个ejs模板进行拼接

/* html/income/income.js*/const content= require('./income.ejs') //使用income.ejs模板进行拼接

const layout = require('../layouts/layout.js')

const pageTitle= '消息通知' //自定义页面title并传给 layoutjs 分发给页面的公共模块

module.exports= layout.init(pageTitle).run(content({ pageTitle }))

layout.js则引入各个公共模块,给他们传入需要的参数,并返回layout.ejs拼接后的结果

/*html/layout/layout.js*/const layout= require('./layout.ejs')

const header= require( './header.ejs') //页头的模板

const footer = require('./footer.ejs') //页脚的模板

const topNav = require('./top-nav.ejs') //顶部栏的模板

const sideMenu = require('./side-menu.ejs') //侧边栏的模板

/*整理渲染公共部分所用到的模板变量*/const pf={

pageTitle:''}

const moduleExports={/*处理各个页面传入而又需要在公共区域用到的参数*/init(pageTitle) {

pf.pageTitle= pageTitle //比如说页面名称,会在

或面包屑里用到

//console.log('pf.pageTitle'+pf.pageTitle)

return this},/*整合各公共组件和页面实际内容,最后生成完整的HTML文档*/run(content) {

const renderData={

header: header(),

footer: footer(),

topNav: topNav(pf),

sideMenu: sideMenu(),

content: content,

}returnlayout(renderData)

},

}

module.exports= moduleExports

layout.ejs 为终极模板,引入各个公共模块变量

vue
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值