Webpack生成企业站静态页面 - 增强数据处理能力

news2024/12/24 3:17:23

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

        此篇在之前两篇基础上,增强数据处理功能力,让开发更为便捷、更为灵活。如果有朋友不了解此篇讲的是什么内容,可以去看下前面写的。

项目环境搭建 地址:Webpack生成企业站静态页面 - 项目搭建-CSDN博客

组件化 地址:Webpack生成企业站静态页面 - 组件化-CSDN博客

        这里还是以首页为例,数据数据直在存放在index.html中,也能通过art-template完成数据渲染。

一、优化json数据

        首先将html.data.json文件进行优化,在后期开发过程中,随着页面不断增长,json文件中数据不断增加,越积越多。久而久之,也会影响后期维护速度,所以html.data.json只存储所页面公用的数据或变量,例如头部(head标签)中内容,导航和页尾等公共数据。

        html.data.json代码如下:

{
    "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": "首页",
    "keywords": "新闻 旅游 服务 农产品 种植 养殖",
    "description": "这是关于望玉岛度假村相关描述内容"
}

        此时html.data.json文件中,只保留了公共部分用到的数据,首页内容将全部存放在index.html。

        index.html文件中代码如下:

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

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

<datalist>
{
    "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:;"
        }
    ]
}    
</datalist>

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

        注意的是,此时index.html渲染title部分被删除,原因是数据都独立在各自的html中,html-loader加载内容时,合并到htmlData中的数据是唯一的,此时直接在layout.html调用title即可。

        index.html中删除这行代码:

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

        修改layout.html,将”{{block 'title'}}{{/block}}“修改为”{{title}}“,代码如下:

<!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>望玉岛 - {{title}}</title>
</head>
<body>
    <!-- 引入导航HTML部分 -->
    {{include './header.html'}}
    <!-- 渲染内容部分 -->
    {{block 'content'}}{{/block}}
    <!-- 引入底部HTML部分 -->
    {{include './footer.html'}}
</body>
</html>

        当然,以上内容修改完后,现在页面还不能按预期效果渲染出来,并且现在运行npx webpck serve还会出错,因为现在渲染数据集顶级key中还不存在title,并且art-template也不识别<datalist>标签。

二、set功能

        art-template也提供了set设置变量的功能,由于html.data.json中首页数据全部清除,现在渲染的首页中间部分都为空,如下图:

        我们通过set在index.html添加最后项数据,代码如下:

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

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

<!-- 略... -->

{{set 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:;"
    }
]}}

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

        <!-- 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 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}}

        此时首页右下角内容则显示出来了,结果如下图:

        但是set设置变量有作用域限制,当前页面设置变量只能本区域使用,而且extend好像没有传递变量功能,所以数据在共享方面还有所欠缺,要再考虑其他方式来增强数据处理能。

        当然,如果set功能已能满足您的需求,后面内容可以忽略了。

三、webpack配置修改

         为了改善set的不足之处,这里考虑还是将数据存放在html页面。如何自定义内容让art-template识别呢?在实现art-template模板渲染时候,就是在html-loader中preprocessor()回调函数中实现的。同理,在art-template渲染前,将自定义数据识别出来即可。

        另外,把每个页面独有的数据,放在html页面中或者在循环渲染的位置,也更容易找到并修改,所以在此作些文章还是有意义的。

3.1 识别<datalist>标签

        想要匹配<datalist>标签及内部数据,并将其转换为json数据,其方法无非就是使用正则进行匹配。通过正则工具,进行数据测试,匹配到需要的数据,如下图:

        经过多轮测试,此正则已能满足需求,下面将使用它来完成自定义数据加载。

3.2 修改html-loader

        如下图,在art-template对返回的html内容进行渲染前,把自定义数据匹配到,并且合并到htmlData中,则可以实现自定义数据全局化。

        webpack.config.js文件中,将html-loader的options选项中preprocessor回调函数进行修改, 代码如下:

