vue+element開發(fā)一個谷歌插件的全過程
簡單功能:點擊瀏覽器右上角插件icon彈出小彈窗,點擊設(shè)置彈出設(shè)置頁,并替換背景圖或顏色。
開始
1.本地創(chuàng)建文件夾testPlugin并新建manifest.json文件
{
"name": "testPlugin",
"description": "這是一個測試用例",
"version": "0.0.1",
"manifest_version": 2
}
2.添加插件的小icon
testPlugin下創(chuàng)建icons文件夾,可以放入一些不同尺寸的icon,測試可以偷懶都放一種尺寸的icon。修改manifest.json為:
{
"name": "testPlugin",
"description": "這是一個測試用例",
"version": "0.0.1",
"manifest_version": 2,
"icons": {
"16": "icons/16.png",
"48": "icons/16.png"
}
}
這時候在擴展程序中加載已解壓的程序(就是我們創(chuàng)建的文件夾),就可以看到雛形了:

3.選擇性地添加點擊插件icon瀏覽器右上角彈出來的框
"browser_action": {
"default_title": "test plugin",
"default_icon": "icons/16.png",
"default_popup": "index.html"
}
testPlugin創(chuàng)建index.html文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>test plugin</title> </head> <body> <input id="name" placeholder="請輸入"/> </body> </html>
刷新插件,這時候點擊瀏覽器中剛剛添加的插件的icon,就會彈出:

4.js事件(樣式同理)
document.getElementById('button').onclick = function() {
alert(document.getElementById('name').value)
}
html中:
<input id="name" placeholder="請輸入"/> <input id="button" type="button" value="點擊"/> <script src="js/index.js"></script>
刷新插件,這時候點擊瀏覽器中剛剛添加的插件的icon,就會彈出輸入框中的值:

