我正在参加「掘金·启航计划」
是的,我就是想要掘金包包,熬夜写下这篇文章。可能你觉得水,但你不能质疑我想要包包的精神!!
这篇文章适用于使用yapi平台管理接口的同学阅读,不过,如果贵司用别的接口管理平台的话也可来参考参考哦
代码地址(遇到不懂的地方可以直接对照源码)
背景
原因我们Chrome扩展插件只能一个接口一个接口的生成代码,需要实现一个批量生成接口代码的功能,于是leader钉钉发给我一个链接就让我搞(还挺有良心,知道我没接触过Chrome插件)。
于是搜索了下相关Chrome开发知识,我们就能上手开发了
前期准备工作
有了扩展插件开发的基础知识,很容易就能上手了。
manifest.json
创建一个文件夹 custom-api
在根目录创建文件manifest.json,这个文件是扩展必须的文件,是用来描述扩展的功能和配置
manifest.json
{
"manifest_version": 3,
"name": "Hello Extensions",
"description": "Base Level Extension",
"version": "1.0",
"action": {
"default_popup": "hello.html", //点击图表弹出的窗口
"default_icon": "hello_extensions.png" // 扩展图标
}
}
自己准备图标
根目录下创建hello.html (点击图表弹出的窗口)
<html>
<body>
<h1>Hello Extensions</h1>
</body>
</html>
当前目录是这样的
├── hello.html
├── hello_extensions.png
└── manifest.json
接下来就可以放到浏览器扩展工具里面看效果了
构建项目
需要通过jq去操作dom,在项目中引入jquery
需要一个树插件引入,我选择了zTree
我们对扩展程序有了一个基础的认识,现在调整下目录结构,让它看起来更规范
调整后的目录
├── background.js
├── images
│ └── hello_extensions.png
├── js
│ ├── jquery-3.5.1.min.js
│ └── zTree
├── manifest.json
├── popup
│ ├── hello.html
│ ├── popup.css
│ └── popup.js
yapi开放的公共接口
先找下yapi 开放的公共接口,我们需要的就是
/api/interface/list_menu
是的,这一个接口就可以满足我们的需求
开始开发
先准备好我们的popup.html 内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../js/zTree/css/zTreeStyle/zTreeStyle.css" media="all">
<link rel="stylesheet" href="popup.css" media="all">
</head>
<body>
<div class="pop-up-wrap">
<p class="pop-up-title">点击按钮复制api</p>
<div class="ztreeContent">
<div class="pop-up-ztree-loading" >
<p>正在获取页面数据中...</p>
<p>若长时间没获取到数据,请刷新页面重试</p>
</div>
<ul id="treeDemo" class="ztree"></ul>
</div>
<div class="copy-btn-wrap">
<button id="generate" class="copy-btn" >生成代码</button>
</div>
<div class="pop-up">
<div class="pop-up-content-wrap" >
<div class="pop-up-loading" >
<p>正在获取页面数据中...</p>
<p>若长时间没获取到数据,请刷新页面重试</p>
</div>
<div id="copty_content" class="pop-up-content"></div>
<div class="pop-up-fail">获取页面数据失败,请在所需页面手动输入api</div>
</div>
<div class="copy-btn-wrap">
<button id="cpoty_btn" class="copy-btn" data-clipboard-action="copy" data-clipboard-target="#copty_content">复制</button>
</div>
</div>
<div class="copy-success-wrap">
<p class="copy-success-text">复制成功</p>
</div>
</div>
<script type="text/javascript" src="../js/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="../js/zTree/js/jquery.ztree.all.min.js"></script>
<script src="popup.js"></script>
</body>
</html>
css
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
button {
margin: 0px;
padding: 0px;
border: 0px;
outline: none;
}
.pop-up-wrap {
width: 400px;
background: #eee;
}
.pop-up-title {
font-size: 16px;
line-height: 40px;
text-align: center;
background: #fff;
border-bottom: #ccc 1px solid;
}
.pop-up {
padding: 10px 20px 20px;
display: none;
}
.pop-up-content-wrap {
padding: 10px;
background: #fff;
border: solid 1px #ccc;
border-radius: 10px;
}
.pop-up-content {
display: none;
max-height: 500px;
overflow: auto;
}
.pop-up-content span {
display: block;
word-wrap: break-word;
}
.pop-up-fail {
display: none;
}
.copy-btn-wrap {
margin-top: 10px;
text-align: right;
}
.copy-btn {
display: inline-block;
width: 60px;
height: 30px;
color: #fff;
background: rgba(0, 216, 201, .8);
border-radius: 6px;
}
.copy-success-wrap {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
width: 200px;
text-align: center;
background: rgba(235, 235, 235, .8);
border-radius: 10px;
display: none;
}
.copy-success-text{
font-size: 20px;
line-height: 40px;
}
.ztreeContent{
background-color: #fff;
height: 200px;
overflow: auto;
}
.code{
display: none;
margin-top: 10px;
}
.pop-up-content-code{
height: 300px;
overflow: auto;
}
现在页面如下
如何调试
在弹框页面,右击检查,会看到一个控制台,这就是扩展程序的控制台,可以在console里查看打印信息
content script
谷歌插件支持 content script(内容脚本),它是独立运行在一个环境中的,不会与其他扩展可以主页发生冲突。这里我们需要用它来进行一个通信
根目录创建文件夹 scripts
文件夹下创建 content.js
mainfest.json 添加 content_scripts 字段
注意:这里的http://yapi.smart-xwork.cn/* 在使用时必须是你自己的yapi平台地址,不要写成这个哦
"content_scripts": [
{
"js": ["scripts/content.js"],
"matches": [
"http://yapi.smart-xwork.cn/*" //这个是必须的,只有这个网站地址下才可用
]
}
]
popup.js里面我们发出一条信息和内容脚本进行通信
// 发送消息给content-script
function sendMeaasgeToContentScript (message, callback) {
chrome.tabs.query({
active: true,
currentWindow: true
}, function (tabs) {
chrome.tabs.sendMessage(
tabs[0].id,
message,
function (response) {
if (callback) callback(response)
}
)
})
}
document.addEventListener('DOMContentLoaded', function() {
console.log(chrome.extension.getURL)
console.log(window)
sendMeaasgeToContentScript({
from: 'popup',
subject: 'DOMInfo'
}, function (response) {
if (response?.href) {
console.log(response.href)
}
})
});
content.js监听信息
// 监听来自popup的消息
chrome.runtime.onMessage.addListener(function (msg, sender, response) {
if ((msg.from === 'popup') && (msg.subject === 'DOMInfo')) {
response({location: window.location})
}
});
popup 会接收到返回的{{location: window.location}}
我们可以看到控制台输出了location
由此,我们可以在popup.js中得到当前访问的页面路径,即yapi的地址,
请求数据
我们请求yapi接口列表
代码如下
var zTreeObj
var url
document.addEventListener('DOMContentLoaded', function() {
sendMeaasgeToContentScript({
from: 'popup',
subject: 'DOMInfo'
}, function (response) {
if (response?.location) {
console.log(response.location)
getTreeData(response.location) // 这里调接口
}
})
});
// 获取yapi接口列表
function getTreeData (location) {
url = location.origin
const id = location.href.split('/')[4]
const origin = location.origin // http://yapi.smart-xwork.cn
$.ajax({
type:'GET',
url:`${origin}/api/interface/list_menu?project_id=${id}`,
dataType:'json',
success:function(response){
const {
errcode,
data
} = response
if (errcode === 0) {
data.forEach(element => {
element.title = element.name
});
console.log(data)
}
},
error: function(response){
const str = JSON.stringify(response)
}
});
}
// 初始化zTree zTree的使用方法可以去官网查看
function initZTree(data){
// zTree 的参数配置,深入使用请参考 API 文档(setting 配置详解)
var setting = {
check:{
enable:true,
},
data:{
key:{
children:'list',
name:'title'
}
}
};
$(document).ready(function(){
zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, data);
});
}
我们已经获取到数据了,通过调用initZtree方法,可以将接口列表展示到窗口中
生成代码
选中接口,我们开始根据选中的数据生成我们想要的代码
效果图
看看代码实现
// 下划线转驼峰
function toHump(name) {
return name.replace(/\_(\w)/g, function(all, letter){
return letter.toUpperCase();
});
}
$('#generate').click(()=>{
$('.pop-up').show()
const checkedArr = zTreeObj.getNodesByFilter((node)=>{
return node.level==1 && node.checked
})
// 遍历生成代码
let code = ``
checkedArr.forEach(item=>{
let _path = item.path.split('/').slice(-2).join('_')
_path = _path.replace(_path[0], _path[0].toUpperCase())
const _method = item.method.toLowerCase()
const _urlName = `${_method}${toHump(_path)}`
code += `
<span>/** </span>
<span> * ${item.title}</span>
<span> * @desc: ${url}/project/${item.project_id}/interface/api/${item._id}</span>
<span> * @mock: ${url}/mock/${item.project_id}${item.path}</span>
<span> */</span>
<span class="pop-up-url">${_urlName} = ${_method}('${item.path.replace(/^(\s|\/)+|(\s|\/)+$/g, '')}')</span>
`
})
console.log(code)
$('.pop-up-loading').hide()
$('.pop-up-content').show()
$('.pop-up-content').html(
code
)
})
复制代码
这里复制用到一个插件,就不做过多介绍了
用法 html
<div class="copy-btn-wrap">
<button id="cpoty_btn"
class="copy-btn"
data-clipboard-action="copy" // 触发的方法
data-clipboard-target="#copty_content" // 复制的元素id
>复制</button>
</div>
popup.js
$(function(){
copy()
});
// 复制代码
function copy () {
const clipboard = new ClipboardJS('#cpoty_btn');
clipboard.on('success', function(e) {
$('.copy-success-wrap').show()
setTimeout(() => {
$('.copy-success-wrap').hide()
}, 1000);
});
clipboard.on('error', function(e) {
alert("复制失败!请手动复制")
});
}
至此 一个快速生成接口代码的插件就完成了(写的较粗,可自行更改样式)