options: {
    minimize: false,        // 不压缩html内容
    preprocessor: (content, loaderContext) => {
        // 正则达式
        let regEx = /<datalist>\s*{\s*[\s\S]*?\s*}\s*<\/datalist>/gi,
        // 区域html页面中json数据
        htmlResult = content.match(regEx),
        // 公共部分json数据
        returnData = {...htmlData},
        // 临时存储html中读取到的json数据
        data = {};
        // 判断htmlResult如果不为空,并且数组(match匹配到数据返回为数组格式)则转换字符串内容为json数据
        if(null!=htmlResult&&Array.isArray(htmlResult)){
            try {
                // 去除datalist标签
                htmlResult = htmlResult.map(item => {
                    item = item.replace('<datalist>', '');
                    item = item.replace('</datalist>', '');
                    return JSON.parse(item);
                });
                // 合并数据
                htmlResult.forEach(item => {
                    Object.assign(data, item);
                });
                // 合并到htmlData数据集中
                Object.assign(returnData, data);
            } catch (error) {
                console.error('html result:', error);
            }
            // 清除页面中数据
            content = content.replace(regEx, '');
        }
        return artTemplate.compile(content)(returnData);
    }
}

       大家在写代码时,要多思考,在什么时候代码可能会报错。由于json数据是不可控的,大家在写的时候可能多打一个符号,或者在别的地方拷过来一些特殊符号,导致JSON.parse时编译时报错,从而导致整个js运行报错,影响其他正常程序执行。所以这里在JSON.parse位置,添加了try{}catch{}用来捕捉错误。

        还有细心朋友会发现另一个细节,就是<datalist>数据不放在<block>中,html也不会渲染出来,那为什么要匹配到后将其清除呢?这是因为这里使用的是extend继承原因,layout.html中所有坑位的渲染是通过<block>完成的,不在<block>内的内容是不会被渲染。但如果是有些数据放在<block>中,或者没使用extend继承关系时,则会被渲染到页面中;所以多做此一举对于编写代码,能更为灵活操作。

        此时重新运行npx webpack serve,不仅首页内容又全部显示出来了,不同页面也能正常显示各自的标题了,如下图:

        该篇为功能扩展部分,解决需要优化的小功能。有时一些小需求不需要到处找插件,在自己能力和条件允许范围内,可以自己动手来实现需求。像此功能,其实也就是一条正则就解决的事,  没必要花大量时间研究插件,了解他人制定的规则,自己实现更为自在、更有效率。希望此篇对大家有帮助,谢谢~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1552334.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pyecharts操作三

pyecharts操作三 pyecharts 是一个用于生成Echarts图表的Python库。Echarts是百度开源的一个数据可视化JS库&#xff0c;可以生成一些非常酷炫的图表。 环境安装 pip install pyecharts 检查版本 import pyecharts print(pyecharts.version) 2.0.3 GL关系图 import rando…

Linux(CentOS7)安装 Redis

目录 下载 上传 解压 编译与安装 修改配置文件 ​编辑 启动redis 客户端使用 下载 官网地址&#xff1a; Download | RedisRedisYou can download the last Redis source files here. For additional options, see the Redis downloads section below.Stable (7.2)Re…

想学网络安全,从哪里开始?网络安全的学习路线

网络安全学习路线&#xff1a; 想学习网络安全专业的知识&#xff0c;想当黑客&#xff0c;但是不知道该从哪里开始学。 我给你一个路线&#xff01; 清晰图片和大纲&#xff1a;https://docs.qq.com/doc/DU1lpVFpSbWVrd2p3

Linux安装redis(基于CentOS系统,Ubuntu也可参考)

前言&#xff1a;本文内容为实操记录&#xff0c;仅供参考&#xff01; 一、下载并解压Redis 1、执行下面的命令下载redis&#xff1a;wget https://download.redis.io/releases/redis-6.2.6.tar.gz 2、解压redis&#xff1a;tar xzf redis-6.2.6.tar.gz 3、移动redis目录&a…

MySQL进阶-----索引的语法与SQL性能分析

目录 前言 一、索引语法 1.SQL语法 2.案例演示 二、SQL性能分析 三、慢查询日志 1.开启日志 2.测试样例 四、profile详情 1.开启profile 2.profile测试SQL语句 五、explain详情 1.语法结构 2.执行顺序示例&#xff08;id&#xff09; 3.执行性能示例(type) 前言 本…

斜率优化dp 笔记

任务安排1 有 N 个任务排成一个序列在一台机器上等待执行&#xff0c;它们的顺序不得改变。 机器会把这 N 个任务分成若干批&#xff0c;每一批包含连续的若干个任务。 从时刻 00 开始&#xff0c;任务被分批加工&#xff0c;执行第 i 个任务所需的时间是 Ti。 另外&#x…

uniApp使用XR-Frame创建3D场景(6)播放模型动画

上篇文章讲述了如何将XR-Frame作为子组件集成到uniApp中使用 这篇我们讲解播放模型动画 先看源码 <xr-scene render-system"alpha:true" bind:ready"handleReady"> <xr-node visible"{{sec6}}"><xr-light type"ambient&qu…

火车头通过关键词采集文章的原理

随着互联网信息的爆炸式增长&#xff0c;网站管理员和内容创作者需要不断更新和发布新的文章&#xff0c;以吸引更多的用户和提升网站的排名。而火车头作为一款智能文章采集工具&#xff0c;在这一过程中发挥着重要作用。本文将探讨火车头如何通过关键词采集文章&#xff0c;以…

<QT基础(5)>事件监听

