json转js与js转json以及练习了ajax-xhr/fetch异步通讯以及模块常识,其中Promise状态及Promise中的Fetch API部分暂时还没进行示例学习操作
程序员文章站
2022-04-17 19:01:16
...
JSON与js对象方法互转
用到了俩函数
JSON.stringify js转json
JSON.parse json转js
示例代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>json加长版</title>
</head>
<body>
<script>
// js对象转前端json
const ad = {
name: "老卢",
email: "123456@qq.com",
gender: "male",
salary: 123456,
// toJSON() {
// return `name:${this.name},email:${this.email}`;
// },
};
// console.log(ad.toJSON());
// 返回了老卢和邮箱
// 序列号json:JSON.stringify
// JSON.stringify支持对json序列化的格式化,,后面增加一个nell空,2是空格或者别的符号,默认是空格
let jsonstr = JSON.stringify(ad, null, 2);
console.log(jsonstr);
// 第二个参数 array,callback
// array 以数组方式限制返回,
jsonstr = JSON.stringify(ad, ["name", "gender"]);
// 看到结果只返回了名字跟性别
console.log(jsonstr);
//callback 还可以以方法的形式去控制输出
jsonstr = JSON.stringify(ad, function (key, value) {
switch (key) {
// 这里根据键来判断
// 键是性别
case "gender":
// 返回的值是male,那就是男的,其他默认女的
return value === "male" ? "男" : "女";
// 如果查询的是工资 返回一个undefined,在json是不允许undefined的
case "salary":
return undefined;
// 其他默认返回值
default:
return value;
}
});
console.log(jsonstr);
// 第三个参数:参数的格式化
jsonstr = JSON.stringify(ad, null, 2);
console.log(jsonstr); //默认两个空格
jsonstr = JSON.stringify(ad, null, "**");
console.log(jsonstr); //把空格格式换为**
// 2. jsonStr -> jsObj: json字符串[后端] -> js对象[前端]
// JSON.parse
// 1. 所有属性必须使用双引号
// 2. 字符类型的值必须使用双引号
// 3. 不能有undefined
// 4. 最后一个值后不能有逗号
//////////////////////////////////////////
/////////////json转js/////////////////////
/////////////使用JSON.parse(siteinfo)/////
//声明一个json对象
const siteInfo = `
{
"name":"PHP中文网",
"domain":"https://www.php.cn",
"isRecord":true,
"email":"498668472@qq.com",
"address":"合肥市政务新区蔚蓝商务港",
"category":["视频","文章","资源"],
"lesson": {
"name": "第18期Web全栈线上培训班",
"price": 4800,
"content": ["JavaScript", "PHP", "ThinkPHP"]
}
}
`;
console.log(siteInfo); //已经是json格式,转成js格式
let site = JSON.parse(siteInfo);
console.log(site);
site = JSON.parse(siteInfo, function (key, value) {
// 如果键返回email或者address 则删除
if (key === "email" || key === "address") {
delete this[key];
} else {
return value;
}
});
console.log(site);
let html = `
<li> 网站名称:${site.name} </li>
<li>网站域名:${site.domain.slice(8)}</li>
<li>网站备案:${site.isRecord ? "已备案" : "未备案"}</li>
<li>联系邮箱:${site.email}</li>
<li>联系地址:${site.address}</li>
<li>服务内容:<ul>
<li style="color:red">1. arry.map()</li>
${site.category
.map(function (value) {
return "<li>" + value + "</li>";
}) //.join将元素数组,转成换字符串
.join("")}
<li style="color:red">2. arry.reduce()</li>
${site.category.reduce((acc, cur) => `${acc}</li><li>${cur}`, "")}
</ul></li>
<li>课程信息:
<ul>
<li style="color:red"> 1: 根据键名获取值</li>
${Object.keys(site.lesson).map(function (key) {
//根据键返回值
`<li>${site.lesson[key]}</li>`;
})}
<li style="color: red"> 2: 直接获取值</li>
${Object.values(site.lesson)
.map(less => `<li>${less}</li>`)
.join("")}
</ul>
`;
/////开始渲染到页面,新建一个ul标签
const ul = document.createElement("ul");
ul.innerHTML = html; //html塞到ul下面
document.body.append(ul); //将ul塞到body里面
</script>
<!-- Object.values 与之相反 -->
<!-- let person = {name:"张三",age:25,address:"深圳",getName:function(){}}
Object.keys(person).map((key)=>{ person[key] // 获取到属性对应的值,做一些处理 }) -->
</body>
</html>
示例截图:
ajax-xhr/fetch异步通讯
代码部分:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ajax-xhr-fetch异步</title>
</head>
<button onclick="getUser1(this)">查询用户信息 - XHR</button>
<button onclick="getUser2(this)">查询用户信息 - Fetch</button>
<body></body>
<script>
// 1. 传统 XHR
/**
* 1. 创建对象: new XMLHttpRequest();
* 2. 响应类型: xhr.responseType = "json";
* 3. 配置参数: xhr.open("GET", url, true);
* 4. 请求回调: xhr.onload = () => console.log(xhr.response);
* 5. 失败回调: xhr.onerror = () => console.log("Error");
* 6. 发起请求: xhr.send(null);
*
* xhr 至少监听2个事件: load,error, 调用2个函数: open,send
* post请求,需要设置一下请求头与请求的数据,其它与get请求完全相同
*/
function getUser1(btn) {
// 创建一个对象
const xhr = new XMLHttpRequest();
// 数据类型,当前获取到的数据类型 例如是json
xhr.responseType = "json";
// 请求的类型方式,是post还是get 包括请求的url,这里的url暂定,一会声明一个
let url = "http://website.io/users.php";
url = "http://website.io/users.php?id=2";
xhr.open("GET", url, true);
//返回成功后需要处理的步骤(老师说是回调) 请求成功用xhr.onload
xhr.onload = () => {
console.log(xhr.response);
render(xhr.response, btn); //将结果渲染到bth按钮输出到页面中,render在function.js里面的定义的一个函数
}; //结果是储存到xhr.response中,所以你可以对结果进行预处理
//返回失败后需要处理的步骤(失败的回调) 请求失败用xhr.onerror
xhr.onerror = () => console.log("Error"); //失败的回调,也可以渲染到页面中,比如提示给用户失败
// 最后发起请求
xhr.send(null);
}
// 2. 现代 Fetch
/** 语法:
fetch(...)//请求的url
.then(...)请求成功返回的数据,
.then(...)并且then可以链式调用,比如拿到数据后渲染到页面,以及其他的操作
.catch(...) 403错误返回的请求数据
*/
function getUser2(btn) {
//当无get请求参数时,返回全部数组用户,用表格显示(已经封装到了function.js当中)
//有get时,根据functin.js当中的返回数据,返回指定id,单调数据,具体请看function.js中代码
let url = "http://website.io/users.php";
fetch(url)
.then(response => response.json()) //请求成功返回的json单条或数组的内容
.then(json => {
console.log(json);
render(json, btn);
})
.catch(err => console.log("Fetch Error", err));
}
</script>
<!-- //引入function.js -->
<script src="function.js"></script>
</html>
示例截图:
下面是老师的配置文件(如需测试,自行拿取)
跨域请求端口:
<?php
// 允许跨域请求
header('access-control-allow-origin: *');
// 用户数据
$users = require 'data.php';
// 如果没有get参数,就返回全部用户数据
if (!isset($_GET['id'])) {
echo json_encode($users);
die();
}
// 如果有get参数,如 id=1,则返回指定的一个用户信息
$id = $_GET['id'] ?? false;
if (in_array($id, array_column($users, 'id'))) {
foreach ($users as $user) {
if ($user['id'] == $id) {
// 密码不需要返回,过滤掉
array_pop($user);
echo json_encode($user);
}
}
} else {
echo json_encode('没有该用户');
}
数据存放接口:
<?php
return [
["id" => 1, 'name' => '猪老师', 'email' => 'zhu@php.cn', 'password' => md5('123')],
["id" => 2, 'name' => '灭绝', 'email' => 'mj@php.cn', 'password' => md5('456')],
["id" => 3, 'name' => '欧阳', 'email' => 'oy@php.cn', 'password' => md5('789')],
];
渲染封包接口:
// 渲染用户数据到页面中
function render(data, btn) {
// 1. 如果是数组,则创建表格展示
if (Array.isArray(data)) {
// 创建表格
const table = document.createElement("table");
// 设置表格样式
table.border = 1;
table.cellPadding = 3;
table.cellSpacing = 0;
table.width = 360;
// 设置标题
const caption = table.createCaption();
caption.textContent = "用户信息列表";
caption.style.fontSize = "18px";
caption.style.fontWeight = "bolder";
caption.style.marginBottom = "8px";
// 创建表头
const thead = table.createTHead();
thead.style.backgroundColor = "lightcyan";
thead.innerHTML = "<tr><th>ID</th><th>用户名</th><th>邮箱</th></tr>";
// 创建表格主体
const tbody = table.createTBody();
tbody.align = "center";
// 遍历数组
data.forEach(user => {
let html = `
<tr>
<td>${user.id}</td><td>${user.name}</td><td>${user.email}</td>
</tr>
`;
// 插入到表格中
tbody.insertAdjacentHTML("beforeEnd", html);
});
// 防止重复生成表格,应该判断一下当前按钮的下一个兄弟是否是表格
if (btn.nextSibling.tagName !== "TABLE") {
btn.after(table);
}
}
// 2. 如果是单个对象,则用列表渲染
else {
// 创建列表元素,用于显示用户信息
const ul = document.createElement("ul");
// 使用模板字面量,快速创建用户数据
ul.innerHTML = `
<li>ID : <span class="user">${data.id}</span></li>
<li>用户名 : <span class="user">${data.name}</span></li>
<li>邮箱 : <span class="user">${data.email}</span></li>
`;
// 与上面功能一样,也是为了防止重复创建列表
if (btn.nextSibling.tagName !== "UL") {
btn.after(ul);
// 添加自定义样式,将用户信息高亮显示
document.querySelectorAll("ul li .user").forEach(item => (item.style.color = "red"));
}
}
}
Promise状态及Fetch API在1月10日课件dom3-dom6中,其中dom6是fetch/promise的api操作,类似fetch中的异步
js导入模块操作
模块的概念,模块就是一个js文件,可以内部成员全部私有,通过导出对象来引用
白话就是,本来js文件点进去所有人都能看,你把js文件给私有化了,然后进行了导入js文件里面的一些函数,比如计算,判断,加减乘除乱七八糟的模块,你经常用,但是不想每次都写一个函数,那么就封装在模块里面,导入直接使用
示例模块,命名为m1.js
export
控制导出的模块名,放在函数中,例如export { user, hello, email }
;,支持重命名导出,例如export { user as user1, hello, email };
let user = "猪老师";
function hello(name) {
return "Hello " + name;
}
let email = "498668472@qq.com";
// export { user as user1, hello, email };
export { user, hello, email };
html中的js代码:
<!DOCTYPE html>
<html lang="zh-CN">
<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>模块常识</title>
</head>
<body>
<script type="module">
// type="module": 支持模块系统
// 模块就是一个js文件,内部成员全部私有,通过导出对象来引用
// 1. 导入模块
// import { user as user1, hello, email } from "./m1.js";
import { user, hello, email } from "./m1.js";
// let user = "灭绝";
// console.log(user1);
console.log(user);
console.log(hello(user));
console.log(email);
</script>
</body>
</html>
导出为默认成员:
m2.js代码
let user = "猪老师";
function hello(name) {
return "Hello " + name;
}
let email = "498668472@qq.com";
// hello 默认导出的成员
export { user, hello as default, email };
默认成员在html中的部分:
<!DOCTYPE html>
<html lang="zh-CN">
<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>模块常识</title>
</head>
<body>
<script type="module">
// 1. 导入模块
// 模块中的默认成员, 使用独立变量接收,如import hello
import hello, { user, email } from "./m2.js";
console.log(user);
console.log(hello(user));
console.log(email);
</script>
</body>
</html>
导出默认成员时增加一个命名空间
m3.js代码:
let user = "猪老师";
function hello(name) {
return "Hello " + name;
}
let email = "498668472@qq.com";
const APP = "商城";
// hello 默认导出的成员
export { user, hello, email, APP };
但在html中将改变:
例如:import * as phpcn,使用命名空间后,所有的代码将遵循使用命名空间名phpcn.模块函数名
<!DOCTYPE html>
<html lang="zh-CN">
<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>模块常识</title>
</head>
<body>
<script type="module">
// 1. 导入模块
// import { hello, APP, user, email } from "./m3.js";
// 当导入成员较多时,使用命名空间来简化
// 命名空间,就是一个对象,只不过这个对象是在当前模块/脚本中是唯一的
import * as phpcn from "./m3.js";
console.log(phpcn.user);
console.log(phpcn.hello(phpcn.user));
console.log(phpcn.cnemail);
console.log(phpcn.APP);
</script>
</body>
</html>