前端工程化03-贝壳找房项目案例JavaScript常用的js库

4、项目实战(贝壳找房)

这个项目包含,基本的ajax请求调用,内容的渲染,防抖节流的基本使用,ajax请求工具类的封装

4.1、项目的接口文档

下述接口文档:

简述内容
baseURL:http://123.207.32.32:9060/beike/api
首页数据(GET):baseURL + /homePageInfo
搜索接口(GET):baseURL + /sug/headerSearch?cityId=440100&cityName=广州&channel=site&keyword=白云山&query=白云山
热门推荐(GET):baseURL + /site/rent
城市数据(GET):baseURL + /city

详细接口文档,见如下资料:HYBeiKe接口文档.md

4.2、为什么要封装Ajax请求库

//文档加载完成以后再进行dom操作
$(function(){//1、拿到我们首页的一个数据$.ajax({//1.1、不会出现跨域问题、后台配置跨域  node cors   nginx反向代理url: "http://123.207.32.32:9060/beike/api/homePageInfo",type: "get",dataType: "json",success: function(data){console.log(data)//1.2、更新左上角的地址信息var  addr=data.curLocation || {}console.log(addr.city)$(".header .address").text(addr.city)},error: function(err){console.log(err)}})
})/*** 为什么要封装*   1、可扩展性、可维护性*   2、封装性:可以对我们共性代码进行封装,baseURl,timeOut(解耦合)*   3、统一处理我们的请求(前置拦截请求:放token、后置拦截请求:解构data数据,异常拦截处理:统一弹出错误提示)*/

image-20240421151222548

代码封装的工具类request.js文件

