Develop your own Chrome extensions with Vue

Translation: Crazy house technology

Original: www.sitepoint.com/build-vue-c...

Without permission is forbidden

Browser extensions can modify and enhance the functionality of the Web browser applet. They can be used for a variety of tasks, such as to stop advertising, password management, organization label, change the appearance and behavior of the web page and so on.

The good news is the browser extension is not difficult to write. You can use the already familiar with Web technologies (HTML, CSS and JavaScript) to create - just like a normal web page. But the web is different, extension can access many browser-specific API, this is interesting.

In this tutorial, I will show you how to build a Chrome can change a simple extension of the new tab behavior. JavaScript extensions of this section, I will use Vue.js framework, because it will allow us to quickly get up and running , and work with a vue is very interesting.

This tutorial code can be found on GitHub

Basics Chrome extensions

The core part of the Chrome extension is manifest file and background scripts . manifest file in JSON format, providing important information about extensions, such as its version rights, resources or desired. Background script allows extension to respond to the particular browser event, such as creating a new tab.

To demonstrate these concepts, let's write a "Hello, World!" Chrome extension.

Create a file called hello-world-chromenew folder and two files: manifest.jsonand background.js:

mkdir hello-world-chrome
cd hello-world-chrome
touch manifest.json background.js
复制代码

Open manifest.jsonand add the following code:

{
  "name": "Hello World Extension",
  "version": "0.0.1",
  "manifest_version": 2,
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }
}
复制代码

name, versionAnd manifest_versionare required fields. nameAnd the versionfield can be anything you want; the manifest Version should be set to 2 (starting from the Chrome 18).

backgroundAllow us to register a background scripts in scriptslisted behind the array. Unless extended need chrome.webRequest API to block or modify a network request, otherwise the persistentbond should be set false.

Add the following code to background.jsthe browser pop-up dialog box when installing a hello extension:

chrome.runtime.onInstalled.addListener(() => {
  alert('Hello, World!');
});
复制代码

Finally, install extensions. Open Chrome and type in the address bar chrome://extensions/. You should see a page showing extensions installed.

Since we want the file (rather than Chrome Web Store) install their own extensions, so you need to use the toggle button top right corner of the page to activate developer mode . This should add an extra menu bar, which contains Load unpacked options. Click this button and select your previously created hello-world-chromefolder. Click Open , should be able to see the installed extensions, and pop-up "Hello, World!" Window.

Congratulations! You've just created a Chrome extension.

Chrome's new tab page coverage

In order to meet us when you open a new tab is your extension. By using Override Pages API to do this.

Note: Before you progress, make sure to disable other extensions to cover the Chrome new tab page. It allows only one extension to change this behavior.

First, create a page to be displayed, rather than a new tab. We call it tab.html. It should be located in the same file with a list of files and folders in the background script:

<!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>
复制代码

Next you need to know to make the extended presence of the page. Can be specified in a manifest file chrome_url_overridesis achieved, as follows:

"chrome_url_overrides": {
  "newtab": "tab.html"
}
复制代码

Finally, you need to reload extensions for the changes to take effect. You can click the Hello World extension program on the extension page on Chrome's reload to do this icon.

Now, when you open a new tab, your custom message will appear.

Adding to expand Vue

Now we have a very basic extension, then the rest of the need to implement the function. When the user opens a new tab, I wish to extend to:

  • From the wonderful joke website icanhazdadjoke.com get a joke.
  • Jokes displayed to the user in a good form.
  • Display user likes the joke buttons. This can save a joke to chrome.storage.
  • Displays a button for the user to view a collection of jokes.

Of course, you can also use pure JavaScript libraries like jQuery or to do all these - you happy enough!

But for the purposes of this tutorial, I will use Vue and awesome vue-web-extension model to implement this feature.

With Vue allows me to write more faster and better organized code. As we have seen, boilerplate provides several scripts that can be solved when building Chrome extension some of the pain of common tasks (for example: Whenever you make a change must reload extensions).

