翻译:疯狂的技术宅javascript
原文:www.sitepoint.com/build-vue-c…css
未经容许严禁转载html
浏览器扩展程序是能够修改和加强 Web 浏览器功能的小程序。它们可用于各类任务,例如阻止广告,管理密码,组织标签,改变网页的外观和行为等等。前端
好消息是浏览器扩展并不难写。能够用你已经熟悉的 Web 技术(HTML、CSS 和 JavaScript)建立 —— 就像普通网页同样。可是与网页不一样的是,扩展程序能够访问许多特定于浏览器的 API,这才是有趣的地方。vue
在本教程中,我将向你展现如何为 Chrome 构建一个可以改变新标签页行为的简单扩展。这个扩展程序的 JavaScript 部分,我将使用 Vue.js 框架,由于它将容许咱们快速启动并运行,并且用 vue 工做是颇有趣的。java
Chrome扩展程序的核心部分是 manifest 文件 和后台脚本。manifest 文件采用JSON格式,提供有关扩展的重要信息,例如其版本、资源或所需的权限。后台脚本容许扩展对特定的浏览器事件作出反应,例如建立新选项卡。jquery
为了演示这些概念,让咱们先写一个“Hello,World!” Chrome 扩展。webpack
建立一个名为 hello-world-chrome
的新文件夹和两个文件:manifest.json
和 background.js
:ios
mkdir hello-world-chrome
cd hello-world-chrome
touch manifest.json background.js
复制代码
打开 manifest.json
并添加如下代码:
{
"name": "Hello World Extension",
"version": "0.0.1",
"manifest_version": 2,
"background": {
"scripts": ["background.js"],
"persistent": false
}
}
复制代码
name
、version
和 manifest_version
都是必填字段。 name
和 version
字段能够是你想要的任何内容; manifest version 应设置为2(从Chrome 18开始)。
background
容许咱们注册一个后台脚本, 在scripts
后面的数组中列出。除非扩展须要用 chrome.webRequest API来阻止或修改网络请求,不然 persistent
键应设置为 false
。
将如下代码添加到 background.js
,使浏览器在安装扩展时弹出出 hello 对话框:
chrome.runtime.onInstalled.addListener(() => {
alert('Hello, World!');
});
复制代码
最后安装扩展程序。打开 Chrome 并在地址栏中输入 chrome://extensions/
。你应该看到一个显示已安装扩展程序的页面。
因为咱们要从文件(而不是Chrome网上应用店)安装本身的扩展程序,所以须要使用页面右上角的切换按钮来激活开发者模式。这应该添加一个额外的菜单栏,其中包含 Load unpacked选项。单击此按钮并选择你以前建立的 hello-world-chrome
文件夹。单击打开,应该可以看到已安装的扩展,并弹出“Hello,World!”窗口。
恭喜!你刚刚制做了一个 Chrome 扩展程序。
为了在打开新选项卡时迎接咱们的是本身的扩展程序。能够经过使用 Override Pages API 来完成此操做。
注意:在你取得进展以前,请务必停用其余可以覆盖 Chrome 新标签页的扩展程序。一次只容许一个扩展改变这种行为。
首先建立一个要显示的页面,而不是新的标签页。咱们称之为 tab.html
。它应该与清单文件和后台脚本位于同一文件夹中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My New Tab Page!</title>
</head>
<body>
<h1>My New Tab Page!</h1>
<p>You can put any content here you like</p>
</body>
</html>
复制代码
接下来须要让扩展知道页面的存在。能够经过在清单文件中指定 chrome_url_overrides
来实现,以下所示:
"chrome_url_overrides": {
"newtab": "tab.html"
}
复制代码
最后,你须要从新加载扩展才能使更改生效。你能够经过在 Chrome 的扩展程序页面上单击 Hello World 扩展程序的 reload 图标来执行此操做。
如今,当你打开新标签页时,你的自定义消息会出现。
如今咱们有一个很是基本的扩展,接下来要实现剩下的需功能了。当用户打开新标签页时,我但愿扩展可以:
chrome.storage
。固然你也能够用纯 JavaScript 或像 jQuery 这样的库来完成全部这些 —— 你开心就好!
可是出于本教程的目的,我将用 Vue 和使人敬畏的 vue-web-extension 样板来实现此功能。
用 Vue 可让我又快又好地编写更有条理的代码。正如咱们所看到的,样板文件提供了几个脚本,能够在构建 Chrome 扩展程序时解决一些痛苦的常见任务(例如:每当你进行更改时都必须从新加载扩展程序)。
本节假定你的计算机上安装了 Node 和 npm。若是不是这样,你能够到 nodejs.org/en/ 获取相关二进制文件,或者你能够使用版本管理器。我建议使用版本管理器。
咱们还须要安装 Vue CLI 和 @vue/cli-init package:
npm install -g @vue/cli
npm install -g @vue/cli-init
复制代码
完成后,让咱们获得样板的副本:
vue init kocal/vue-web-extension new-tab-page
复制代码
这将打开一个向导,询问你一堆问题。为了保证本教程的重点,我把回答列出来:
? Project name new-tab-page
? Project description A Vue.js web extension
? Author James Hibbard <jim@example.com>
? License MIT
? Use Mozilla's web-extension polyfill? No ? Provide an options page? No ? Install vue-router? No ? Install vuex? No ? Install axios? Yes ? Install ESLint? No ? Install Prettier? No ? Automatically install dependencies? npm 复制代码
你能够根据本身的喜爱调整答案,可是你必定要安装 axios。咱们会用它来获取笑话。
接下来,切换到项目目录并安装依赖项:
cd new-tab-page
npm install
复制代码
而后就能够用样板提供的脚本构建咱们的新扩展了:
npm run watch:dev
复制代码
这会将扩展构建到项目根目录中的 dist
文件夹中,来进行开发并监视更改。
要将扩展程序添加到 Chrome,请执行上述相同的步骤,要选择 dist
文件夹做为扩展程序目录。若是一切按计划进行,那么当扩展程序初始化时,你应该看到“Hello world!”消息。
让咱们花一点时间来看看样板给了咱们些什么。当前文件夹结构应以下所示:
.
├── dist
│ └── <the built extension>
├── node_modules
│ └── <one or two files and folders>
├── package.json
├── package-lock.json
├── scripts
│ ├── build-zip.js
│ └── remove-evals.js
├── src
│ ├── background.js
│ ├── icons
│ │ ├── icon_128.png
│ │ ├── icon_48.png
│ │ └── icon.xcf
│ ├── manifest.json
│ └── popup
│ ├── App.vue
│ ├── popup.html
│ └── popup.js
└── webpack.config.js
复制代码
在项目根目录中能够看到,样板文件正在使用 webpack。这很好,由于这为咱们的后台脚本提供了 Hot Module Reloading。
src
文件夹包含咱们将用于扩展的全部文件。manifest 文件和 background.js
对于咱们来讲是熟悉的,但也要注意包含Vue 组件的 popup
文件夹。当样板文件将扩展构建到 dist
文件夹中时,它将经过 vue-loader 管理全部 .vue
文件并输出一个浏览器能够理解的 JavaScript 包。
在 src
文件夹中还有一个 icons
文件夹。若是你看一眼 Chrome 的工具栏,会看到咱们的扩展程序的新图标(也被称为 browser action)。这就是今后文件夹中拿到的。若是单击它,你应该会看到一个弹出窗口,显示“Hello world!” 这是由 popup/App.vue
建立的。
最后,请注 scripts
文件夹的两个脚本:一个用于删除 eval
用法以符合 Chrome Web Store 的内容安全策略,另外一个用于当你要把扩展上传到Chrome Web Store时将其打包到 .zip 文件中,。
在 package.json
文件中还声明了各类脚本。咱们将用 npm run watch:dev
来开发扩展,而后使用 npm run build-zip
生成一个ZIP文件以上传到 Chrome Web Store。
首先从 background.js
中删除烦人的 alert
语句。
在 src
文件夹中建立一个新的 tab
文件夹来存放新标签页的代码。咱们将在这个新文件夹中添加三个文件 —— App.vue
,tab.html
, tab.js
:
mkdir src/tab
touch src/tab/{App.vue,tab.html,tab.js}
复制代码
打开 tab.html
并添加如下内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>New Tab Page</title>
<link rel="stylesheet" href="tab.css">
</head>
<body>
<div id="app"></div>
<script src="tab.js"></script>
</body>
</html>
复制代码
这里没什么特别的。这是一个简单的 HTML 页面,它将保存咱们的 Vue 实例。
接下来在 tab.js
中添加:
import Vue from 'vue';
import App from './App';
new Vue({
el: '#app',
render: h => h(App)
});
复制代码
在这里导入 Vue,用它为元素传递一个选择器,而后告诉它渲染 App
组件。
最后在 App.vue
中写以下代码:
<template>
<p>{{ message }}</p>
</template>
<script> export default { data () { return { message: "My new tab page" } } } </script>
<style scoped> p { font-size: 20px; } </style>
复制代码
在使用这个新标签页以前,咱们须要更新 manifest 文件:
{
"name":"new-tab-page",
...
"chrome_url_overrides": {
"newtab": "tab/tab.html"
}
}
复制代码
为了使它们可用于扩展,咱们还须要让样板编译咱们的文件并复制到 dist
文件夹。
像下面这样修改 webpack.config.js
,更新entry
和plugins
键:
entry: {
'background': './background.js',
'popup/popup': './popup/popup.js',
'tab/tab': './tab/tab.js'
}
plugins: [
...
new CopyWebpackPlugin([
{ from: 'icons', to: 'icons', ignore: ['icon.xcf'] },
{ from: 'popup/popup.html', to: 'popup/popup.html', transform: transformHtml },
{ from: 'tab/tab.html', to: 'tab/tab.html', transform: transformHtml },
...
})
复制代码
你须要从新启动 npm run watch:dev
任务才能使这些更改生效。完成此操做后,从新加载扩展程序并打开新选项卡。你应该会看到“My new tab page”。
好的,咱们已经覆盖了 Chrome 的新标签页,而且将其替换为了 mini Vue app。可是咱们要作的不只仅是显示一条消息。
更改 src/tab/App.vue
中的模板部分以下:
<template>
<div>
<div v-if="loading">
<p>Loading...</p>
</div>
<div v-else>
<p class="joke">{{ joke }}</p>
</div>
</div>
</template>
复制代码
将 <script>
部分更改成以下代码:
<script>
import axios from 'axios';
export default {
data () {
return {
loading: true,
joke: "",
}
},
mounted() {
axios.get(
"https://icanhazdadjoke.com/",
{ 'headers': { 'Accept': 'application/json' } }
)
.then(res => {
this.joke = res.data.joke
this.loading = false;
});
}
}
</script>
复制代码
最后,将 <style>
部分更改成以下代码:
<style>
body {
height: 98vh;
text-align: center;
color: #353638;
font-size: 22px;
line-height: 30px;
font-family: Merriweather,Georgia,serif;
background-size: 200px;
display: flex;
align-items: center;
justify-content: center;
}
.joke {
max-width: 800px;
}
</style>
复制代码
若是你正在运行 npm run watch:dev
任务,则扩展程序会自动从新加载,而且每当你打开新标签页时都会看到一个笑话。
接下来花点时间来了解一下本身都作了些什么。
在模板中,咱们使用 v-if 块来显示加载消息或笑话,具体取决于 loading
的状态。最初它被设置为 true
(显示加载消息),而后咱们的脚本将触发 Ajax 请求来检索笑话。一旦 Ajax 请求完成,loading
属性将被设置为 false
,致使组件被从新渲染并显示笑话。
在 <script>
部分,咱们导入了 axios,而后声明了几个数据属性——前面提到的 loading
属性和一个 joke
属性来保存这个笑话。而后使用了 mount
生命周期钩子,一旦咱们的 Vue 实例被挂载就会触发,向 joke API 发出 Ajax 请求。请求完成后,更新两个数据属性使组件从新渲染。
到目前为止还挺好。
接下来,添加一些可以让用户喜欢一个笑话和列出喜欢的笑话列表的按钮。因为咱们将使用 Chrome’s storage API 来保存这些笑话,因此可能须要添加第三个按钮来删除 storage 中的笑话。
将按钮添加到 v-else 块:
<div v-else>
<p class="joke">{{ joke }}</p>
<button @click="likeJoke" :disabled="likeButtonDisabled">Like Joke</button>
<button @click="logJokes" class="btn">Log Jokes</button>
<button @click="clearStorage" class="btn">Clear Storage</button>
</div>
复制代码
没有什么使人兴奋的东西了。请注意咱们将相似按钮的 disabled
属性绑定到 Vue 实例上的数据属性来肯定其状态。这是由于用户不该该屡次喜欢一个笑话。
接下来,将 click handler 和 Like Button Disabled
添加到脚本部分:
export default {
data () {
return {
loading: true,
joke: "",
likeButtonDisabled: false
}
},
methods: {
likeJoke(){
chrome.storage.local.get("jokes", (res) => {
if(!res.jokes) res.jokes = [];
res.jokes.push(this.joke)
chrome.storage.local.set(res);
this.likeButtonDisabled = true;
});
},
logJokes(){
chrome.storage.local.get("jokes", (res) => {
if(res.jokes) res.jokes.map(joke => console.log(joke))
});
},
clearStorage(){
chrome.storage.local.clear();
}
},
mounted() { ... }
}
复制代码
在这里,咱们声明了三个新方法来处理这三个新按钮。
likeJoke
方法在 Chrome 的存储中查找 jokes
属性。若是它不存在(也就是说,用户还没有喜欢一个笑话),会将其初始化为空数组。而后它将当前的笑话推送到此数组并将其保存到 storage。最后,将 likeButtonDisabled
数据属性设置为 true
,并禁用 like 按钮。
logJokes
方法还在 Chrome storage 中查找 jokes
属性。若是找到了,会遍历其全部条目并将它们输出到控制台。
clearStorage
方法负责清除数据。
继续在扩展中调整这个新功能,直到本身满意。
它可以工做了,可是按钮是很丑,页面也有点简单。下面就要给扩展作一些润色。
下一步,安装 vue-awesome 库。它可以使咱们在页面上使用 Font Awesome 图标,并使这些按钮看起来更漂亮一些:
npm install vue-awesome
复制代码
在 src/tab/tab.js
中对库进行注册:
import Vue from 'vue';
import App from './App';
import "vue-awesome/icons";
import Icon from "vue-awesome/components/Icon";
Vue.component("icon", Icon);
new Vue({
el: '#app',
render: h => h(App)
});
复制代码
修改模板:
<template>
<div>
<div v-if="loading" class="centered">
<p>Loading...</p>
</div>
<div v-else>
<p class="joke">{{ joke }}</p>
<div class="button-container">
<button @click="likeJoke" :disabled="likeButtonDisabled" class="btn"><icon name="thumbs-up"></icon></button>
<button @click="logJokes" class="btn"><icon name="list"></icon></button>
<button @click="clearStorage" class="btn"><icon name="trash"></icon></button>
</div>
</div>
</div>
</template>
复制代码
最后,让咱们为按钮添加更多样式,并添加一张图片:
<style>
body {
height: 98vh;
text-align: center;
color: #353638;
font-size: 22px;
line-height: 30px;
font-family: Merriweather,Georgia,serif;
background: url("https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2018/12/1544189726troll-dad.png") no-repeat 1% 99%;
background-size: 200px;
display: flex;
align-items: center;
justify-content: center;
}
.joke {
max-width: 800px;
}
.button-container {
position: absolute;
right: 0px;
top: calc(50% - 74px);
}
.btn {
background-color: #D8D8D8;
border: none;
color: white;
padding: 12px 16px;
font-size: 16px;
cursor: pointer;
display: block;
margin-bottom: 5px;
width: 50px;
}
.btn:hover {
background-color: #C8C8C8;
}
.btn:disabled {
background-color: #909090;
}
</style>
复制代码
从新加载扩展并打开一个新标签,你应该看到这样的东西。
若是想让其余人也可使用你的扩展程序,能够经过 Chrome Web Store 作到。
首先你须要有一个 Google 账户,能够用该账户登陆 Developer Dashboard 。系统会提示你输入开发人员详细信息,在发布第一个应用程序以前,你必须支付 5 美圆的开发人员注册费(经过信用卡)。
接下来,你须要为本身的应用建立一个 ZIP 文件。你能够经过 npm run build-zip
在本地执行这项操做。这会在项目根目录中建立一个名为 dist-zip
的文件夹,其中包含准备上传到 Web Store 的 ZIP 文件。
对于简单的小扩展,这就够了。可是,在你上传本身的扩展以前,请务必阅读官方 Publish in the Chrome Web Store 指南。
在本教程中,我重点介绍了 Chrome 扩展程序的主要部分,并展现了如何用在 Vue.js 中 vue-web-extension 样板构建扩展程序,最后讲解了如何将扩展上传到 Web Store。
但愿你喜欢本教程,并用它指导你始构建本身的 Chrome 扩展。