前后端分离之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: [
new HtmlWebpackPlugin(
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可以直接获取到传过来的值,获取方法如下:
<!-- index.ejs --> <!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<header style="text-align:center;color:#fff;font-size:20px;background:#333;">
this is header.
</header> <%= htmlWebpackPlugin.options._html %> <section id="app"></section> <footer style="text-align:center;color:#fff;font-size:20px;background:#333;">
this is footer.
</footer>
<script src="./dist/build.js"></script>
</body>
</html>
<%= %> 用来引入变量
<% %> 用来执行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: [
new HtmlWebpackPlugin({
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
代码如下:
/***** 生成组合后的html *****/ var pages = getEntry('./html/src/**/*.ejs')
for (var pathname in pages) {
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 in module.exports.entry) {
conf.chunks = [pathname, 'vendors', 'manifest']
} module.exports.plugins.push(new htmlWebpackPlugin(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 // 比如说页面名称,会在<title>或面包屑里用到 //console.log('pf.pageTitle'+pf.pageTitle) return this
},
/* 整合各公共组件和页面实际内容,最后生成完整的HTML文档 */
run(content) {
const renderData = {
header: header(),
footer: footer(),
topNav: topNav(pf),
sideMenu: sideMenu(),
content: content,
}
return layout(renderData)
},
} module.exports = moduleExports
layout.ejs 为终极模板,引入各个公共模块变量
<!-- html/layout/layout.ejs --> <!DOCTYPE html>
<html>
<head>
<title>vue</title>
</head>
<body> <%= header %>
<div id="wrapper">
<%= topNav %>
<%= sideMenu %>
<%= content %>
</div>
<%= footer %>
</body>
</html>
OK,到这里我们基本可以完成功能了,对每个新页面我们只需要关注这个页面的body部分,以及一个页面控制器 js 即可。无需在页面引入 css 和 js ,html-webpack-plugin会自动根据模板命名找到对应的js文件引入到html中,而css就只需要在相应的js文件中引入即可。
前后端分离的html拼接也就完成了。
目录结构参考:
源码:https://github.com/saysmy/vue2-webpack2-demo
如有错误请指正,有更好的构建方式期待留言交流
转载请注明出处 https://i.cnblogs.com/EditPosts.aspx?postid=6700040
前后端分离之vue2.0+webpack2 实战项目 -- html模板拼接的更多相关文章
- 前后端分离之vue2.0+webpack2 实战项目 -- webpack介绍
webpack的一点介绍 Webpack 把任何一个文件都看成一个模块,模块间可以互相依赖(require or import),webpack 的功能是把相互依赖的文件打包在一起.webpack 本 ...
- 鲜衣怒马散尽千金,Vue3.0+Tornado6前后端分离集成Web3.0之Metamask钱包区块链虚拟货币三方支付功能
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_219 不得不承认,大多数人并不拥有或者曾经拥有加密货币.是的,Web3.0.加密货币.区块链,对于大多数的互联网用户来说,其实是一 ...
- 区块相隔虽一线,俱在支付同冶熔,Vue3.0+Tornado6前后端分离集成Web3.0之Metamask区块链虚拟三方支付功能
最近几年区块链技术的使用外延持续扩展,去中心化的节点认证机制可以大幅度改进传统的支付结算模式的经营效率,降低交易者的成本并提高收益.但不能否认的是,区块链技术也存在着极大的风险,所谓身怀利器,杀心自起 ...
- SpringBoot电商项目实战 — 前后端分离后的优雅部署及Nginx部署实现
在如今的SpringBoot微服务项目中,前后端分离已成为业界标准使用方式,通过使用nginx等代理方式有效的进行解耦,并且前后端分离会为以后的大型分布式架构.弹性计算架构.微服务架构.多端化服务(多 ...
- FastAPI + Vue 前后端分离 接口自动化测试工具 apiAutoTestWeb
apiAutoTestWeb使用说明 apiAutoTestWeb是为apiAutoTest的可视化版本,其采用前后端分离(FastAPI + Vue2)方式实现 具体使用: Python3 + Fa ...
- EF+jQueryUI前后端分离设计
开源项目练习EF+jQueryUI前后端分离设计 最近大家流行把项目开源,我也来玩玩.只是开源公司项目不好,小弟只好从公司项目经验上另外弄出一套练习开源给大家. 这个项目可以做简单的团队任务系统( ...
- SSM框架中的前后端分离
认识前后端分离 在传统的web应用开发中,大多数的程序员会将浏览器作为前后端的分界线.将浏览器中为用户进行页面展示的部分称之为前端,而将运行在服务器,为前端提供业务逻辑和数据准备的所有代码统称为后端. ...
- 《论vue在前后端分离项目中的实践之年终总结》
我是2014年的时候开始了解知道的vue,当时vue还不太成熟,想用但是又怕自己hold不住,况且那时候vue还没有成熟的(路由.验证.ui组件)插件,社区也是不温不火的,再说也没有合适的机遇让我去项 ...
- 前后端分离(手) -- mock.js
前言: 本篇博文昨天七夕写的,一天下来被虐得体无完肤,苦逼的单身狗只能学习,对!我爱学习,关掉朋友圈,并写了一篇博文发泄发泄.这次写mock.js的使用,能使前后端分离,分离,分离,重要的是说三遍. ...
随机推荐
- HDU - 1166 - 敌兵布阵 线段树的单点修改,区间求和
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> ...
- Python-类的封装
1:封装数据 将数据隐藏起来这不是目的.隐藏起来然后对外提供操作该数据的接口,然后我们可以在接口附加上对该数据操作的限制,以此完成对数据属性操作的严格控制. class Teacher: def __ ...
- php 简单的学习GD库绘制图片并传回给前端实现方式
1.基本的GD库绘制图片汇总 2.后台实现小案例 <?php // $img = imagecreatetruecolor(200,40); // var_dump($img); // 利用GD ...
- 使用publisher模式控制频繁的UI输出,避免Winform界面假死
http://www.cnblogs.com/Charltsing/p/publisher.html 最近测试task并发任务的效率与线程池的区别,发现了另外一个问题.task建立任务的速度很快,输出 ...
- abaqus安装破解
软件安装包 链接:http://pan.baidu.com/s/1pL4oxfX 密码:on1g 破解网页视频链接https://v.youku.com/v_show/id_XMTg4ODM5NjY5 ...
- final域的内存语义
final 一.final的基本语义 final关键字可以用来修饰类.方法和变量(包括成员变量和局部变量) 当用final修饰一个类时,表明这个类不能被继承. 当用final修饰一个方法时,表明这个方 ...
- Composer安装与使用
Composer是PHP中用来管理依赖(dependency)关系的工具.你可以在自己的项目中声明所依赖的外部工具库(libraries),Composer会帮你安装这些依赖的库文件. Windows ...
- 设置SQLServer数据库内存
需要设置SQLServer数据库的内存配置.登录数据库,这里使用的是SQLServer2008,右键点击最上方的服务器名,在弹出的菜单中,点击属性] 打开服务器属性窗口.默认显示的是第一项[常规]内容 ...
- windows环境下protobuf的java操作{编译,序列化,反序列化}
google protocol buffer的使用和原理 概况: Protocol Buffers(也就是protobuf)是谷歌的语言中立的.平台中立的.可扩展的用于序列化结构化的数据: windo ...
- Saltstack 安装与常用模块
一.介绍 saltstack是基于C/S服务模式,在该架构中,服务器端叫做Master,客户端叫做Minion.传统的C/S模式我们这样理解,客户端发送请求给服务器端,服务器端接受到来自客户端的请求并 ...