vue-web-extension-boilerplate

This section assumes that your computer has the Node and npm. If not, you can go to nodejs.org/en/ get related binary files, or you can use the Version Manager . I recommend using the version manager.

We also need to install Vue CLI and @ VUE / cli-the init Package Penalty for :

npm install -g @vue/cli
npm install -g @vue/cli-init
复制代码

When done, let's get a copy of the template:

vue init kocal/vue-web-extension new-tab-page
复制代码

This opens a wizard that asks you a bunch of questions. In order to ensure that the focus of this tutorial, I answer listed:

? Project name new-tab-page
? Project description A Vue.js web extension
? Author James Hibbard <[email protected]>
? 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
复制代码

You can adjust the answer to your liking, but you must install Axios . We will use it to get the joke.

Next, switch to the project directory and install the dependencies:

cd new-tab-page
npm install
复制代码

Then we can build our new model extends the script provided:

npm run watch:dev
复制代码

This will expand the project to build the root directory distfolder, to develop and monitor changes.

To add the extension to Chrome, follow the same steps as above, to select the distfolder as the extension directory. If all goes according to plan, then when the extension program initialization, you should see "Hello world!" Message.

Project Settings

Let's take a moment to look at the model gives us something. The current folder structure should be as follows:

.
├── 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
复制代码

You can see the project root directory, the template file is in use webpack. This is good because it gives us a background scripts Hot Module Reloading .

srcFolder contains all the files will be used for extensions. manifest file and background.jsfor us are familiar with, but also pay attention to include Vue assembly popupfolder. When the template file will be extended to build dista folder, it will pass vue-loader to manage all .vueand outputs a browser can understand the JavaScript package file.

In the srcfolder there is a iconsfolder. If you see a Chrome toolbar, you'll see a new icon in our extension program (also known as Browser Action ). This is to get from this folder. If you click it, you should see a pop-up window that displays "Hello world!" This is due to popup/App.vuecreate.

Finally, please note scriptstwo scripts folders: one for deleting evalusage to conform to the Chrome Web Store content security policies, and one for when you want to upload to the Chrome Web Store extensions package it in .zip file, .

In the package.jsondocument also declares the various scripts. We will use npm run watch:devto develop extensions, then npm run build-zipgenerate a ZIP file uploaded to Chrome Web Store.

Use Vue components in a new tab

First, from background.jsdeleting annoying in alertthe statement.

In srccreating a new folder in the tabfolder to store the code for the new tab page. We will add three new files in the folder - App.vue, tab.html, tab.js:

mkdir src/tab
touch src/tab/{App.vue,tab.html,tab.js}
复制代码

Open tab.htmland add the following:

<!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>
复制代码

Nothing special here. This is a simple HTML page, it will save our Vue instance.

Then in tab.jsadded:

import Vue from 'vue';
import App from './App';

new Vue({
  el: '#app',
  render: h => h(App)
});
复制代码

Here Vue introduction, it is passed with a selector for the element, and then tells it to render Appassembly.

Finally, App.vuewrite the following code:

<template>
  <p>{{ message }}</p>
</template>

<script>
export default {
  data () {
    return {
      message: "My new tab page"
    }
  }
}
</script>

<style scoped>
p {
  font-size: 20px;
}
</style>
复制代码

Before using this new tab, we need to update the manifest file:

{
  "name":"new-tab-page",
  ...
  "chrome_url_overrides": {
    "newtab": "tab/tab.html"
  }
}
复制代码

In order to make them available to expand, we need to let our compiler model file and copy it to dista folder.

Like the following modifications webpack.config.js, updates entryand pluginskey:

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 },
    ...
  })
复制代码

You need to restart the npm run watch:devtask to make these changes to take effect. Once this is done, reload the extension and open a new tab. You should see "My new tab page".

Obtaining and displaying joke

