提交 d4510dd3 编写于 作者: 杨若瑜's avatar 杨若瑜

完成Objs工具编写

上级 168f452a
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
瑜美科技出品
强大的前端库
\ No newline at end of file
# YumeiSoft.CommonFrontUtils
## 瑜美科技出品
强大的通用前端算法库
如何启动演示:
```
yarn install
yarn start
```
目录结构:
```
src React项目
src/demo 示例
src/Yumeisoft/CommonFrontUtils 源代码
```
工具类型:
```
Objs 对象数组操作工具
Obj 对象操作工具
List 数组操作工具
```
\ No newline at end of file
{
"name": "commonfrontutils",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
import React, { Component } from 'react';
import Welcome from './demo/Welcome';
import ObjsDemo from './demo/ObjsDemo';
export default class App extends Component {
constructor() {
super();
this.state = { demo: Welcome };
}
render() {
let DemoTarget = this.state.demo;
return (
<>
<div>
<button
onClick={() => {
this.setState({ demo: Welcome });
}}>
首页
</button>
<button
onClick={() => {
this.setState({ demo: ObjsDemo });
}}>
演示Objs
</button>
</div>
<div>
<DemoTarget />
</div>
</>
);
}
}
/**
* Copyright (c) 2020 YumeiSoft
* CommonFrontUtils is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* List 数组操作工具
* @author 黑龙江省瑜美科技发展有限公司 杨若瑜
* @since 2020年09月12日
*/
class List {
constructor(input) {
this.input = input;
}
/** 取纯数字部分 */
nums() {
let result = [];
for (let i in this.input) {
let item = this.input[i];
if (!isNaN(item) && item !== Infinity) {
result.push(Number(item));
}
}
return result;
}
/** 计算平均值 */
avg(num) {
let nums = this.nums();
let sum = this.sum();
if (num) {
return sum / num;
} else {
return sum / nums.length;
}
}
/** 求最大值 */
max() {
return Math.max(...this.nums());
}
/** 求最小值 */
min() {
return Math.min(...this.nums());
}
/** 求和 */
sum() {
let sum = 0;
let nums = this.nums();
for (let i in nums) {
sum += nums[i];
}
return sum;
}
/** 获得数量 */
count(){
return this.input.length;
}
}
export default (input) => {
return new List(input);
};
/**
* Copyright (c) 2020 YumeiSoft
* CommonFrontUtils is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* Obj 对象操作工具
* @author 黑龙江省瑜美科技发展有限公司 杨若瑜
* @since 2020年09月12日
*/
class Obj {
constructor(input) {
this.input = input;
}
/** 转成JSON字符串 */
toJson(){
return JSON.stringify(this.input);
}
/** 通过序列化和反序列化深拷贝对象 */
deepClone(){
return JSON.parse(this.toJson(this.input));
}
/** 获取当前对象所有键 */
keys() {
if (!this.input) return [];
return Object.keys(this.input);
}
/** 判断是否为字符串 */
isStr() {
return typeof this.input === 'string';
}
/** 判断是否为空 */
isNull() {
if (this.input === null) return true;
}
/** 判断是否为数字 */
isNum() {
return typeof this.input === 'number';
}
/** 判断是否与目标对象的值相等 */
eq(target) {
if (this.input === target) return true;
if(this.isNum()||new Obj(target).isNum()){
if(Number(this.input)===Number(target)){
return true;
}
}
if(this.isStr()||new Obj(target).isStr()){
if(String(this.input)===String(target)){
return true;
}
}
return false;
}
}
export default (input) => {
return new Obj(input);
};
/**
* Copyright (c) 2020 YumeiSoft
* CommonFrontUtils is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import Obj from './Obj';
import List from './List';
/**
* Objs 对象数组操作工具
* @author 黑龙江省瑜美科技发展有限公司 杨若瑜
* @since 2020年09月12日
*/
class Objs {
constructor(input) {
this.input = input;
this.funcList = [];
this.deepCloned = false;
}
/** 增加判断条件 */
filter(func) {
this.funcList.push(func);
return this;
}
/** 列出所有符合判断条件的数据 */
list() {
let result = [];
let funcList = this.funcList;
outer: for (let i in this.input) {
let obj = this.input[i];
for (let j in funcList) {
if (!funcList[j](obj)) {
continue outer;
}
}
result.push(obj);
}
return result;
}
/** 遍历回调 */
each(func) {
let list = this.list();
let result = [];
for (let idx in list) {
let item = list[idx];
let handleResult = func(item, idx);
if (handleResult || handleResult == null) {
result.push(handleResult);
} else {
result.push(item);
}
}
return result;
}
/** 只取出一个符合条件的数据 */
one(column, value) {
if (column && value) {
this.filter((o) => Obj(o[column]).eq(value));
}
let listResult = this.list();
if (Obj(listResult.length).eq(1)) {
return listResult[0];
} else if (Obj(listResult.length).eq(0)) {
throw new Error('DataNotFound');
} else if (listResult.length > 1) {
throw new Error('DataNotSingle');
}
}
/** 建立映射关系表 */
keyColumn(keyColumn, valueColumn) {
let listResult = this.list();
let result = {};
for (let i in listResult) {
let key = listResult[i][keyColumn];
let value = listResult[i][valueColumn];
result[key] = value;
}
return result;
}
/** 建立主键-对象映射关系表 */
keyObj(keyColumn) {
let listResult = this.list();
let result = {};
for (let i in listResult) {
let key = listResult[i][keyColumn];
result[key] = listResult[i];
}
return result;
}
/** 抽取某个字段 */
colList(colName) {
let result = [];
this.each((item) => {
result.push(item[colName]);
});
return result;
}
/** 抽取多个字段 */
colLists(colNames) {
if (!colNames) {
colNames = this.colNames();
}
colNames = new Objs(colNames);
let result = {};
this.each((item) => {
colNames.each((colName) => {
if (!result[colName]) {
result[colName] = [];
}
result[colName].push(item[colName]);
});
});
return result;
}
/** 取平均值 */
colAvg(columnName) {
let fieldResult = this.colList(columnName);
return List(fieldResult).avg();
}
/** 取最大值 */
colMax(columnName) {
let fieldResult = this.colList(columnName);
return List(fieldResult).max();
}
/** 取最小值 */
colMin(columnName) {
let fieldResult = this.colList(columnName);
return List(fieldResult).min();
}
/** 计数 */
count() {
let listResult = this.list();
return listResult.length;
}
/** 求和 */
colSum(columnName) {
let fieldResult = this.colList(columnName);
return List(fieldResult).sum();
}
/** 取出所有键名 */
colNames() {
let result = [];
let listResult = this.list();
for (let i in listResult) {
let keys = Obj(listResult[i]).keys();
for (let keyIdx in keys) {
let key = keys[keyIdx];
if (!result.includes(key)) {
result.push(key);
}
}
}
return result;
}
/** 取出公共键名 */
sharedColNames() {
let result = [];
let listResult = this.list();
for (let i in listResult) {
let keys = Obj(listResult[i]).keys();
if (Obj(i).eq(0)) {
result = keys;
continue;
}
for (let resultIdx in result) {
let key = result[resultIdx];
if (!keys.includes(key)) {
result.splice(resultIdx, 1);
}
}
}
return result;
}
/** 转换成二维数组 */
toLists(colNames) {
if (!colNames) {
colNames = this.colNames();
}
colNames = new Objs(colNames);
let result = this.each((item) => {
let colVals = [];
colNames.each((colName) => {
colVals.push(item[colName]);
});
return colVals;
});
return result;
}
/** 分组 */
group(func) {
let getGroupKey = func;
// 单字段分组
if (Obj(typeof func).eq('string')) {
let colName = func;
getGroupKey = (item) => {
return item[colName];
};
}
// 多字段分组
if (Array.isArray(func)) {
let colNames = new Objs(func);
getGroupKey = (item) => {
let keyObj = colNames.each((colName) => {
return item[colName];
});
return JSON.stringify(keyObj);
};
}
let result = {};
this.each((item) => {
let groupKey = getGroupKey(item);
if (!result[groupKey]) {
result[groupKey] = [];
}
result[groupKey].push(item);
});
return result;
}
/** 聚合分组 */
aggGroup(func, colName, oper) {
let groupData = this.group(func);
let aggFunc = oper;
// 预设聚合方式
if (Obj(typeof oper).eq('string')) {
aggFunc = (list) => {
return List(list)[oper]();
};
}
for (let key in groupData) {
let groupList = groupData[key];
let colList = new Objs(groupList).colList(colName);
let aggResult = aggFunc(colList);
groupData[key] = aggResult;
}
return groupData;
}
/** 深拷贝 */
deepClone() {
this.input = Obj(this.input).deepClone();
this.deepCloned = true;
return this;
}
/** 转树形结构 */
toTrees(id, pid, branchName) {
let list = new Objs(this.list());
let result = [];
let idMap = list.keyObj(id);
let pidMap = list.group(pid);
for (let key in pidMap) {
let branchObjs = pidMap[key];
if (branchObjs) {
if (idMap[key]) {
idMap[key][branchName] = branchObjs;
} else {
new Objs(branchObjs).each((item) => result.push(item));
}
}
}
return result;
}
/** 升序排列 */
sortBy(columnName) {
let sortColumn = columnName;
let nextSortColumns = [];
// 如果是多字段
if (Array.isArray(sortColumn)) {
if (sortColumn.length === 0) {
return this.list();
}
sortColumn = columnName[0];
nextSortColumns = columnName.splice(1);
}
let listResult = this.list();
let listMap = {};
let orderedMap = {};
let result = [];
for (let i in listResult) {
let sortVal = listResult[i][sortColumn];
if (!listMap[sortVal]) {
listMap[sortVal] = [];
}
listMap[sortVal].push(listResult[i]);
}
Object.keys(listMap)
.sort()
.forEach((key) => {
orderedMap[key] = listMap[key];
});
for (let key in orderedMap) {
let objs = orderedMap[key];
objs = new Objs(objs).sortBy(nextSortColumns);
result.push(...objs);
}
return result;
}
/** 倒序排列 */
sortDescBy(columnName) {
return this.sortBy(columnName).reverse();
}
}
export default (input) => {
return new Objs(input);
};
import React, { Component } from 'react';
import ObjsService from './ObjsService';
/** 输入参数 */
let input = [
{
id: '823585b8-062d-4e15-b17c-2d8932d4a1a4',
name: '张三',
age: '25',
balance: 1000,
gender: '',
dept: '采购部',
post: '部门经理',
superior: '1bc06853-b0fd-4cbc-9d53-16c054b8ca9b',
},
{
id: '39d2fd99-00f5-4996-9a3f-165148ab7972',
name: '李四',
age: 17,
balance: 400,
gender: '',
dept: '技术部',
post: '管理培训生',
deptId: '2',
superior: '37f15bff-e0ee-4b44-9291-5c9fa0bcf954',
},
{
id: '37f15bff-e0ee-4b44-9291-5c9fa0bcf954',
name: '王五',
age: 30,
balance: 500,
gender: '',
dept: '技术部',
post: '部门经理',
superior: '1bc06853-b0fd-4cbc-9d53-16c054b8ca9b',
},
{
id: '0f0479cc-59fe-4c56-9685-75c4067300b6',
name: '小红',
age: 16,
balance: 200,
gender: '',
dept: '采购部',
post: '管理培训生',
superior: '823585b8-062d-4e15-b17c-2d8932d4a1a4',
},
{
id: 'f01430fd-5df3-402a-92ef-aca63d882e2b',
name: '小明',
age: 24,
balance: 700,
gender: '',
dept: '技术部',
post: '管理培训生',
superior: '37f15bff-e0ee-4b44-9291-5c9fa0bcf954',
},
];
export default class extends Component {
constructor() {
super();
this.state = {
inputText: JSON.stringify(input, null, 2),
};
this.demos = new ObjsService().getDemos();
}
run(testUnit, input) {
this.setState({
execFunc: String(this.demos[testUnit]).replace(new RegExp('Obj(.)+?\\)'), 'Objs'),
});
return this.demos[testUnit](input);
}
execute(testUnit) {
let outputText;
try {
let input = JSON.parse(this.state.inputText);
let output = this.run(testUnit, input);
outputText = JSON.stringify(output, null, 2);
} catch (e) {
console.error(e);
outputText = '执行出错:\n' + e.message;
}
this.setState({
outputText,
});
}
render() {
let { inputText, outputText } = { ...this.state };
return (
<>
<div>
<div>输入:</div>
<textarea
style={{ width: '500px', height: '200px' }}
onChange={(event) => {
this.setState({
inputText: event.target.value,
});
}}
value={inputText}
/>
<div style={{ width: '800px' }}>
{Object.keys(this.demos).map((item, key) => {
return (
<button key={key} onClick={this.execute.bind(this, item)}>
{item}
</button>
);
})}
</div>
{this.state.execFunc && (
<>
<div>示例代码:</div>
<div>
<pre>{this.state.execFunc}</pre>
</div>
</>
)}
{outputText && (
<>
<div>输出:</div>
<textarea style={{ width: '500px', height: '200px' }} value={outputText} onChange={() => {}} />
</>
)}
</div>
</>
);
}
}
import Objs from '../Yumeisoft/CommonFrontUtils/Objs';
/**
* Objs对象数组操作工具演示
* @author 黑龙江省瑜美科技发展有限公司 杨若瑜
* @since 2020年09月12日
*/
export default class Demo {
getDemos() {
return {
自定义过滤: (input) => {
return Objs(input)
.filter((item) => item.age > 18)
.list();
},
依据主键获取对象Object: (input) => {
return Objs(input).one('id', '0f0479cc-59fe-4c56-9685-75c4067300b6');
},
抽取指定字段映射表Map: (input) => {
return Objs(input).keyColumn('id', 'name');
},
'获取映射表Key-Object': (input) => {
return Objs(input).keyObj('id');
},
单取name集合: (input) => {
return Objs(input).colList('name');
},
取age的平均值: (input) => {
return Objs(input).colAvg('age');
},
取age的最大值: (input) => {
return Objs(input).colMax('age');
},
取age的最小值: (input) => {
return Objs(input).colMin('age');
},
取balance的和: (input) => {
return Objs(input).colSum('balance');
},
取出字段名的List: (input) => {
return Objs(input).colNames();
},
取出公共键名的List: (input) => {
return Objs(input).sharedColNames();
},
自定义遍历获取List: (input) => {
return Objs(input).each((item) => (item.status = 0));
},
高级自定义遍历获取List: (input) => {
return Objs(input).each((item, index) => {
item.status = 0;
if (item.age > 18) item.status = 1;
item.emptno = '2020' + (Array(2).join(0) + (Number(index) + 1)).slice(-2);
return item;
});
},
转换为二维数组Lists: (input) => {
return Objs(input).toLists();
},
按指定字段转换为二维数组获取Lists: (input) => {
return Objs(input).toLists(['name', 'age']);
},
'抽取所有字段组成Key-List': (input) => {
return Objs(input).colLists();
},
'抽取指定字段组成Key-List': (input) => {
return Objs(input).colLists(['name', 'gender']);
},
'单字段分组获取Key-Objects': (input) => {
return Objs(input).group('dept');
},
'多字段分组获取Key-Objects': (input) => {
return Objs(input).group(['dept', 'gender']);
},
'自定义分组获取Key-Objects': (input) => {
return Objs(input).group((item) => {
if (item.age >= 30) {
return '30岁及以上';
} else {
return '30岁以下';
}
});
},
浅拷贝操作: (input) => {
console.warn('操作前原对象');
console.log(JSON.stringify(input, null, 2));
let result = Objs(input).each((item) => (item.name = '请在控制台查看输出'));
console.warn('操作后原对象');
console.log(JSON.stringify(input, null, 2));
return result;
},
深拷贝操作: (input) => {
console.warn('操作前原对象');
console.log(JSON.stringify(input, null, 2));
let result = Objs(input)
.deepClone()
.each((item) => (item.name = '请在控制台查看输出'));
console.warn('操作后原对象');
console.log(JSON.stringify(input, null, 2));
return result;
},
转树形结构获取Trees: (input) => {
return Objs(input).toTrees('id', 'superior', 'subordinates');
},
'聚合分组-计数': (input) => {
return Objs(input).aggGroup('dept', 'id', 'count');
},
'聚合分组-平均': (input) => {
return Objs(input).aggGroup('gender', 'balance', 'avg');
},
'聚合分组-自定义': (input) => {
return Objs(input).aggGroup(
(item) => {
if (item.age >= 30) {
return '30岁及以上男性比例';
} else {
return '30岁以下男性比例';
}
},
'gender',
(aggList) => {
let maleCount = 0;
for (let i in aggList) {
if (aggList[i] === '') maleCount++;
}
return (maleCount / aggList.length) * 100 + '%';
}
);
},
单字段升序排列: (input) => {
return Objs(input).sortBy('age');
},
多字段升序排列: (input) => {
return Objs(input).sortBy(['dept','age']);
},
单字段降序排列: (input) => {
return Objs(input).sortDescBy('age');
},
多字段降序排列: (input) => {
return Objs(input).sortDescBy(['dept','age']);
},
};
}
}
import React, { Component } from 'react'
export default class Welcome extends Component {
render() {
return (
<div>
欢迎使用Yumeisoft.CommonFrontUtils
</div>
)
}
}
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.0/8 are considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export function register(config) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Let's check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://bit.ly/CRA-PWA'
);
});
} else {
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
}
}
function registerValidSW(swUrl, config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
);
// Execute callback
if (config && config.onUpdate) {
config.onUpdate(registration);
}
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
// Execute callback
if (config && config.onSuccess) {
config.onSuccess(registration);
}
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl, config) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl, {
headers: { 'Service-Worker': 'script' },
})
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get('content-type');
if (
response.status === 404 ||
(contentType != null && contentType.indexOf('javascript') === -1)
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl, config);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready
.then(registration => {
registration.unregister();
})
.catch(error => {
console.error(error.message);
});
}
}
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册