Webpack生成企业站静态页面 - 组件化

一些项目因需求不同,如需SEO或小项目,使用angular、react或vue就大材小用了。我们可以通过webpack、gulp这些构建工具,也能快速完成html页面开发,并且也能使用less/sass/styus等样式预编译功能,以及将js、html分模块、分组件进行开发。

上一篇已经讲了webpack搭建项目环境,这里就直接使用上篇搭建的环境进行开发,地址:Webpack生成企业站静态页面 - 项目搭建-CSDN博客

这篇我们就一讲下如下将这样一个企业站,在webpack中快速构建。

一、插件安装

需要将html文件分组件化,并能动态渲染每个页面数据,还需要安装一个插件,art-template模板引擎在很多构建工具中都能使用到,下面我们来安装下:

javascript 复制代码
npm i -D art-template

art-template 是一个简约、超快的模板引擎。其官方地址:art-template

二、使用模板引擎

在网上也看到其他博主,使用封装art-template的插件,这边测试感觉效果不太好。刚好html-loader提供了对外回调功能,而且直接使用art-template发现效果更好。

在上一篇中讲到html中,html-loader其options中有preprocessor回调函数,可以在html-loader处理html内容之前,重新更新html的内容部分,配置信息如下:

名称 类型 默认值 默认值
sources {Boolean|Object} true 启用/禁用 sources 处理
preprocessor {Function} undefined 允许在处理前对内容进行预处理
minimize {Boolean|Object} 在生产模式下为 true,其他情况为 false 通知 html-loader 压缩 HTML
esModule {Boolean} true 通知 html-loader 压缩 HTML

2.1 创建公共数据文件

在进行模板渲染时,html页面中需要动态渲染的数据,需要通过一个json文件保存进行,以供art-template渲染时调用,这里在island目录中创建html.data.json文件,代码如下:

javascript 复制代码
{
    "indexData": {
        "title": "首页"
    },
    "listData": {
        "title": "列表页"
    },
    "articleData": {
        "title": "列表-详情页"
    },
    "contactData": {
        "title": "联系我们"
    },
    "messageData": {
        "title": "留言页"
    }
}

文件位置如下图:

2.2 json和art-template的引用

在webpack.config.js中引入art-template,并在preprocessor回调函数中使用art-template渲染html内容;在渲染前,还需要将html.data.json文件引入,命名为htmlData。

在art-template引入后,首先要配置一下art-template读取模板目录位置,否则在进行渲染时,会报找不到模板位置错误。

webpack.config.js 文件代码如下:

javascript 复制代码
const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const artTemplate = require('art-template');
const { entrys, staticHtmls } = require('./static.config');
const htmlData = require('./html.data.json');

// 指定art-template模板路径
artTemplate.defaults.root = resolve(__dirname, './src');
// 指定模板名称
artTemplate.defaults.extname = '.html';