;(function(window, $) {function request(config) {// 返回一个Promisereturn $.ajax({timeout: config.timeout || 5000,url: config.url || '',method: config.method || 'GET',data: config.data || {},headers: config.headers || {}//后面的会把前面的覆盖掉//...config })}function get(url, data = {}, config = {}) {// 返回一个Promisereturn request({url,method: 'GET',data,...config})}function post(url, data = {}, config = {}) {return request({url,method: 'POST',data,...config})}window.HyReq = {request,get,post}
//立即执行函数
})(window, jQuery)

4.3、代码风格

$(function(){//0.初始化页面需要执行的函数initPage();function initPage(){//1.拿到首页的数据HyReq.get('http://123.207.32.32:9060/beike/api/homePageInfo').then(function(res){console.log(res)//1.1、更新左上角的地址信息renderHeaderAddress(res);}).catch(function(err){console.log(err)});}//2.渲染头部的数据function renderHeaderAddress(res){//1.更新左上角的地址信息var  addr=res.curLocation || {}console.log(addr.city)$(".header .address").text(addr.city)}
})
const  BASE_URL='http://123.207.32.32:9060/beike/api/'const  HYAPI={HOME_PAGE_INFO:BASE_URL+'homePageInfo', //获取首页的数据HOT_RECOMMEND:BASE_URL+'site/rent' //获取热门推荐数据
}

4.5、热门推荐

1、公用代码抽取

2、数据缓存优化

$(function(){// 常规变量var $searchInput=$(".header .house-search")var $searchList=$(".header .search-list")var $searchTips=$(".header .search-tips")// 缓存变量var cacheSearchListData=[];//1.初始化页面需要执行的函数initPage();function initPage(){//1.拿到首页的数据HyReq.get(HYAPI.HOME_PAGE_INFO).then(function(res){console.log(res)//1.1、更新左上角的地址信息renderHeaderAddress(res);}).catch(function(err){console.log(err)});}//2.渲染头部的数据function renderHeaderAddress(res){//1.更新左上角的地址信息var  addr=res.curLocation || {}console.log(addr.city)$(".header .address").text(addr.city)}//3.监听房子搜索输入框的focus事件$searchInput.on("focus",function(){//判断缓存是否有数据if(cacheSearchListData.length){//渲染界面renderSearchList(cacheSearchListData);return;}//1、发起网络请求,获取热门推荐的数据HyReq.get(HYAPI.HOT_RECOMMEND).then(function(res){//获得数据赋值变量值var searchListData=res.rent_house_list.list||[];//判断是否有数据if(!searchListData){//没有数据直接返回return;}//复杂的数组映射成为一个简单的数组(map映射,并不会改变原数组)searchListData=searchListData.map((item)=>{return{title:item.app_house_title}})//有数据就处理下缓存cacheSearchListData=searchListData;//渲染页面结构renderSearchList(searchListData);})})//4、清空隐藏$searchInput.on('blur',function(){$searchList.empty()// $searchTips.css('display','none')// $searchList.hide();})//searchListData:[{title:'}]function renderSearchList(searchListData=[]){//渲染界面的var htmlString=`<li><span>热门搜索</span></li>`searchListData.forEach(function(item){console.log(item);htmlString+=`<li><span>${item.title}</span></li>`});//拼接给搜索列表$searchList.empty().append(htmlString)}})

4.6、缓存防抖应用

用的是我们js高级手写的防抖节流库

function debounce(fn, delay = 500, immediate = false) {// 1.定义一个定时器, 保存上一次的定时器let timer = nulllet isInvoke = false// 2.真正执行的函数const _debounce = function(...args) {// 取消上一次的定时器if (timer) clearTimeout(timer)// 判断是否需要立即执行if (immediate && !isInvoke) {fn.apply(this, args)isInvoke = true} else {// 延迟执行timer = setTimeout(() => {// 外部传入的真正要执行的函数fn.apply(this, args)isInvoke = false}, delay)}}return _debounce
}function throttle(fn, interval = 400, options = { leading: true, trailing: false }) {// 1.记录上一次的开始时间const { leading, trailing } = optionslet lastTime = 0let timer = null// 2.事件触发时, 真正执行的函数const _throttle = function(...args) {// 2.1.获取当前事件触发时的时间const nowTime = new Date().getTime()if (!lastTime && !leading) lastTime = nowTime// 2.2.使用当前触发的时间和之前的时间间隔以及上一次开始的时间, 计算出还剩余多长事件需要去触发函数const remainTime = interval - (nowTime - lastTime)if (remainTime <= 0) {if (timer) {clearTimeout(timer)timer = null}// 2.3.真正触发函数fn.apply(this, args)// 2.4.保留上次触发的时间lastTime = nowTimereturn}if (trailing && !timer) {timer = setTimeout(() => {timer = nulllastTime = !leading ? 0: new Date().getTime()fn.apply(this, args)}, remainTime)}}return _throttle
}

在jq库下导入

<script src="./js/utils.js"></script>

实战代码

$(function(){// 常规变量var $searchInput=$(".header .house-search")var $searchList=$(".header .search-list")var $searchTips=$(".header .search-tips")var $searchMenu=$('.header .search-menu > ul')var $searchMenuArrow=$('.header .arrow')//首页的所有数据var homePageInfoData={} //首页的所有的数据//搜索框提示内容var currentSearchPlaceHolder='请输入区域、商圈或小区名开始找房'// 缓存变量var cacheSearchListData=[];//渠道全局变量var currentSearchBarSelector='site';//1.初始化页面需要执行的函数initPage();function initPage(){//1.拿到首页的数据HyReq.get(HYAPI.HOME_PAGE_INFO).then(function(res){//0、把首页数据存起来homePageInfoData=res;//1、更新左上角的地址信息renderHeaderAddress(res);//2、渲染搜索栏renderSearchBar(res);}).catch(function(err){console.log(err)});}//2.渲染头部的数据function renderHeaderAddress(res){//1.更新左上角的地址信息var  addr=res.curLocation || {}$(".header .address").text(addr.city)}//3.监听房子搜索输入框的focus事件$searchInput.on("focus",function(){//1、如果 input 有数据因该去搜索var  value=$(this).val()if(value.trim()){//去搜索房子(通过代码模拟一个用户输入事件)$(this).trigger('input')return;}//2、如果没有数据就是热门推荐//判断缓存是否有数据if(cacheSearchListData.length){//渲染界面renderSearchList(cacheSearchListData);return;}//1、发起网络请求,获取热门推荐的数据HyReq.get(HYAPI.HOT_RECOMMEND).then(function(res){//获得数据赋值变量值var searchListData=res.rent_house_list.list||[];//判断是否有数据if(!searchListData){//没有数据直接返回return;}//复杂的数组映射成为一个简单的数组(map映射,并不会改变原数组)searchListData=searchListData.map((item)=>{return{title:item.app_house_title}})//有数据就处理下缓存cacheSearchListData=searchListData;//渲染页面结构renderSearchList(searchListData);})})//4、清空隐藏$searchInput.on('blur',function(){$searchList.empty()// $searchTips.css('display','none')// $searchList.hide();})//5、搜索列表渲染 searchListData:[{title:'}]function renderSearchList(searchListData=[]){//渲染界面的var htmlString=`<li><span>热门搜索</span></li>`searchListData.forEach(function(item){htmlString+=`<li><span>${item.title}</span></li>`});//拼接给搜索列表$searchList.empty().append(htmlString)}//6、列表输入搜索   debounce防抖函数$searchInput.on('input',debounce(function(){//转jq对象,拿到valvar value=$(this).val();// url?key=value // data:{}  转查询字符串,放到url//取首页数据var curLocation=homePageInfoData.curLocationHyReq.get(HYAPI.HOME_SEARCH,{cityId:curLocation.cityCode,   cityName:curLocation.city,   channel:currentSearchBarSelector,   keyword:value, query:value	}).then(function(res){console.log(res);//获取赋值给变量var  searchData=res.data.result||[]//将复杂的数组转换为简单的数组searchData=searchData.map((item)=>{return{title:item.hlsText||item.text}})//渲染列表renderSearchList(searchData);})}))//7、箭头移动事件监听$searchMenu.on('click','li',function(){console.log(this)//1、修改li的高亮var $li=$(this)$li.addClass('active').siblings().removeClass('active');//2、移动箭头var liWidth=$li.width();var position=$li.position();// console.log(liWidth)// console.log(position)var arrowLeft =position.left+(liWidth/2)$searchMenuArrow.css('left',arrowLeft)//3、修改我们的placholder$searchInput.prop({placeholder:currentSearchPlaceHolder+$li.text()})//4、拿到li中绑定的keyconsole.log($li.data('key'))currentSearchBarSelector=$li.data('key')})//8、渲染搜索栏数据function renderSearchBar(res){var  searchBarData=res.searchMenus||[];var  stringHtml='';searchBarData.forEach(function(item,index){var active=index===0?'active':'';stringHtml+=`<li class="item ${active}" data-key="${item.key}"><span>${item.title}</span></li>`})$searchMenu.empty().append(stringHtml)}})

5、常用的JavaScript的库

jQuery是一个快速、小型且功能丰富的 JavaScript 库,它使HTML文档遍历和操作、事件处理、动画和 AJAX 之类的事情变得更加简单。当时jQuery库不但简化了代码,而且提供出色的跨浏览器支持,其极大的提高了 Web 开发人员的工作效率。 除了jQuery之外,其实还有许多库和框架可供JavaScript开发人员使用。下图是前端开发常用的工具库:

image-20240502192637856

5.1、underscore库 VS Lodash

Lodash Underscore 都是非常实用JavaScript工具库,它们都提供了非常多的函数来对数字字符串数组对象等操作。

这些函数不但可以简化JavaScript编写,而且可以极大的提高我们的开发效率。这些库非常适合如下操作:

  • 迭代数组、对象和字符串。
  • 操作和测试值。
  • 创建复合函数。

LodashUnderscore的一个分支,仍然遵循Underscore的API, 但在底层已完全重写过。对于字符串、数组、对象等Lodash提供了跨环境迭代的支持。

Lodash还添加了许多Underscore没有提供的特性和功能,例如:提供 AMD 支持深度克隆深度合并更好的性能大型数组和对象迭代的优化等,如今的Lodash足以成为Underscore替代品。

Lodash从第4个版本开始放弃对IE9以下的支持。

image-20240502193516496

5.2、Lodash库的安装

方式一:CND

https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js

方式二:下载源码引入

<!--1、本地源码引入(会在全局的window中添加 _ 变量-->
<script src="../libs/lodash.min.js"></script>
<script>console.log(window._)//去除假值console.log(_.compact([1,2,3,false,null]))
</script>

5.3、Lodash库的基本使用

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./utils/HYLodash.js"></script><script>// 1.打印一下 _console.log("%O", _)console.log(_.VERSION) // 查看Lodash的版本号console.log(_.join([2022, 06, 23], '-'))</script>
</body>
</html>

5.4、手写一个精简版的Lodash

HYLodash.js

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./utils/HYLodash.js"></script><script>// 1.打印一下 _console.log("%O", _)console.log(_.VERSION) // 查看Lodash的版本号console.log(_.join([2022, 06, 23], '-'))</script>
</body>
</html>

参考官网文档

https://www.lodashjs.com/docs/lodash.random

5.5、Lodash-number的操作

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./libs/lodash-4.17.21.js"></script><script>// 1.获取随机数console.log( _.random(5)  )  // 0-5console.log( _.random(5, 10)  )  // 5 - 10</script>
</body>
</html>

5.6、Lodash-string的操作

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./libs/lodash-4.17.21.js"></script><script>// 1.将字符串转成 驼峰命名 中间的空格会去掉console.log( _.camelCase(' foo bar  ')  )// 2.转驼峰,并忽略掉---console.log( _.camelCase('--foo-bar--')  )// 3.首字母大写,前面有空格,去不掉,中间有空格,也去不掉console.log( _.capitalize('foo bar') )// 4.判断字符串是否以某个字符串结尾console.log(_.endsWith('logo.jpeg', '.png') )// 5.字符串填充,希望长度为2,不够就填充0,填充到你制定的长度console.log(_.padStart('9', 2, '0'))   // 1 -> 01</script>
</body>
</html>

5.7、Lodash-array的操作

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./libs/lodash-4.17.21.js"></script><script>var obj = {}var colors = ['red', 'red', obj, obj,  'green', 'blue', ['orange', 'pink'] ]// 1.数组去重// console.log( _.uniq(colors) )// 2.扁平化// console.log( _.flatten(colors) )// 2.去除数组中假的值console.log( _.compact( [1, 2, {}, '', 0, null, undefined, false, 'red'] ) )</script>
</body>
</html>

5.8、Lodash-object的操作

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./libs/lodash-4.17.21.js"></script><script>var user = {name: 'liujun',age: '17',height: '1.66',friends: ['Evan','John','Mark','Jack','David']}// console.log( _.pick(user, ['name', 'friends']) )// console.log( _.omit(user, ['name', 'friends']) )// console.log( _.clone(user) )console.log( _.cloneDeep(user) )  // 深拷贝</script>
</body>
</html>

5.9、Lodash-object的操作

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./libs/lodash-4.17.21.js"></script><script>var user = {name: 'liujun',age: '17',height: '1.66',friends: ['Evan','John','Mark','Jack','David']}// 浅拷贝(祖宗变孩子也跟着变)--我只想拷贝部分属性// console.log( _.pick(user, ['name', 'friends']) )// 浅拷贝(排除name,friends,其他的我都要)// console.log( _.omit(user, ['name', 'friends']) )// 浅拷贝(克隆user())// console.log( _.clone(user) )// 深拷贝console.log( _.cloneDeep(user) )  // 深拷贝</script>
</body>
</html>

工作中,比如我们需要写防抖、需要写节流、需要函数的柯里化、我们就不需要再耗费很多的时间在去写这个东西、我们直接采用一个库就能解决

5.1、Moment.js库 VS Day.js

  • Moment库,官网的描述
    • Moment 是一个 JavaScript 库,可以帮助我们快速处理时间和日期,已在数百万的项目中使用。
    • Moment对浏览器的兼容性比较好,例如,在Internet Explorer 8+版本运行良好。
    • 现在比较多人反对使用 Moment是因为它的包大小。Moment 不适用于“tree-shaking”算法,因此往往会增加 Web 应用程序包的大小。如果需要国际化或时区支持,Moment 可以变得相当大。
    • 现在比较多人反对使用 Moment是因为它的包大小。Moment 不适用于“tree-shaking”算法,因此往往会增加 Web 应用程序包的大小。如果需要国际化或时区支持,Moment 可以变得相当大。
  • Day.js库,官网的描述:
    • Day.js 是 Moment的缩小版。Day.js 拥有与 Moment相同的 API,并将其文件大小减少了 97%。
    • Moment完整压缩文件的大小为 67+Kb,Day.js 压缩文件只有 2Kb。
    • Day.js所有的 API 操作都将返回一个新的Day.js对象,这种设计能避免 bug 产生,减少调试时间。
    • Day.js 对国际化支持良好。国际化需手动加载,多国语言默认是不会被打包到Day.js中的。
  • tree-shaking算法
    • 打包的时候就不把那些没有用到的函数打包到我们的引用程序中,像一个棵树把枯萎的叶子摇掉一样

5.2、Day.js库安装

方式一:CND

https://unpkg.com/dayjs@1.8.21/dayjs.min.js

<!--CDN example (unpkg)-->
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>

方式二:下载源码引入

<script src="path/to/dayjs/dayjs.min.js"></script>
<script>dayjs().format()</script>

image-20240503003056232

5.3、Day.js初体验

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- window.dayjs = 工厂函数--><script src="./libs/dayjs.js"></script><script>// console.log("%O", dayjs)console.log("%O", dayjs()) // 创建 dayjs 对象console.log(dayjs().format()) // 拿到当前的时间</script></body>
</html>

5.4、手写精简版的Day.js

(function(g){g = typeof globalThis !== 'undefined' ? globalThis : g || self;// 构造函数function Dayjs(dateString) {if (dateString) {var parsedDate = new Date(dateString);if (isNaN(parsedDate.getTime())) {throw new Error('Invalid date format');}this.$Y = parsedDate.getFullYear();this.$M = parsedDate.getMonth();this.$D = parsedDate.getDate();} else {var currentDate = new Date();this.$Y = currentDate.getFullYear();this.$M = currentDate.getMonth();this.$D = currentDate.getDate();}}// 格式化日期Dayjs.prototype.format = function(formatString = 'YYYY-MM-DD') {const year = this.$Y;const month = (this.$M + 1).toString().padStart(2, '0');const day = this.$D.toString().padStart(2, '0');return formatString.replace(/YYYY/g, year).replace(/MM/g, month).replace(/DD/g, day);}// 工厂函数function dayjs(dateString) {return new Dayjs(dateString);}// 原型链处理dayjs.prototype = Object.create(Dayjs.prototype);dayjs.prototype.constructor = dayjs;// 导出g.dayjs = dayjs;
})(this);

使用自定义的day.js

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./utils/HYDayjs.js"></script><script>console.log("%O", dayjs)console.log("%O", dayjs()) // 创建 Dayjs 对象console.log(dayjs().format()) // 拿到当前的时间</script>
</body>
</html>

5.5、Dayjs-获取和设置时间

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./libs/dayjs.js"></script><script >// 1.拿到Dayjs的对象// var day = dayjs()// 获取时间// console.log(day.year(), (day.month() + 1), day.date(), day.hour(), day.minute(), day.second())// 2.设置时间var day = dayjs().year(2021).month(5).date(1)console.log(day.year(), (day.month() + 1), day.date(), day.hour(), day.minute(), day.second())</script>
</body>
</html>

5.6、Dayjs-时间操作

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./libs/dayjs.js"></script><script>// 1.增加一天var day = dayjs() // dayjs 对象// .add(1, 'year') // 增加一年// .add(2, 'month') // 增加2个月// .add(-1, 'month') // 减去一个月// .subtract(1, 'year')  // 减去一年// .subtract(1, 'month')// .subtract(1, 'day') // .startOf('year')  // 一年的开始 2022-01-01 00:00:00// .startOf('month')  // // .startOf('day')  //// 时间的格式化console.log( day.format("YYYY-MM-DD HH:mm:ss") )</script>
</body>
</html>

5.7、Dayjs-时间解析

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./libs/dayjs.js"></script><script>// 1.解析一个字符串(ISO 8601)类型的时间// YYYY-MM-DD HH:mm:ss// YYYY-MM-DD// YYYY/MM/DD// var day = dayjs('2021-2-2 12:00:10') // dayjs 对象// 2.解析时间戳(毫秒)// var day = dayjs(1656206934331) // dayjs 对象// 3.解析时间戳(秒)// var day = dayjs.unix( 1656206934 ) // dayjs 对象// 4.解析Date对象// var day = dayjs(new Date('2022-10-1')) // dayjs 对象// 时间的格式化// console.log( day.format("YYYY/MM/DD HH/mm/ss") )</script>
</body>
</html>

5.8、Dayjs-插件的使用

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="./libs/dayjs.js"></script><!-- 会在 Dayjs 的原型上添加: fromNow .... --><script src="./libs/dayjs.relative-time.min.js"></script><!-- 给给dayjs的全局变量 Ls 添加了一个中文支持--><script src="./libs/dayjs.zh-cn.min.js"></script><script>// 1.安装插件dayjs.extend(dayjs_plugin_relativeTime)// 2.切换使用中文dayjs.locale('zh-cn')// 1. 1小时   5分钟   2天前var day = dayjs(1656206934331) // dayjs 对象console.log(day.fromNow())</script>
</body>
</html>

5.9、DayJs-国际化

当提到 Day.js 或任何日期时间库的“国际化”功能时,它确实指的是根据不同国家或地区的习惯来表示日期和时间。这包括但不限于日期的书写顺序(例如,是“月/日/年”还是“日/月/年”)、使用的语言(如英文的“January”对应中文的“一月”)、以及时间格式(12小时制与24小时制)等。

通过国际化功能,开发者能够确保应用程序中的日期和时间信息能被全球各地的用户准确理解和识别,提升了用户体验,特别是在构建多语言版本的网站或应用时尤为重要。Day.js 通过切换locale(地区语言设置)来实现这一点,确保日期和时间的展示符合用户的地区文化期望。

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

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

相关文章

ESP32 烧录固件

第一步&#xff1a;下载固件 git clone --recursive https://github.com/espressif/esp-at.git 第二步&#xff1a;执行编译 在该目录执行 python build.py install 如图&#xff1a; 第三步&#xff1a;选择芯片 输入2 第四步&#xff1a;选择固件 输入1 第五步&#…

error LNK2001: 无法解析的外部符号 “__declspec(dllimport) public: __cdecl ......

运行程序时&#xff0c;报如上图所示错误&#xff0c;其中一条是&#xff1a; ReflectionProbe.obj : error LNK2001: 无法解析的外部符号 "__declspec(dllimport) public: __cdecl osg::Object::Object(bool)" (__imp_??0ObjectosgQEAA_NZ) 报这个错误一般是因为…

银行ETL-监管报送

1104报表 1104报表主要包括&#xff1a;资产负债&#xff0c;表外业务、流动性风险、贷款质量、投向行业和地区、重点客户等。 1104报表分类 普通报表、机构特色类报表。 反洗钱 大额交易、可疑交易。标签分类&#xff1a;疑似犯罪、疑似毒品、疑似传销。 反洗钱—接口报…

揭秘Fabric交易流程:一文带你深入了解

随着区块链技术的日益普及&#xff0c;Hyperledger Fabric作为一种联盟链解决方案&#xff0c;受到了广泛关注。那么&#xff0c;Fabric的交易流程究竟是怎样的呢&#xff1f;本文将为您一一揭晓。 1. Fabric交易的参与方 客户端&#xff1a;交易流程的发起方&#xff0c;发起…

Windows 容器镜像踩坑记录

为什么研究windows容器&#xff1f;emm&#xff0c;公司需要&#xff0c;不想多说。 dotnet后端 问题描述&#xff1a; 基于mcr.microsoft.com/dotnet/aspnet:6.0镜像撰写dockerfile编译.net core后端项目后运行容器出现类库不存在问题&#xff1a; 程序中使用了fastreport&a…

数据库(MySQL)—— DQL语句(基本查询和条件查询)

数据库&#xff08;MySQL&#xff09;—— DQL语句&#xff08;基本查询和条件查询&#xff09; 什么是DQL语句基本查询查询多个字段字段设置别名去除重复记录 条件查询语法条件 我们今天进入MySQL的DQL语句的学习&#xff1a; 什么是DQL语句 MySQL中的DQL&#xff08;Data Q…

【论文】关于网页上能打开的文章下载PDF“显示无效或损坏的 PDF 文件”的解决办法

1. 遇到的问题 今天我在 dl.acm.org/doi 下载论文时发现下载后的pdf打开出现“显示无效或损坏的 PDF 文件” 可是在原网址是可以打开并显示的 2. 解决方案 这里我用到了和之前【论文】去除PDF论文行号的完美解决方案 的相似的解决办法 就是下载的时候不直接下载&#xf…

【前端项目——分页器】手写分页器实现(JS / React)

组件介绍 用了两种方式实现&#xff0c;注释详细~ 可能代码写的不够简洁&#xff0c;见谅&#x1f641; 1. 包含内容显示的分页器 网上看了很多实现&#xff0c;很多只有分页器部分&#xff0c;没和内容显示联动。 因此我增加了模拟content的显示&#xff0c;这里模拟了32条数…

环形链表面试题详解

A. 环形链表1 给你一个链表的头节点 head &#xff0c;判断链表中是否有环. 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置…

【数据结构】第四讲:双向链表

目录 一、链表的分类 二、双向链表的结构及实现 1.带头双向链表的结构 2.创建节点 3.初始化 4.尾插 5.打印 6.头插 7.尾删 8.头删 9.在pos位置之后插入数据 10.删除pos节点 11.查找 12.销毁 个人主页&#xff1a;深情秋刀鱼-CSDN博客 数据结构专栏&#xff1a;数…

虚拟化技术 安装并配置ESXi服务器系统

安装并配置ESXi服务器系统 一、实验目的与要求 1.掌握创建VMware ESXi虚拟机 2.掌握安装VMware ESXi系统 3.掌握配置VMware ESXi系统的管理IP 4.掌握开启VMware ESXi的shell和ssh功能的方法 二、实验内容 1.安装VMware workstation 15或更高版本 2.创建VMware ESXi虚拟…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(三)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; 继续接上一篇文章内容&#xff0c;讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 当我们点击 submit 提…

基于t972 Android9 AP6256,如何在设置中添加5G热点选项,并使其正常打开

通过设置的的WiFi热点选项可以知道关键词“2.4GHz”&#xff0c;因此可以其全局搜索&#xff0c;在packages\apps\Settings\res\values\strings.xml文件下找到如下图所示&#xff0c; 从上面注释可以知道&#xff0c;选项按键选择2.4GHz触发的按键关键词是“wifi_ap_choose_2G…

✔ ★Java项目——设计一个消息队列(五)【虚拟主机设计】

虚拟主机设计 创建 VirtualHost实现构造⽅法和 getter创建交换机删除交换机创建队列删除队列创建绑定删除绑定发布消息 ★路由规则1) 实现 route ⽅法2) 实现 checkRoutingKeyValid3) 实现 checkBindingKeyValid4) 实现 routeTopic5) 匹配规则测试⽤例6) 测试 Router 订阅消息1…

