一、背景
公司官网项目有许多页面的页脚都不是统一管理的,且页脚的版权信息中的最新年份是需要每年手动更改,比较费时间,后续版权信息有修改也需要修改多个文件,比较麻烦。
为了方便管理和节省后续修改的开销,此次对官网页脚做一个优化:将不同页面中相同的页脚版权信息统一起来组件化管理,把静态的最新年份改成动态的,根据服务器时间转换成当前年份,实现自动更新时间
公司官网有四个项目,页脚文件有三种:
- php
- 纯 html
- vue
针对三种文件要给出三种方案
二、需求任务
-
PC 官网:页脚年份是静态的,需要改成从服务器获取当前时间,转换成对应年份,实现自动更新时间
php
html
-
移动端: 页脚年份也是静态的,而且存在内容重复的组件,有多个 copyRight.vue,有部分 copyRight 的template 部分相同,只是样式不同
需要将内容相同的 copyRight 抽取到公共的组件,实现复用,静态的年份信息也需要改成从服务器获取当前时间,转换成对应年份,实现自动更新时间
三、实现方案
1. php:
<?php echo date('Y');?> ,php 是服务器端的脚本语言,这个 php 语句获取获取的时间就是服务器时间,不需要请求接口
具体方案: 将所有含有版权信息的都更换成这一段
© 2013-<?php echo date('Y');?>
2. html
- 将请求接口获取时间,转换成年份的操作封装在一个 js 文件内:
ajax 请求接口数据,并将服务器时间利用 Date 方法转换成对应的年份- 用 jq 根据 id 获取 dom 元素并将元素内容替换成上一步骤转换好的年份
- 在需要自动更新页脚时间的 html 文件中,引入上述 js 文件,同时引入 jquery 资源
具体代码:
get-current-year.js
/**
* @file 请求服务器时间 转换成对应的年份
*/
function getCurrentYear() {
const url = '接口';
//请求接口
$.ajax({
url,
dataType: 'jsonp',
type: 'get',
success: function(data) {
//转换成对应的年份
const currentYear = new Date(data.currentTime).getFullYear();
//jq 写法,$('#currentYear') 等同于 document.querySelector('#currentYear')
//$('#currentYear')获取 id = "currentYear" 的dom元素
//把 currentYear 的值写入该 dom 元素的 html 中
$('#currentYear').html(currentYear);
},
error: function() {
console.error("数据获取异常");
}
});
}
getCurrentYear();
举其中一个例子,foot.html
<footer>
© 2013-<span id="currentYear" class="footer-year"></span>xx有限公司 版权所有
</footer>
//公司的 jquery 资源
<script src="https://xxx/assets/lib/jquery/jquery.min.js"></script>
//官网 js 文件缓存地址
<script src="https:/xxx/assets/dist/js/get-current-year.min.js"></script>
3. vue
实现时间自动更新
- 引入 APIQuery 类文件和 api 导出文件
- 新建一个 get-current-year-mixins.js,data 声明 currentYear,实现请求接口获取服务器时间,将成功获取的服务器时间存入 store 中,将获取到的 serviceTime 通过 Date 方法进行转换, 赋值给 currentYear
- 含有版权信息的文件引入 get-current-year-mixins.js ,将静态的时间 ”2023“ 替换成{{ currentYear }},即可实现页脚时间自动更新
具体代码
api-query.js
/**
* @file APIQuery 类
*/
import { send as ajax } from '@just4/ajax/ajax';
import { jsonp } from '@just4/load-script';
import { startsWithProtocol } from '@utils/net'; //公司的工具包
export default class APIQuery {
constructor(options) {
if (options.baseUrl) { this.setBaseUrl(options.baseUrl); }
this._timeout = options.timeout || 10000;
this._afterResponse = options.afterResponse;
this._beforeRequest = options.beforeRequest;
this._handleHeader = options.handleHeader;
}
setBaseUrl(baseUrl) { this._baseUrl = baseUrl; }
_addBaseUrl(url) {
if (!this._baseUrl || startsWithProtocol(url)) {
return url;
} else {
return String(
typeof this._baseUrl === 'function' ? this._baseUrl() : this._baseUrl
).replace(/\/+$/, '') + '/' + url.replace(/^\/+/, '');
}
}
async _request(url, options, isJsonp = false) {
const requestUrl = this._addBaseUrl(url);
options.timeout = options.timeout || this._timeout;
if (this._handleHeader) {
options.headers = this._handleHeader(options.headers);
}
if (this._beforeRequest) {
options.beforeSend = (xhr) => this._beforeRequest(xhr, options);
}
let res;
if (isJsonp) {
res = await jsonp(requestUrl, options);
} else {
res = await ajax(requestUrl, options);
}
return this._afterResponse ? this._afterResponse.call(window, res, options) : res;
}
get(url, options = {}) {
return this._request(
url,
Object.assign(options, {
method: 'get'
})
);
}
post(url, options = {}) {
return this._request(
url,
Object.assign(options, {
method: 'post'
})
);
}
delete(url, options = {}) {
return this._request(
url,
Object.assign(options, {
method: 'delete'
})
);
}
jsonp(url, options = {}) {
return this._request(
url,
options,
true,
);
}
}
api/exports.js
/**
* @file API 导出
*/
import APIQuery from './api-query';
export const apiActivity = new APIQuery({
baseUrl: '写自己的接口baseurl',
afterResponse: (response) => {
return response;
}
});
store/index.js
import { apiActivity } from '~/assets/api/exports';
export const state = () => ({
serviceTime: new Date().getTime(),
});
export const mutations = {
setServiceTime(state, serviceTime) {
state.serviceTime = serviceTime;
},
};
export const actions = {
/**
* 获取服务器时间
*/
getServiceTime() {
return apiActivity.jsonp('/currentTime');
},
};
get-service-time.js
/**
* @file 请求接口获取服务器时间 更新保存在store 转换成对应的年份 mixin
*/
export default {
data() {
return {
currentYear: new Date().getFullYear(),
}
},
mounted() {
this.setTime();
},
methods: {
async setTime() {
let serviceTime = Date.now();
const { currentTime, status } = await this.$store.dispatch(
'getServiceTime'
);
if (status === 'success') {
serviceTime = currentTime;
}
this.$store.commit('setServiceTime', serviceTime);
this.currentYear = new Date(serviceTime).getFullYear();
},
},
}
关于 mixin 可以看这篇文章 Vue -- Mixins 详解 - 掘金 (juejin.cn)
CopyRight.vue
<template>
<section :class="cssClass" >
<p>©2013-{{currentYear}} xx公司版权所有</p>
</section>
</template>
<script>
// 引入 mixin
import getServiceTimeMixin from '~~/assets/mixins/get-service-time-mixin';
export default {
mixins: [getServiceTimeMixin],
props: {
cssClass: {
type: String,
default: '',
}
},
}
版权组件统一管理
- component/page-landing 目录下的几个页面组件都含有copyRight组件,经过对比,7个文件中,其中5个组件template内容完全相同,只有样式不一样
- 在 component/page-landing/common 目录下新建公用copyRight 组件,利用 props 传递类名,不同的页面对应不同的类名,有不同的样式,实现统一管理