module.exports = {
    entry: {
        jquery: ['jquery'],
        ...entrys()
    },
    output: {
        filename: 'js/[name].bundle.js',      // 对入口名称进行命名,
        clean: true                           // 在生成文件之前清空 output 目录
    },
    module: {
        rules: [
            // MiniCssExtractPlugin.loader 提取CSS为独立文件
            // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
            {
                test: /\.css$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
            // webpack 将 Less 编译为 CSS 的 loader。
            {
                test: /\.less$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            },
            // 匹配图片资源,指定构建后存储位置和命名
            {
                test: /\.(png|jpg|jpeg|svg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[name].[ext]'
                }
            }, 
            // 匹配html页面,并提取内部资源文件
            {
                test: /\.html$/i,
                loader: "html-loader",
                exclude: /node_modules/,
                options: {
                    minimize: false,        // 不压缩html内容
                    preprocessor: (content, loaderContext) => {
                        return artTemplate.compile(content)(htmlData);
                    }
                }
            },
            // 将jquery暴露给全局对象(self、window 和 global)
            {
                test: require.resolve('jquery'),
                loader: "expose-loader",
                options: {
                    exposes: ["$", "jQuery"]
                }
            }
        ]
    },
    plugins: [
        ...staticHtmls(),
        // 提取css文件
        new MiniCssExtractPlugin({
            filename: 'css/[name]_bundle.css',      //输出文件
        })
    ],
    resolve: {
        alias: {
            // 样式路径目录别名
            $css: resolve(__dirname, 'src/css')
        }
    },
    mode: 'production',
    devServer: {
        static: {
            // 指定服务运行目录
            directory: resolve(__dirname, 'dist')
        },
        compress: true,     //gzip压缩
        port: 3000,         //指定端口号
        open: true,         //服务启动后自动在浏览器打开
        hot: true           //开启热更
    }
}

2.3 创建公共文件

做过前端开发的朋友会知道,页面中很多代码是公用的,这部分如果每个页面再重复写,则会大大增加后期维护成本。这里将html中head部分、导航和底部内容提取出来,放在src下template目录中,如下图:

三、企业站搭建

3.1 编写公共内容

layout.html是用于存储页面整体框架部分,如html、head、body部分,以及head中引入公共资源等内容,代码如下:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 渲染头部资源 -->
    <block 'head'></block>
    <!-- 渲染当前页面标题 -->
    <title>望玉岛 - {{block 'title'}}{{/block}}</title>
</head>
<body>
    <!-- 引入导航HTML部分 -->
    {{include './header.html'}}
    <!-- 渲染内容部分 -->
    {{block 'content'}}{{/block}}
    <!-- 引入底部HTML部分 -->
    {{include './footer.html'}}
</body>
</html>

header.html是用于存储公共头部内容,如导航部分,代码如下:

html 复制代码
<!-- header_wrapper -->
<div id="header_wrapper">
	<!-- 导航 START -->
    <div class="navigation">
    	<div class="navi_middle">
            <ul>
                <li class="curhover"><a href="#">首页<span>HOME</span></a></li>
                <li><a href="#">新闻动态<span>NEWS</span></a></li>
                <li><a href="#">旅游项目<span>PROJEC</span></a></li>
                <li><a href="#">服务项目<span>SERVICES</span></a></li>
                <li><a href="#">公司产业<span>ENTERTAINMENT</span></a></li>
                <li><a href="#">农副产品<span>BY-PRODUCT</span></a></li>
                <li><a href="#">种植养殖<span>GRANCHIO</span></a></li>
                <li><a href="#">联系我们<span>CONTACT US</span></a></li>
            </ul>
            <div class="clear"></div>
        </div>
    </div>
    <!-- 导航 END -->
</div>
<!-- /header_wrapper -->

footer.html是用于存储页面底部公共部分代码,代码如下:

html 复制代码
<!-- footer_wrapper -->
<div id="footer_wrapper">
	<div id="footer">
    	<p>Copyright @ 2011-2012 <a href="#" target="_blank">XXXX度假村有限公司</a> 版权所有 All Right Reserved. 苏ICP备XXX号</p>
        <p>地址:XXXX 邮编:211300 电话:025-XXXXXXXX</p>
    </div>
</div>
<!-- /footer_wrapper -->

以上html独立出来文件中已使用art-template模板的语法,如对不熟悉,可以去其官网了解。

公共部分样式添加,这里就将其放入到common.less文件中,代码如下:

css 复制代码
*{ margin:0px; padding:0px; outline:0px;}
body{ font-size:12px; font-family:"微软雅黑"; font-size:14px;}
img{ border:0px;}
.clear{ clear:both;}
.fl{ float:left;}

/*导航*/
#header_wrapper{
    .navigation{ 
        background:url(../images/index_01.jpg) repeat-x;

        .navi_middle{ 
            width:1040px; height:64px; margin:0px auto;
        }

        ul{ 
            position:relative; height:53px; float:left;

            li{ 
                list-style:none; 
                padding:0px 10px; 
                text-align:center; 
                background:url(../images/index_02.gif) no-repeat center right; 
                float:left;

                a{ 
                    display:block; 
                    padding:10px 20px; 
                    text-decoration:none; 
                    font-size:16px; color:#FFF;

                    span{ display:block; font-size:12px;}
                    &:hover{ background:url(../images/index_03.jpg) repeat-x;}
                }

                &.curhover{
                    a{ background:url(../images/index_03.jpg) repeat-x;}
                }
            }
        }
    }
}