分布式websocket IM即时通讯聊天开源项目如何启动

前言 自己之前分享了分布式websocket的视频有同学去fork项目了&#xff0c;自己启动一下更方便理解项目嘛。然后把项目启动需要的东西全部梳理出来。支持群聊单聊,表情包以及发送图片。 支持消息可靠&#xff0c;消息防重&#xff0c;消息有序。同时基础架构有分布式权限&…

深入教程:在STM32上实现能源管理系统

引言 能源管理系统&#xff08;EMS&#xff09;在提高能源效率、减少能源消耗和支持可持续发展方面起着关键作用。本教程将介绍如何在STM32微控制器上开发一个能源管理系统&#xff0c;这种系统能够监控和控制能源使用&#xff0c;适用于家庭自动化、工业控制系统以及任何需要…

jQuery Moblie 笔记14 开发跨平台移动设备网页

相关内容&#xff1a;jQuery Moblie基础、操作、移动设备仿真器、jQuery Moblie网页实例、jQuery Moblie的UI组件、…… jQuery推出了一套新的函数库jQuery Mobile&#xff0c;目的是希望能够统一当前移动设备的用户界面(UI)。 移动设备开发应用程序目前大致分为两种&#xff…

MLP手写数字识别(3)-使用tf.data.Dataset模块制作模型输入(tensorflow)

1、tensorflow版本查看 import tensorflow as tfprint(Tensorflow Version:{}.format(tf.__version__)) print(tf.config.list_physical_devices())2、MNIST数据集下载与预处理 (train_images,train_labels),(test_images,test_labels) tf.keras.datasets.mnist.load_data()…

强大而简洁:初学Python必须掌握的14个单行代码

Python的魅力与单行代码的重要性 Python&#xff0c;作为一种高级编程语言&#xff0c;自诞生以来就以其简洁、易读、易学的特性而广受开发者喜爱。其魅力不仅在于其强大的功能和广泛的应用领域&#xff0c;更在于其能够用简洁的代码实现复杂的功能&#xff0c;这种能力在很大…

Redisson 分布式锁和同步器

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 redisson 是基于redis的扩展库,使得redis除了应用于缓存以外,还能做队列…