一個嵌入網(wǎng)頁中的懸浮框
上述例子是點擊icon瀏覽器右上角出現(xiàn)的小彈窗,
引入vue.js、element-ui
下載合適版本的vue.js和element-ui等插件,同樣按照index.js一樣的操作引入,如果沒有下載單獨js文件的地址,可以打開cdn地址直接將壓縮后的代碼復(fù)制。
manifest.json中添加:
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"css": [
"css/index.css"
],
"js": [
"js/vue.js",
"js/element.js",
"js/index.js"
],
"run_at": "document_idle"
}
],
在index.js文件:
這里使用在head里插入link 的方式引入element-ui的css,減少插件包的一點大小,當(dāng)然也可以像引入index.js那樣在manifest.json中引入。
直接在index.js文件中寫Vue實例,不過首先得創(chuàng)建掛載實例的節(jié)點:
let element = document.createElement('div')
let attr = document.createAttribute('id')
attr.value = 'appPlugin'
element.setAttributeNode(attr)
document.getElementsByTagName('body')[0].appendChild(element)
let link = document.createElement('link')
let linkAttr = document.createAttribute('rel')
linkAttr.value = 'stylesheet'
let linkHref = document.createAttribute('href')
linkHref.value = 'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
link.setAttributeNode(linkAttr)
link.setAttributeNode(linkHref)
document.getElementsByTagName('head')[0].appendChild(link)
const vue = new Vue({
el: '#appPlugin',
template:`
<div class="app-plugin-content">{{text}}{{icon_post_message}}<el-button @click="Button">Button</el-button></div>
`,
data: function () {
return { text: 'hhhhhh', icon_post_message: '_icon_post_message', isOcContentPopShow: true }
},
mounted() {
console.log(this.text)
},
methods: {
Button() {
this.isOcContentPopShow = false
}
}
})
讓我們來寫一個簡易替換網(wǎng)頁背景顏色工具
index.js:
let element = document.createElement('div')
let attr = document.createAttribute('id')
attr.value = 'appPlugin'
element.setAttributeNode(attr)
document.getElementsByTagName('body')[0].appendChild(element)
let link = document.createElement('link')
let linkAttr = document.createAttribute('rel')
linkAttr.value = 'stylesheet'
let linkHref = document.createAttribute('href')
linkHref.value = 'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
link.setAttributeNode(linkAttr)
link.setAttributeNode(linkHref)
document.getElementsByTagName('head')[0].appendChild(link)
const vue = new Vue({
el: '#appPlugin',
template: `
<div v-if="isOcContentPopShow" class="oc-move-page" id="oc_content_page">
<div class="oc-content-title" id="oc_content_title">顏色 <el-button type="text" icon="el-icon-close" @click="close"></el-button></div>
<div class="app-plugin-content">背景:<el-color-picker v-model="color1"></el-color-picker></div>
<div class="app-plugin-content">字體:<el-color-picker v-model="color2"></el-color-picker></div>
</div>
`,
data: function () {
return { color1: null, color2: null, documentArr: [], textArr: [], isOcContentPopShow: true }
},
watch: {
color1(val) {
let out = document.getElementById('oc_content_page')
let outC = document.getElementsByClassName('el-color-picker__panel')
this.documentArr.forEach(item => {
if(!out.contains(item) && !outC[0].contains(item) && !outC[1].contains(item)) {
item.style.cssText = `background-color: ${val}!important;color: ${this.color2}!important;`
}
})
},
color2(val) {
let out = document.getElementById('oc_content_page')
let outC = document.getElementsByClassName('el-color-picker__panel')[1]
this.textArr.forEach(item => {
if(!out.contains(item) && !outC.contains(item)) {
item.style.cssText = `color: ${val}!important;`
}
})
}
},
mounted() {
chrome.runtime.onConnect.addListener((res) => {
if (res.name === 'testPlugin') {
res.onMessage.addListener(mess => {
this.isOcContentPopShow = mess.isShow
})
}
})
this.$nextTick(() => {
let bodys = [...document.getElementsByTagName('body')]
let headers = [...document.getElementsByTagName('header')]
let divs = [...document.getElementsByTagName('div')]
let lis = [...document.getElementsByTagName('li')]
let articles = [...document.getElementsByTagName('article')]
let asides = [...document.getElementsByTagName('aside')]
let footers = [...document.getElementsByTagName('footer')]
let navs = [...document.getElementsByTagName('nav')]
this.documentArr = bodys.concat(headers, divs, lis, articles, asides, footers, navs)
let as = [...document.getElementsByTagName('a')]
let ps = [...document.getElementsByTagName('p')]
this.textArr = as.concat(ps)
})
},
methods: {
close() {
this.isOcContentPopShow = false
}
}
})
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>my plugin</title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div class="plugin">
<input id="plugin_button" type="button" value="打開" />
</div>
</body>
<script src="js/icon.js"></script>
</html>
新建icon.js:
plugin_button.onclick = function () {
mess()
}
async function mess () {
const tabId = await getCurrentTabId()
const connect = chrome.tabs.connect(tabId, {name: 'testPlugin'});
connect.postMessage({isShow: true})
}
function getCurrentTabId() {
return new Promise((resolve, reject) => {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
resolve(tabs.length ? tabs[0].id : null)
});
})
}
這樣一個小嘗試就完成了,當(dāng)然如果有更多需求可以結(jié)合本地存儲或者服務(wù)端來協(xié)作。
總結(jié)
到此這篇關(guān)于vue+element開發(fā)一個谷歌插件的文章就介紹到這了,更多相關(guān)vue+element開發(fā)插件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue3中導(dǎo)入和使用組件幾種常見方法(.vue文件)
組件是Vue.js最強大的功能之一, 組件可以擴展HTML元素,封裝可重用的代碼,下面這篇文章主要介紹了Vue3中導(dǎo)入和使用組件幾種常見方法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-09-09
vue學(xué)習(xí)筆記之給組件綁定原生事件操作示例
這篇文章主要介紹了vue學(xué)習(xí)筆記之給組件綁定原生事件操作,結(jié)合實例形式詳細分析了vue.js組件綁定原生事件相關(guān)原理、實現(xiàn)方法與操作注意事項,需要的朋友可以參考下2020-02-02
前端vue面試總問watch和computed區(qū)別及建議總結(jié)
在現(xiàn)代前端的面試中,vue和react是面試過程中基本必問的技術(shù)棧,其中Vue響應(yīng)式話題,watch和computed是面試官非常喜歡聊的主題,雖然watch和computed它們都用于監(jiān)聽數(shù)據(jù)的變化,但它們在實現(xiàn)原理、使用場景和行為上有著顯著的區(qū)別,本文將深入探討,并提供一些面試過程中的建議2023-10-10
element vue validate驗證名稱重復(fù) 輸入框與后臺重復(fù)驗證 特殊字符 字符長度 及注意事項小結(jié)【實例代碼
這篇文章主要介紹了element vue validate驗證名稱重復(fù) 輸入框與后臺重復(fù)驗證 特殊字符 字符長度 及注意事項小結(jié),本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2018-11-11