/*中间内容公共部分*/
#mainer_wrapper{
    .main-container{ width:1000px; margin:20px auto; }
}


/*页面脚样式*/
#footer_wrapper{ 
    background:#017e3a; 
    font-size:12px;

    .footer{ 
        width:1000px; 
        margin:0px auto; 
        color:#FFF; 
        line-height:30px; 
        text-align:center; 
        padding:20px 0px;

        a{ 
            text-decoration:none; color:#FFF;

            &:hover{ text-decoration:underline;}
        }
    }
}

本项目中使用的样式预编译插件是less,需要了解其语法和使用,可以去官网查看,地址:Less.js 中文网

3.2 首页公共部分

在3.1中已将项目中所需要公共部分独立出来,现在可以进行开发了。首先通过art-template中继承(extend)功能,将layout.html引入到index.html中,代码如下:

html 复制代码
{{ extend './template/layout.html' }}

此时执行webpack命令,则会生成带header.html和footer.html部分的HTML页面,如下图:

3.3 添加页面标题

在2.1中创建公共数据文件中,我们已经创建了html.data.json文件,并且在art-template渲染时将其传入。以art-template语法熟悉的朋友肯定知道,此时可以在页面中调到html.data.json中定义的数据。

另外,在创建layout.html时,也在里面给title留了一个坑位,只要在index.html将title数据添加上即可。

index.html代码如下:

html 复制代码
{{ extend './template/layout.html' }}

{{block 'title'}}{{indexData.title}}{{/block}}

此时执行webpack命令,dist目录中index.html的title部分则已有"首页"标题了,如上图:

由此类推,其他页面的公共部分引入和标题填充,就不用细讲了,标题内容也在html.data.json文件中都定义好了,直接在各自html页面中调用即可。

3.4 解决html热更问题

在开发首页内容里,细心朋友肯定已发现html代码修改后,页面并未更新。这个问题可以通过devServer中的watchFiles来解决,其可以用来监听指定文件,只要将需要监听的html文件路径放在watchFiles中即可。而html页面配置都在static.config.js中,所以我们在这里面稍作调用,再将数据指给watchFile,具体如下:

如上图,在static.config.js中定义获取所有html路径的函数,代码如下:

javascript 复制代码
// 监听热更html页面
watchHtmls: () => htmls.map(item => resolve(__dirname, `./src/${item.name}`))

然后将watchHtmls()引入到webpck.config.js中,并赋值给wathFiles,具体如上:

如上图,在webpack.config.js中添加watchFiles,代码如下:

javascript 复制代码
const { resolve } = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const artTemplate = require('art-template');
const { entrys, staticHtmls, watchHtmls } = require('./static.config');
const htmlData = require('./html.data.json');

// 略...

module.exports = {
    // 略...

    mode: 'production',
    devServer: {
        static: {
            // 指定服务运行目录
            directory: resolve(__dirname, 'dist')
        },
        watchFiles: [...watchHtmls()],
        compress: true,     //gzip压缩
        port: 3000,         //指定端口号
        open: true,         //服务启动后自动在浏览器打开
        hot: true           //开启热更
    }
}

此时关闭本地服务,重新运行npm webpack serve命令,再去修改index.html页面内容,则保存后页面就会自动更新了。

3.5 首页内容开发

html和css部分为前端开发基础知识,这里就不细进,直接贴代码了。

index.html中htlm部分代码如下:

html 复制代码
{{ extend './template/layout.html' }}

{{block 'title'}}{{indexData.title}}{{/block}}

