LoginSignup
0
0

More than 1 year has passed since last update.

To-Do ListのChrome拡張機能をVue.jsで作る

Posted at

Chromeの拡張機能でいい感じのTo-Do Listが欲しいと思い、ちょうどバイト先でもVueを使っていたのでVueを使い作ってみました。

(Vue.jsはバージョン2.6.14です。あと, 他の記事を見たときにbuildがめんどくさいと書いてあったのですがその辺りはpythonで実行しています。buildしたときにファイルを追加しなきゃならないのがめんどくさい)

是非ダウンロードして使ってみて下さい!!!

ソースコード↓

完成イメージ

Screen Shot 2022-02-27 at 10.25.50.jpg
Screen Shot 2022-02-27 at 10.26.45.jpg   Screen Shot 2022-02-27 at 10.26.59.jpg

機能

  • リストへの書き込み
  • やったことをチェックできる
  • リストのリセット
  • リストの一括リセット
  • ダークモード
  • リストのドラッグ

手順

  1. Chorme拡張機能の申請に必須のファイル(manifest.json)を作成
  2. 作りたいものをVue-cliで作成
  3. 申請し審査を通す

1.Chorme拡張機能の申請に必須のファイル(manifest.json)を作成

申請、開発途中の確認(chrome://extensions)をする際に、npm run buildで作ったdistディレクトリをアップロードするのですがその際にmanifest.jsonと必要な画像ファイルがdistに入らないのでpythonでbuild+必須ファイルのセッティングを行ってくれるようコードしました。

extention_build.py
# make manifest.json and set icon to dist/icons
import os
import json
import shutil


def main():
    os.system('npm run build')
    write_manifest()
    set_icons()


def write_manifest():
    content = {
        "name": "To Do List",
        "description": "A simple to-do list extension, You can also write your own not-to-do list",
        "manifest_version": 3,
        "version": "1.0.4",
        "permissions": ["activeTab", "storage"],
        "icons": {
            "16": "icons/icon16.png",
            "48": "icons/icon48.png",
            "128": "icons/icon128.png",
        },
        "action": {
            "default_icon": "icons/icon128.png",
            "default_popup": "index.html"
        }
    }

    os.system('touch ./dist/manifest.json')
    with open('./dist/manifest.json', 'w') as f:
        json.dump(content, f, ensure_ascii=False, indent=4, separators=(',', ': '))


def set_icons():
    os.system('mkdir dist/icons')
    for icon in ['icon16.png', 'icon48.png', 'icon128.png']:
        shutil.copy(f'./src/assets/icons/{icon}', './dist/icons/')


if __name__ == '__main__':
    main()

manifest.jsonの中身自体はcontentという変数で定義しています。

なのでこれをmanifest.jsonだと思って下さい。

pythonの環境がある方はバージョンにもよりますがファイル名等を揃えておけばこれで動くと思います。(Python 3.8.8)

permissions自体は何種類かあるのですが、使わない機能をpermissionsに入れて申請すると審査落ちするので気をつけて下さい。
またiconsdefault_iconは必ず正方形に整形しておく必要があります。
そうしないと適切に描画されなかったりそもそも拡張機能を開けなくなってしまいます。
画像整形にはこの辺りのサービスが使えると思います。

今回は、To-Do Listの中身をchromeの方で保管しておいて欲しいそもそのこの拡張機能を表示するのにHTMLのポップアップを許して欲しいという2つの要求があるので"permissions": ["activeTab", "storage"]としています。

2. とりあえず作りたいものをVue-cliであらかた作ってみる

このあたりは本当に人によりけりだと思います。
その際にこの記事がかなり参考になりました。
見本も3つあるのでだいたいどんなことをしなければいけないのかのイメージが付きます。

以下自分の場合

ディレクトリ構成
.
├── README.md
├── babel.config.js
├── extensiton_build.py
├── package-lock.json
├── package.json
├── public
│   ├── favicon.ico
│   └── index.html
├── src
│   ├── App.vue
│   ├── assets
│   │   ├── icons
│   │   │   ├── icon.png
│   │   │   ├── icon128.png
│   │   │   ├── icon16.png
│   │   │   └── icon48.png
│   │   ├── logo.png
│   │   └── scss
│   │       ├── dark-mode.scss
│   │       └── style.scss
│   ├── components
│   │   ├── NotToDoList.vue
│   │   ├── Preferences.vue
│   │   └── ToDoList.vue
│   ├── main.js
│   └── mixinFunctions.js
└── vue.config.js

コンポーネントとしてToDoList.vueNotToDoList.vue、設定をまとめたPreferences.vue作りました。これらをApp.vue<component>タグを使いそれぞれ描画できるようにしています。

一応、storageを使う際にデータの保存と取り出し方は決まっていてなおかつ各コンポーネントで共通しているためmixinするようしました。

mixinFunctions.js
export default {
    methods: {
        getFromChromeStorage(objName, listLength = null) {
            chrome.storage.local.get(objName, item => {
                if (listLength === null) {
                    this[objName] = item[objName] ? true : false;
                } else {
                    this[objName] = item[objName] ? item[objName] : this.createList(objName, listLength);
                }
            });
        },
        createList(objName, listLength) {
            const generatedList = [];
            const uniqueIds = ['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta'];
            for (let i = 0; i < listLength; i++) {
                generatedList.push({ id: uniqueIds[i], isChecked: false, content: '' });
            }
            this.setToChromeStorage(objName, generatedList);
            this[objName] = generatedList;
            return this[objName];
        },
        setToChromeStorage(objName, object) {
            chrome.storage.local.set({ [objName]: object }, function() {
                console.log(`${objName} saved`);
            });
        },
    },
}

toDoListとnotToDoListはどちらも{ id: uniqueIds[i], isChecked: false, content: '' }というオブジェクトの配列にしています。
なぜ、uniqueIdsを設定しているのかというとVue.Draggableという要素をドラッグできるようにするライブラリを使っていて、ドラッグ後の順番を保証するために必要でした。
(もっと良い方法がある気がします。。。)

storageからの取得はchrome.storage.local.get、格納はchrome.storage.local.setで行います。
setの際、keyを動的に変更するには{ [objName]: object }とするそうです。
こうすることでそれぞれのコンポーネントのdataを動的に受け入れさせます。

その後も見た目の調整等を行い、完成しました。

3. googleに申請する

作りたいものはできたので、申請します。
まず、初回にデベロッパーとして登録するのに5ドルかかります。
その後npm run builddistフォルダを作りそれを.zipにして拡張機能ダッシュボードの新しいアイテムにアップロードし、結果を待ちます。

審査結果はだいたい2日位で返ってきました。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0