Well, we have covered the Chrome new tab page, and replace it for mini Vue app. But we do more than just display a message.

Change src/tab/App.vuetemplate section as follows:

<template>
  <div>
    <div v-if="loading">
      <p>Loading...</p>
    </div>
    <div v-else>
      <p class="joke">{{ joke }}</p>
    </div>
  </div>
</template>
复制代码

The <script>change part of the following code:

<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>
复制代码

Finally, the <style>change is part of the following code:

<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>
复制代码

If you are running npm run watch:devthe task, the extension will be automatically reloaded, and every time you open a new tab will see a joke.

Next, take the time to understand yourself have done.

In the template, we use v-if block to display a message or a joke load, depending on the loadingstate. Initially it is set true(display loading message), then our script will trigger the Ajax request to retrieve a joke. Once the request is complete Ajax, loadingproperty will be set false, resulting in re-assembly is rendered and displayed joke.

In <script>part, we import axios, then declares several data attributes - the aforementioned loadingproperties and a jokeproperty to hold the joke. Then use the mount lifecycle hook , once our Vue will trigger instance is mounted to joke API Ajax request. After the completion of the request, the update data attributes that the two re-rendering component.

So far very good.

The joke hold persisted to Chrome Storage

Next, add a button that allows users to like a few jokes and lists favorite joke list. Since we will use Chrome's storage API to save these jokes, it may be necessary to add a third button to delete the storage of jokes.

Add a button to block 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>
复制代码

Nothing exciting things. Please note that we will be button-like disabledproperties bound to a data property on the Vue instance to determine its status. This is because the user should not be like a joke more than once.

Next, click handler and Like Button Disabledadd to the Scripting section:

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() { ... }
}
复制代码

Here, we declare three new ways to deal with these three new buttons.

likeJokeMethod looks in Chrome's storage jokesproperties. If it does not exist (that is, the user has not liked a joke), it will be initialized to empty array. It then current joke push this array and save it to storage. Finally, the likeButtonDisableddata property to true, and disable the like button.

logJokesChrome storage method also looks for jokesproperties. If found, it will traverse all the entries and outputs them to the console.

clearStorage Method is responsible for clearing data.

Continue to adjust this new feature in the extension, until their own satisfaction.

As an extension to do some landscaping

It can work, but the buttons are ugly, page a bit simple. Below it is necessary to do some retouching to expand.

Next, install vue-awesome library. It enables us to use the Font Awesome icon on the page, and look more beautiful some of these buttons:

npm install vue-awesome
复制代码

In src/tab/tab.jsthe library registration:

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)
});
复制代码

Modify the template:

<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>
复制代码

Finally, let's add more style to the button, and add a picture:

<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>
复制代码

Reload expand and open a new tab, you should see something like this.

The extension uploaded to the Chrome Web Store

If you want other people can use your extension, through Chrome Web Store to do.

First you need to have a Google account, you can log in with the account Developer Dashboard . You will be prompted to enter details developer, before publishing the first application, you must pay the developer registration fee of $ 5 (by credit card).

Next, you need to create a ZIP file for your application. You can npm run build-zipperform this operation locally. This creates a project named in the root directory of dist-zipthe folder that contains ready to upload to the Web Store's ZIP file.

For simple little extension, that was enough. However, before you upload your own extension, be sure to read the official Publish in the Chrome Web Store Guide.

to sum up

In this tutorial, I focused on the main part of the Chrome extension, and shows how to use the Vue.js in vue-web-extension model to build extensions, and finally explain how to extend uploaded to the Web Store.

I hope you enjoy this tutorial, and use it to guide you begin to build your own Chrome extensions.

Welcome to the front end of public concern number: Pioneer front-end, more front-end dry.

Reproduced in: https: //juejin.im/post/5d0389aae51d45772a49ad38

Guess you like

Origin blog.csdn.net/weixin_34128411/article/details/93183324