{{block 'content'}}
<!-- mainer_wrapper -->
<div id="mainer_wrapper">
	<!-- main -->
	<div class="main-container">
        <div class="clear"></div>

        <!-- 广告 START -->
        <div class="box_gg">
        	<a href="#" target="_blank"><img src="images/index_08.jpg" alt="banner" /></a>
        </div>
        <!-- 广告 END -->
        
        <!-- box_content 最新活动 START -->
    	<div class="box_content wd490 fl">
        	<div class="title"><a href="#" class="more">MORE &gt;&gt;</a>最新活动</div>
            <div class="content">
				<dl class="b_list">
                	<dt>
                        <a href="#" target="_blank"><img src="images/index_09.jpg" alt="09" /></a>
                    </dt>
                    <dd>
                    	<h2><a href="#" target="_blank">望玉岛标题</a></h2>
                        <span>
                            望玉岛度假村一日游活动方案:活动主题,放飞心情,走进自然,活动地;望玉岛度假村,
                            行程特点;领略望玉岛... 
                            <a href="#" target="_blank">[详细情况]</a>
                        </span>
                    </dd>
                </dl>
                <dl class="b_list">
                	<dt>
                        <a href="#" target="_blank"><img src="images/index_10.jpg" alt="10" /></a>
                    </dt>
                    <dd>
                    	<h2><a href="#" target="_blank">望玉岛标题</a></h2>
                        <span>
                            望玉岛度假村一日游活动方案:活动主题,放飞心情,走进自然,活动地;望玉岛度假村,
                            行程特点;领略望玉岛... 
                            <a href="#" target="_blank">[详细情况]</a>
                        </span>
                    </dd>
                </dl>
                <dl class="b_list">
                	<dt>
                        <a href="#" target="_blank"><img src="images/index_11.jpg" alt="11" /></a>
                    </dt>
                    <dd>
                    	<h2><a href="#" target="_blank">望玉岛标题</a></h2>
                        <span>
                            望玉岛度假村一日游活动方案:活动主题,放飞心情,走进自然,活动地;望玉岛度假村,
                            行程特点;领略望玉岛... 
                            <a href="#" target="_blank">[详细情况]</a>
                        </span>
                    </dd>
                </dl>
                
                <div class="clear"></div>
            </div>
        </div>
        <!-- /box_content 最新活动 END -->
        
        <!-- box_content 旅游项目 START -->
    	<div class="box_content wd490 fl mg_l15">
        	<div class="title"><a href="#" class="more">MORE &gt;&gt;</a>旅游项目</div>
            <div class="content">
				<dl class="b_list">
                	<dt>
                        <a href="#" target="_blank"><img src="images/index_09.jpg" alt="09" /></a>
                    </dt>
                    <dd>
                    	<h2><a href="#" target="_blank">望玉岛标题</a></h2>
                        <span>
                            望玉岛度假村一日游活动方案:活动主题,放飞心情,走进自然,活动地;望玉岛度假村,
                            行程特点;领略望玉岛... 
                            <a href="#" target="_blank">[详细情况]</a>
                        </span>
                    </dd>
                </dl>
                <dl class="b_list">
                	<dt>
                        <a href="#" target="_blank"><img src="images/index_10.jpg" alt="10" /></a>
                    </dt>
                    <dd>
                    	<h2><a href="#" target="_blank">望玉岛标题</a></h2>
                        <span>
                            望玉岛度假村一日游活动方案:活动主题,放飞心情,走进自然,活动地;望玉岛度假村,
                            行程特点;领略望玉岛... 
                            <a href="#" target="_blank">[详细情况]</a>
                        </span>
                    </dd>
                </dl>
                <dl class="b_list">
                	<dt>
                        <a href="#" target="_blank"><img src="images/index_11.jpg" alt="11" /></a>
                    </dt>
                    <dd>
                    	<h2><a href="#" target="_blank">望玉岛标题</a></h2>
                        <span>
                            望玉岛度假村一日游活动方案:活动主题,放飞心情,走进自然,活动地;望玉岛度假村,
                            行程特点;领略望玉岛... 
                            <a href="#" target="_blank">[详细情况]</a>
                        </span>
                    </dd>
                </dl>
                
                <div class="clear"></div>
            </div>
        </div>
        <!-- /box_content 旅游项目 END -->
        
        <!-- box_content 旅游咨询 START -->
    	<div class="box_content fl" style="width:360px;">
        	<div class="title"><a href="#" class="more">MORE &gt;&gt;</a>旅游咨询</div>
            <div class="content">
				<ul class="box_list">
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">新春有礼------望玉岛别墅标间推出亲民价,餐饮</a>
                    </li>
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">新春有礼------望玉岛别墅标间推出亲民价,餐饮</a>
                    </li>
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">新春有礼------望玉岛别墅标间推出亲民价,餐饮</a>
                    </li>
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">新春有礼------望玉岛别墅标间推出亲民价,餐饮</a>
                    </li>
                </ul>
            </div>
        </div>
        <!-- /box_content 旅游咨询 END -->
        <!-- box_content 贵宾服务 START -->
    	<div class="box_content fl mg_l15" style="width:360px;">
        	<div class="title"><a href="#" class="more">MORE &gt;&gt;</a>贵宾服务</div>
            <div class="content">
				<ul class="box_list">
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">新春有礼------望玉岛别墅标间推出亲民价,餐饮</a>
                    </li>
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">新春有礼------望玉岛别墅标间推出亲民价,餐饮</a>
                    </li>
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">新春有礼------望玉岛别墅标间推出亲民价,餐饮</a>
                    </li>
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">新春有礼------望玉岛别墅标间推出亲民价,餐饮</a>
                    </li>
                </ul>
            </div>
        </div>
        <!-- /box_content 贵宾服务 END -->
        <!-- box_content 招聘信息 START -->
    	<div class="box_content fl mg_l15" style="width:240px;">
        	<div class="title"><a href="#" class="more">MORE &gt;&gt;</a>招聘信息</div>
            <div class="content">
				<ul class="box_list">
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">2015-03-17诚招</a>
                    </li>
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">2014-03-12招聘</a>
                    </li>
                    <li>
                        <span>2014-10-2</span>
                        <a href="#" target="_blank">2013-03-30诚招学生暑期工</a>
                    </li>
                </ul>
            </div>
        </div>
        <!-- /box_content 招聘信息 END -->
        <div class="clear"></div>
    </div>
    <!-- /main -->