事件监听 事件监听&#xff08;Event Handling&#xff09;是在程序中监视和响应发生的事件的一种机制。在Qt中&#xff0c;事件监听是一种常见的用于处理用户输入、系统事件以及其他类型事件的方法。通过事件监听&#xff0c;您可以在发生特定事件时捕获事件并执行相应的操作…

HarmonyOS 应用开发之Want的定义与用途

Want 是一种对象&#xff0c;用于在应用组件之间传递信息。 其中&#xff0c;一种常见的使用场景是作为 startAbility() 方法的参数。例如&#xff0c;当UIAbilityA需要启动UIAbilityB并向UIAbilityB传递一些数据时&#xff0c;可以使用Want作为一个载体&#xff0c;将数据传递…

VMware vSAN OSA存储策略 - 基于虚拟机的分布式对象存储

简介 博客&#xff1a;https://songxwn.com/ 存储策略 (Storage Policy) 是管理员定义的一组规则&#xff0c;这组规则定义了数据对象在 vSAN 存储上是如何保存的&#xff0c;存储策略定义了数据存储的可靠性、访问性能等特性。vSAN 提供了基于存储策略的存储管理 SPBM (Stor…

解码“零信任”,如何带来信任感?

零信任的“信任”来源&#xff0c;并非凭空而生&#xff0c;而是建立在严格、细致且持续的验证、策略之上。它不仅能够提升企业的安全防护能力&#xff0c;也在加速安全技术的创新与演进。 推动创新 零信任理念激活网络安全 身份和访问管理革新。零信任理念“永不信任&#…

Jenkins升级中的小问题

文章目录 使用固定版本安装根据jenkins页面下载war包升级jenkins重启jenkins报错问题解决 K8s部署过程中的一些小问题 ##### Jenkins版本小插曲 ​ 在Jenkins环境进行插件安装时全部清一色飘红&#xff0c;发现是因为Jenkins版本过低导致&#xff0c;报错的位置可以找到更新je…

【InternLM 实战营第二期笔记】书生·浦语大模型全链路开源体系及InternLM2技术报告笔记

大模型 大模型成为发展通用人工智能的重要途径 专用模型&#xff1a;针对特定任务&#xff0c;一个模型解决一个问题 通用大模型&#xff1a;一个模型应对多种任务、多种模态 书生浦语大模型开源历程 2023.6.7&#xff1a;InternLM千亿参数语言大模型发布 2023.7.6&#…

【React】onClick点击事件传参的4种方式

记录React onClick 点击事件传参的 4 种方式 方式一&#xff1a;使用内联箭头函数 import React, { MouseEvent } from "react";function App() {const handleClick (event: MouseEvent<HTMLButtonElement>, name: string) > {console.log(event)console.…

Unity图集编辑器

图集编辑器 欢迎使用图集编辑器新的改变编辑器图片 欢迎使用图集编辑器 Unity图集操作很是费劲 无法批量删除和添加图集中的图片 新的改变 自己写了一个图集编辑器 客&#xff1a; 支持批量删除 左键点击图片代表选中 右键点击图标定位到资产支持批量添加 选中图片拖拽到编…

小程序利用WebService跟asp.net交互过程发现的问题并处理

最近在研究一个项目&#xff0c;用到asp.net跟小程序交互&#xff0c;简单的说就是小程序端利用wx.request发起请求。获取asp.net 响应回来的数据。但经常会报错。点击下图的测试按钮 出现如下错误&#xff1a; 百思不得其解&#xff0c;试了若干方法&#xff0c;都不行。 因为…

非wpf应用程序项目【类库、用户控件库】中使用HandyControl

文章速览 前言参考文章实现方法1、添加HandyControl包&#xff1b;2、添加资源字典3、修改资源字典内容 坚持记录实属不易&#xff0c;希望友善多金的码友能够随手点一个赞。 共同创建氛围更加良好的开发者社区&#xff01; 谢谢~ 前言 wpf应用程序中&#xff0c;在入口项目中…

单例模式如何保证实例的唯一性

前言 什么是单例模式 指一个类只有一个实例&#xff0c;且该类能自行创建这个实例的一种创建型设计模式。使用目的&#xff1a;确保在整个系统中只能出现类的一个实例&#xff0c;即一个类只有一个对象。对于频繁使用的对象&#xff0c;“忽略”创建时的开销。特点&#xff1a…

arp 协议

数据链路层 我们之前学习到的 IP 协议解决的是数据跨网络传输的问题。 数据链路层解决的是&#xff1a;直接相连的主机&#xff0c;进行数据交付的问题&#xff01; 直接相连的设备包括我们的电脑&#xff0c;路由器等等哈&#xff01; 我们在网络基础那篇文章中讲过什么是以…