上一篇中已经把所有思路都理顺了,这边我们就开始具体编码吧。(如果您有更好的办法,欢迎留言讨论!互相学习!)
我们先来看一下最终完成的效果:
2.1 安装 express-hbs
npm i express-hbs
2.2 在app.js中更换模板引擎,并指定母版页位置 如图:
至此,我们的模板引擎更换完毕,你会发现,在Views文件加下的所有文件,都是以*.hbs结尾的,如果新加文件,请保持后缀一致。
2.3 刚才已经配置好了母版页的位置,就是 “/views/layout” ,现在我们去看看这个母版页里面的内容吧;如下图
2.4 现在来介绍下母版页,这个母版页是AdminLTE中的精简版,我把多余的部分全部删除。
从图中可以看出,模板分为四个部分: header(头部)、 aside(侧边栏)、 content(中间内容) 和 footer(底部)
其中我们注意到,在中间内容部分,有一个 {{{body}}} 这种写法的意思就是:每次访问具体页面时,会将具体页面替换掉{{{body}}}部分的内容;
例如:我们想访问主页,主页是 views/index.hbs,我们来看看其中的内容:
是的,主页里就只有这些代码,当进行访问主页路由的时候,也就是 localhost:3000时,hbs会将整个div自动替换 {{{body}}}
我们所看到的就会如下:这极大的方便了我们对模板的应用。
到目前,我们所有的视图都具备模板了,而且母版页是单独存放的;下面我们来解决无刷新问题;
首先,我们编写一个公共的js方法,放在 Base.js中,这个方法有两个作用
1:将侧边栏所有的页面切换请求,通过Ajax发送出去,并得到一个html 页面,将中间部分进行填充;
2:成功填充页面后,将当期请求的url更新到地址栏,以便于用户刷新操作;
看一下这个方法:
var ChangePage = function (url) {
$.ajax({
type: 'GET',
url: url,
data: { c_type: 'page' },
success: function (res) {
$("#main_container").html(res);
var stateObject = {};
var title = "Wow Title";
var newUrl = url;
history.pushState(stateObject, title, newUrl);
}
});
}
细心的朋友会发现一个问题,我在ajax请求的时候,给了一个参数:c_type
别忘记了,这里还有一个非常严重的问题没有解决,那就是 通过页面侧边栏发起的页面跳转,我们希望返回的是不带模板页的分布视图!
这里的参数 c_type 就是为了便于后续的区分处理
4.1 来看一下路由渲染页面是如何进行操作的(为了方便,我把所有页面的跳转都写到了index.js路由中,不要像我学习啊,我实在是太懒了)
router.get('/', function(req, res, next) {
var pageData = {};
if(req.query.c_type=='page')
{
pageData.layout='';
}
res.render('index', pageData);
});
首先我们定义了一个对象:pageData,他用来向页面传递数据;
这里当我们发现前端请求的参数里包含一个叫 c_type 的参数,并且值为 page 那么我们就认为他是从页面侧边栏发起的请求
这个时候,我们关键性的一句来了:pageData.layout=''; 这一句的意思就是不使用模板,返回局部视图,从而实现了无刷新;
4.2 但是这样的操作太过繁琐,我们岂不是每个路由都需要添加一个类似的判断?太麻烦了吧?于是我们想到了 中间件 ,它可以把每个请求都过滤一下;
我们来看一下中间件的写法:
//拦截器,必须放在静态资源声明之后、路由导航之前
app.use(function (req, res, next) {
var url = req.query.c_type;
global.pageData = {
data:{}
}
if (url == "page") {
global.pageData.layout='';
}
console.log(global.pageData)
next();
});
这里我们把每个请求都就进行拦截,如果发现请求中带有 c_type参数,那么我们就定义一个全局对象:global.pageData
并给 pageData.layout 赋值为空;
在每个路由中,我们只需要引用下这个全局变量,就可以实现模板的自由控制:改良后的路由如下:
router.get('/', function(req, res, next) {
res.render('index', global.pageData);
});
是不是瞬间少了好多代码!
如果你有一些自定义的数据,就可以放到global.pageData中,这里不作过多解释;
到目前,你已经完成了大部分的操作,页面实现了无刷新加载!
侧边栏的样式完全是AdminLTE中的原始样式,这里你需要稍微观察一下,如果需要添加更多的侧边栏,只需要按照其规则就可以
关于样式保留,这里我们不过多的介绍,下面是完整方法:在 Base.js中
$(".treeview a").click(function () {
var item = $(this).parent().parent().parent('.treeview');
var idStr = $(item).attr('id');
if (idStr != undefined) {
localStorage.setItem("c_slider", idStr);
}else
{
localStorage.setItem("c_slider", '');
}
})
$(function () {
var c_slider = localStorage.c_slider
if (c_slider != undefined) {
$("#" + c_slider).addClass("menu-open");
$("#" + c_slider + ' ul').css('display', 'block');
}
})
六:完整Demo下载:
https://download.csdn.net/download/tomato2313/10937611(可能还在审核中)