</div>
<!-- /mainer_wrapper -->
{{/block}}

index.html中css样式部分存储在index.less文件中,代码如下:

css 复制代码
/*广告条*/
.box_gg{ margin:5px 0px 15px; }

.main-container{
    .box_content{
        .title{ 
            background:url(../images/index_04.jpg) repeat-x; 
            line-height:30px; 
            padding:0px 12px; 
            color:#FFF; 
            border:1px solid #6faf00;

            a.more{ 
                float:right; font-size:12px; color:#FFF; text-decoration:none; 

                &:hover{ text-decoration:underline; }
            }

            .t_navi{ 
                height:30px; line-height:30px; padding:0px 15px; display:inline-block; cursor:pointer; 
            }
            .t_navi_hover{ 
                background:url(../images/index_05.jpg) repeat-x;
            }
        }

        .content{ padding:10px 0px; 
            .box_list{ 
                font-size:12px; clear:both; 

                li{ 
                    list-style:inside circle; border-bottom:1px dashed #7ebc13; line-height:30px;

                    span{ float:right; }
                    a{ 
                        color:#4b4b4b; text-decoration:none; 

                        &:hover{ color:#ff9d42;}
                    }
                }
            }
        }

        /*首页第三行*/
        &.wd490{
            .b_list{ 
                margin-bottom:15px; float:left;

                dt{ width:116px; height:80px; float:left; }
                dd{ 
                    width:360px; height:80px; padding-left:10px; float:right;

                    h2{ font-size:16px; padding-bottom:8px; }
                    span{ font-size:12px; }
                    a{ 
                        color:#ff9d42; text-decoration:none;
                        
                        &:hover{ text-decoration:underline; }
                    }
                }
            }
        }
        
    }

    .mg_l15{ margin-left:16px; }
    .wd300{ width:300px;}
    .wd415{ width:415px;}
    .wd255{ width:250px;}
    .wd490{ width:490px;}
}

此时如果你的devServer是开启的,浏览器中首页则可以正常显示了,如下图:

四、数据动态渲染

到目前为止,html页面各部分已独立开,成组件化开发,但是看似只是把html各个部分html代码拆分开到各自独立文件中,还是存在大量重复代码。所以现在需要使用上前面创建的htm.data.json文件,以及结合art-template语法进行模板渲染了。

4.1 导航数据渲染

首先我们来处理下导航数据,将导航内容全部拿到html.data.json文件中。导航中没有的页面,path路径使用javascript:;代替,作用是点击时不作跳转处理。

html.data.json文件 代码如下:

javascript 复制代码
{
    "navigation": [
        {"name": "首页", "enName": "HOME", "path": "index.html"},
        {"name": "新闻动态", "enName": "NEWS", "path": "list.html"},
        {"name": "旅游项目", "enName": "PROJEC", "path": "javascript:;"},
        {"name": "服务项目", "enName": "SERVICES", "path": "javascript:;"},
        {"name": "公司产业", "enName": "ENTERTAINMENT", "path": "javascript:;"},
        {"name": "农副产品", "enName": "BY-PRODUCT", "path": "javascript:;"},
        {"name": "种植养殖", "enName": "GRANCHIO", "path": "javascript:;"},
        {"name": "联系我们", "enName": "CONTACT US", "path": "contact.html"}
    ],

    "indexData": {
        "title": "首页"
    },
    "listData": {
        "title": "列表页"
    },
    "articleData": {
        "title": "列表-详情页"
    },
    "contactData": {
        "title": "联系我们"
    },
    "messageData": {
        "title": "留言页"
    }
}

header.html代码如下:

html 复制代码
<!-- header_wrapper -->
<div id="header_wrapper">
	<!-- 导航 START -->
    <div class="navigation">
    	<div class="navi_middle">
            <ul>
                {{each navigation as item}}
                <li><a href="{{item.path}}">{{item.name}}<span>{{item.enName}}</span></a></li>
                {{/each}}
            </ul>
            <div class="clear"></div>
        </div>
    </div>
    <!-- 导航 END -->
</div>
<!-- /header_wrapper -->

此时导航数据则是通过art-template循环语句动态渲染到html内容中,不过如下图,会发现之前首页上高亮部分没有了。这是因为循环时,each语句不知道要给哪个添加高亮类样式,所以还需要添加变量进行谈判。

4.2 导航高亮问题

解决高亮问题其实也不复杂,只要通过一个变量来控制渲染不同页面是,动态修改其值,这样在循环时就可以通过if语句进行判断,给哪个添加高亮即可。

在html.data.json中添加变量navIndexName,默认为"首页",如下图:

那如果动态修改这里的navIndexName呢,这就需要先来了解下art-template的内置变量清单。

变量名 功能描述
$data 传入模板的数据
$imports 外部导入的变量以及全局变量
print 字符串输出函数
include 子模板载入函数
extend 模板继承模板导入函数
block 模板继承模板导入函数

所以在页面中修改变量,可以通过$data变量进行操作,以index.html为例,如下图:

以上图方式,分别对新闻列表页、联系我们页面也添加高亮。

list.html代码如下:

html 复制代码
<!-- 修改当前页面对应标题 -->
{{$data.navIndexName = "新闻动态"}}

{{ extend './template/layout.html' }}

{{block 'title'}}{{listData.title}}{{/block}}

contact.html公共代码如下:

html 复制代码
<!-- 修改当前页面对应标题 -->
{{$data.navIndexName = "联系我们"}}

{{ extend './template/layout.html' }}

{{block 'title'}}{{contactData.title}}{{/block}}

最后将变量navIdexName应用到header.html中,在each循环时判断添加高亮类名,代码如下:

html 复制代码
<!-- header_wrapper -->
<div id="header_wrapper">
	<!-- 导航 START -->
    <div class="navigation">
    	<div class="navi_middle">
            <ul>
                {{each navigation as item}}
                <li {{if navIndexName==item.name}}class="curhover"{{/if}}>
                    <a href="{{item.path}}">{{item.name}}<span>{{item.enName}}</span></a>
                </li>
                {{/each}}
            </ul>
            <div class="clear"></div>
        </div>
    </div>
    <!-- 导航 END -->
</div>
<!-- /header_wrapper -->

此时在不同的页面,则会显示对应的高亮部分了。如下 图:

4.3 首页数据渲染

首先把首页中静态页面需要渲染的数据,全部整理到html.data.json中,代码如下:

javascript 复制代码
{
    "navigation": [
        {"name": "首页", "enName": "HOME", "path": "index.html"},
        {"name": "新闻动态", "enName": "NEWS", "path": "list.html"},
        {"name": "旅游项目", "enName": "PROJEC", "path": "javascript:;"},
        {"name": "服务项目", "enName": "SERVICES", "path": "javascript:;"},
        {"name": "公司产业", "enName": "ENTERTAINMENT", "path": "javascript:;"},
        {"name": "农副产品", "enName": "BY-PRODUCT", "path": "javascript:;"},
        {"name": "种植养殖", "enName": "GRANCHIO", "path": "javascript:;"},
        {"name": "联系我们", "enName": "CONTACT US", "path": "contact.html"}
    ],
    "navIndexName": "首页",
    "indexData": {
        "title": "首页",
        "firstList": [
{
"title": "望玉岛标题", 
"description": " 望玉岛度假村一日游活动方案:活动主题,放飞心情,走进自然,活动地;望玉岛度假村,行程特点;领略望玉岛... ",
"thumb": "images/index_09.jpg",
"url": "javascript:;"
},
{
"title": "望玉岛标题", 
"description": " 望玉岛度假村一日游活动方案:活动主题,放飞心情,走进自然,活动地;望玉岛度假村,行程特点;领略望玉岛... ",
"thumb": "images/index_10.jpg",
"url": "javascript:;"
},
{
"title": "望玉岛标题", 
"description": " 望玉岛度假村一日游活动方案:活动主题,放飞心情,走进自然,活动地;望玉岛度假村,行程特点;领略望玉岛... ",
"thumb": "images/index_11.jpg",
"url": "javascript:;"
}
        ],
        "bottomList": [
            {
                "title": "新春有礼------望玉岛别墅标间推出亲民价,餐饮",
                "datetime": "2014-10-2",
                "url": "javascript:;"
            },
            {
                "title": "新春有礼------望玉岛别墅标间推出亲民价,餐饮",
                "datetime": "2014-10-2",
                "url": "javascript:;"
            },
            {
                "title": "新春有礼------望玉岛别墅标间推出亲民价,餐饮",
                "datetime": "2014-10-2",
                "url": "javascript:;"
            },
            {
                "title": "新春有礼------望玉岛别墅标间推出亲民价,餐饮",
                "datetime": "2014-10-2",
                "url": "javascript:;"
            }
        ],
        "inviteList": [
            {
                "title": "2015-03-17诚招",
                "datetime": "2014-10-2",
                "url": "javascript:;"
            },
            {
                "title": "2014-03-12招聘",
                "datetime": "2014-03-12",
                "url": "javascript:;"
            },
            {
                "title": "2013-03-30诚招学生暑期工",
                "datetime": "2014-10-2",
                "url": "javascript:;"
            }
        ]
    },
    "listData": {
        "title": "列表页"
    },
    "articleData": {
        "title": "列表-详情页"
    },
    "contactData": {
        "title": "联系我们"
    },
    "messageData": {
        "title": "留言页"
    }
}

index.html全部通过art-template进行渲染,代码如下:

html 复制代码
<!-- 修改当前页面对应标题 -->
{{$data.navIndexName = "首页"}}

{{extend './template/layout.html'}}

{{block 'title'}}{{indexData.title}}{{/block}}

{{block 'content'}}
<!-- mainer_wrapper -->
<div id="mainer_wrapper">
	<!-- main -->
	<div class="main-container">
        <div class="clear"></div>

        <!-- 广告 START -->
        <div class="box_gg">
        	<a href="#" target="_blank">
                <img src="images/index_08.jpg" alt="banner" />
            </a>
        </div>
        <!-- 广告 END -->
        
        <!-- box_content 最新活动 START -->
    	<div class="box_content wd490 fl">
        	<div class="title"><a href="#" class="more">MORE &gt;&gt;</a>最新活动</div>
            <div class="content">
                {{each indexData.firstList as item}}
				<dl class="b_list">
                	<dt>
                        <a href="#" target="_blank">
                            <img src="{{item.thumb}}" alt="09" />
                        </a>
                    </dt>
                    <dd>
                    	<h2><a href="{{item.url}}" target="_blank">{{item.title}}</a></h2>
                        <span>
                            {{item.description}}
                            <a href="{{item.url}}" target="_blank">[详细情况]</a>
                        </span>
                    </dd>
                </dl>
                {{/each}}
                <div class="clear"></div>
            </div>
        </div>
        <!-- /box_content 最新活动 END -->
        
        <!-- box_content 旅游项目 START -->
    	<div class="box_content wd490 fl mg_l15">
        	<div class="title"><a href="#" class="more">MORE &gt;&gt;</a>旅游项目</div>
            <div class="content">
				{{each indexData.firstList as item}}
				<dl class="b_list">
                	<dt>
                        <a href="#" target="_blank">
                            <img src="{{item.thumb}}" alt="09" />
                        </a>
                    </dt>
                    <dd>
                    	<h2><a href="{{item.url}}" target="_blank">{{item.title}}</a></h2>
                        <span>
                            {{item.description}}
                            <a href="{{item.url}}" target="_blank">[详细情况]</a>
                        </span>
                    </dd>
                </dl>
                {{/each}}
                <div class="clear"></div>
            </div>
        </div>
        <!-- /box_content 旅游项目 END -->
        
        <!-- box_content 旅游咨询 START -->
    	<div class="box_content fl" style="width:360px;">
        	<div class="title"><a href="#" class="more">MORE &gt;&gt;</a>旅游咨询</div>
            <div class="content">
				<ul class="box_list">
                    {{each indexData.bottomList as item}}
                    <li>
                        <span>{{item.datetime}}</span>
                        <a href="{{item.url}}" target="_blank">{{item.title}}</a>
                    </li>
                    {{/each}}
                </ul>
            </div>
        </div>
        <!-- /box_content 旅游咨询 END -->
        <!-- box_content 贵宾服务 START -->
    	<div class="box_content fl mg_l15" style="width:360px;">
        	<div class="title"><a href="#" class="more">MORE &gt;&gt;</a>贵宾服务</div>
            <div class="content">
				<ul class="box_list">
                    {{each indexData.bottomList as item}}
                    <li>
                        <span>{{item.datetime}}</span>
                        <a href="{{item.url}}" target="_blank">{{item.title}}</a>
                    </li>
                    {{/each}}
                </ul>
            </div>
        </div>
        <!-- /box_content 贵宾服务 END -->
        <!-- box_content 招聘信息 START -->
    	<div class="box_content fl mg_l15" style="width:240px;">
        	<div class="title"><a href="#" class="more">MORE &gt;&gt;</a>招聘信息</div>
            <div class="content">
				<ul class="box_list">
                    {{each indexData.inviteList as item}}
                    <li>
                        <span>{{item.datetime}}</span>
                        <a href="{{item.url}}" target="_blank">{{item.title}}</a>
                    </li>
                    {{/each}}
                </ul>
            </div>
        </div>
        <!-- /box_content 招聘信息 END -->
        <div class="clear"></div>
    </div>
    <!-- /main -->
</div>
<!-- /mainer_wrapper -->
{{/block}}

首页到这已开发完成 ,数据也全部配置到json文件中,并且html页面中冗余代码也大大减少,维护起来也更容易、更方便、更易懂。

此篇讲到这就结束了,其他页面开发同首页一样,所以不在重复讲解。

相关推荐
cwj&xyp17 分钟前
Python(二)str、list、tuple、dict、set
前端·python·算法
dlnu201525062219 分钟前
ssr实现方案
前端·javascript·ssr
古木201923 分钟前
前端面试宝典
前端·面试·职场和发展
轻口味2 小时前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王2 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发3 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀3 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪3 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef5 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端