Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产精品成人久久久,亚洲成人综合网站,亚洲春色第一页

          整合營(yíng)銷(xiāo)服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢(xún)熱線:

          高質(zhì)量 Vue.js 自定義彈窗組件VPopup

          很早之前就有寫(xiě)過(guò)一個(gè)wcPop.js彈窗插件,并且在h5酒店預(yù)訂、h5聊天室項(xiàng)目中都有使用過(guò),效果還不錯(cuò)。當(dāng)初想著有時(shí)間整合一個(gè)Vue版本,剛好趁著國(guó)慶節(jié)空閑時(shí)間搗鼓了個(gè)vue.js版自定義模態(tài)彈出框組件VPopup

          v-popup 一款聚合Msg、Dialog、Popup、ActionSheet、Toast等功能的輕量級(jí)移動(dòng)端Vue彈窗組件。

          整合了有贊VantNutUI等熱門(mén)Vue組件庫(kù)中Popup彈出層、Toast輕提示、Notify消息提示、Dialog對(duì)話框及ActionSheet動(dòng)作面板等功能。

          使用組件

          // 在main.js中全局引入
          import Vue from 'vue'
          
          import Popup from './components/popup'
          Vue.use(Popup)

          支持如下兩種方式調(diào)用組件。

          • 標(biāo)簽式調(diào)用
          <v-popup
            v-model="showPopup"
            title="標(biāo)題內(nèi)容" 
            content="彈窗內(nèi)容,告知當(dāng)前狀態(tài)、信息和解決方法,描述文字盡量控制在三行內(nèi)"
            type="android"
            shadeClose="false"
            xclose
            z-index="2000"
            :btns="[
              {...},
              {...},
            ]"
          />
          • 函數(shù)式調(diào)用

          this.$vpopup({...}),傳入?yún)?shù)即可使用,該函數(shù)會(huì)返回彈窗組件實(shí)例。

          let $el = this.$vpopup({
            title: '標(biāo)題內(nèi)容',
            content: '彈窗內(nèi)容,描述文字盡量控制在三行內(nèi)',
            type: 'android',
            shadeClose: false,
            xclose: true,
            zIndex: 2000,
            btns: [
              {text: '取消'},
              {
                text: '確認(rèn)',
                style: 'color:#f60;',
                click: () => {
                  $el.close()
                }
              },
            ]
          });

          你可根據(jù)喜好或項(xiàng)目需要任意選擇一種調(diào)用方式即可。下面就開(kāi)始講解下組件的實(shí)現(xiàn)。

          在components目錄下新建popup.vue頁(yè)面。

          組件參數(shù)配置

          <!-- Popup 彈出層模板 -->
          <template>
            <div v-show="opened" class="nuxt__popup" :class="{'nuxt__popup-closed': closeCls}" :id="id">
              <div v-if="JSON.parse(shade)" class="nuxt__overlay" @click="shadeClicked" :style="{opacity}"></div>
              <div class="nuxt__wrap">
                <div class="nuxt__wrap-section">
                  <div class="nuxt__wrap-child" :class="['anim-'+anim, type&&'popui__'+type, round&&'round', position]" :style="popupStyle">
                    <div v-if="title" class="nuxt__wrap-tit" v-html="title"></div>
                    <div v-if="type=='toast'&&icon" class="nuxt__toast-icon" :class="['nuxt__toast-'+icon]" v-html="toastIcon[icon]"></div>
                    <template v-if="$slots.content">
                      <div class="nuxt__wrap-cnt"><slot name="content" /></div>
                    </template>
                    <template v-else>
                      <div v-if="content" class="nuxt__wrap-cnt" v-html="content"></div>
                    </template>
                    <slot />
                    <div v-if="btns" class="nuxt__wrap-btns">
                      <span v-for="(btn,index) in btns" :key="index" class="btn" :class="{'btn-disabled': btn.disabled}" :style="btn.style" @click="btnClicked($event,index)" v-html="btn.text"></span>
                    </div>
                    <span v-if="xclose" class="nuxt__xclose" :class="xposition" :style="{'color': xcolor}" @click="close"></span>
                  </div>
                </div>
              </div>
            </div>
          </template>
          <script>
            // 彈窗索引,遮罩次數(shù),定時(shí)器
            let $index = 0, $lockCount = 0, $timer = {};
            export default {
              props: {
                ...
              },
              data() {
                return {
                  opened: false,
                  closeCls: '',
                  toastIcon: {
                    loading: '<svg viewBox="25 25 50 50"><circle fill="none" cx="50" cy="50" r="20"></circle></svg>',
                    success: '<svg viewBox="0 0 1024 1024"><path fill="none" d="M75.712 445.712l240.176 185.52s13.248 6.624 29.808 0l591.36-493.872s84.272-17.968 68.64 71.488c-57.04 57.968-638.464 617.856-638.464 617.856s-38.096 21.536-74.544 0C256.272 790.256 12.816 523.568 12.816 523.568s-6.672-64.592 62.896-77.856z"/></svg>',
                    fail: '<svg viewBox="0 0 1024 1024"><path fill="none" d="M450.602 665.598a62.464 62.464 0 0 0 122.88 0l40.96-563.198A102.615 102.615 0 0 0 512.042 0a105.256 105.256 0 0 0-102.4 112.64l40.96 552.958zm61.44 153.6a102.4 102.4 0 1 0 102.4 102.4 96.74 96.74 0 0 0-102.4-102.4z"/></svg>',
                  }
                }
              },
              watch: {
                value(val) {
                  const type = val ? 'open' : 'close';
                  this[type]();
                },
              },
              methods: {
                // 打開(kāi)彈窗
                open() {
                  if(this.opened) return;
                  this.opened = true;
                  this.$emit('open');
                  typeof this.onOpen === 'function' && this.onOpen();
                  this.$el.style.zIndex = this.getZIndex() + 1;
                  
                  if(JSON.parse(this.shade)) {
                    if(!$lockCount) {
                      document.body.classList.add('nt-overflow-hidden');
                    }
                    $lockCount++;
                  }
                  
                  // 倒計(jì)時(shí)關(guān)閉
                  if(this.time) {
                    $index++;
                    // 防止重復(fù)點(diǎn)擊
                    if($timer[$index] !== null) clearTimeout($timer[$index])
                    $timer[$index] = setTimeout(() => {
                      this.close();
                    }, parseInt(this.time) * 1000);
                  }
          
                  // 長(zhǎng)按/右鍵彈窗
                  if(this.follow) {
                    // 避免獲取不到彈窗寬高
                    this.$nextTick(() => {
                      let obj = this.$el.querySelector('.nuxt__wrap-child');
                      let oW, oH, winW, winH, pos;
          
                      oW = obj.clientWidth;
                      oH = obj.clientHeight;
                      winW = window.innerWidth;
                      winH = window.innerHeight;
                      pos = this.getPos(this.follow[0], this.follow[1], oW, oH, winW, winH);
          
                      obj.style.left = pos[0] + 'px';
                      obj.style.top = pos[1] + 'px';
                    });
                  }
                },
                // 關(guān)閉彈窗
                close() {
                  if(!this.opened) return;
                  
                  this.closeCls = true;
                  setTimeout(() => {
                    this.opened = false;
                    this.closeCls = false;
                    if(JSON.parse(this.shade)) {
                      $lockCount--;
                      if(!$lockCount) {
                        document.body.classList.remove('nt-overflow-hidden');
                      }
                    }
                    if(this.time) {
                      $index--;
                    }
                    this.$emit('input', false);
                    this.$emit('close');
                    typeof this.onClose === 'function' && this.onClose();
                  }, 200);
                },
          
                // 點(diǎn)擊遮罩層
                shadeClicked() {
                  if(JSON.parse(this.shadeClose)) {
                    this.close();
                  }
                },
                // 按鈕事件
                btnClicked(e, index) {
                  let btn = this.btns[index];
                  if(!btn.disabled) {
                    typeof btn.click === 'function' && btn.click(e)
                  }
                },
                // 獲取彈窗層級(jí)
                getZIndex() {
                  for(var $idx = parseInt(this.zIndex), $el = document.getElementsByTagName('*'), i = 0, len = $el.length; i < len; i++)
                    $idx = Math.max($idx, $el[i].style.zIndex)
                  return $idx;
                },
                // 獲取彈窗坐標(biāo)點(diǎn)
                getPos(x, y, ow, oh, winW, winH) {
                  let l = (x + ow) > winW ? x - ow : x;
                  let t = (y + oh) > winH ? y - oh : y;
                  return [l, t];
                }
              },
            }
          </script>

          通過(guò)監(jiān)聽(tīng)v-model值調(diào)用open和close方法。

          watch: {
              value(val) {
                  const type = val ? 'open' : 'close';
                  this[type]();
              },
          },

          如果想要實(shí)現(xiàn)函數(shù)式調(diào)用this.$vpopup({...}),則需要使用到Vue.extend擴(kuò)展實(shí)例構(gòu)造器。

          import Vue from 'vue';
          import VuePopup from './popup.vue';
          
          let PopupConstructor = Vue.extend(VuePopup);
          
          let $instance;
          
          let VPopup = function(options = {}) {
              // 同一個(gè)頁(yè)面中,id相同的Popup的DOM只會(huì)存在一個(gè)
              options.id = options.id || 'nuxt-popup-id';
          
              $instance = new PopupConstructor({
                  propsData: options
              });
          
              $instance.vm = $instance.$mount();
              
              let popupDom = document.querySelector('#' + options.id);
              if(options.id && popupDom) {
                  popupDom.parentNode.replaceChild($instance.$el, popupDom);
              } else {
                  document.body.appendChild($instance.$el);
              }
          
              Vue.nextTick(() => {
                  $instance.value = true;
              })
          
              return $instance;
          }
          
          VPopup.install = () => {
              Vue.prototype['$vpopup'] = VPopup;
              Vue.component('v-popup', VuePopup);
          }
          
          export default VPopup;

          這樣就實(shí)現(xiàn)了引入 Popup 組件后,會(huì)自動(dòng)在 Vue 的 prototype 上掛載 $vpopup 方法和注冊(cè) v-popup 組件。

          下面就可以愉快的使用標(biāo)簽式及函數(shù)式調(diào)用組件了。

          • 設(shè)置圓角及關(guān)閉按鈕

          <v-popup v-model="showActionPicker" anim="footer" type="actionsheetPicker" round title="標(biāo)題內(nèi)容"
              :btns="[
                  {text: '取消', click: () => showActionPicker=false},
                  {text: '確定', style: 'color:#00e0a1;', click: () => null},
              ]"
          >
              <ul class="goods-list" style="padding:50px;text-align:center;">
                  <li>雙肩包</li>
                  <li>鞋子</li>
                  <li>運(yùn)動(dòng)褲</li>
              </ul>
          </v-popup>
          
          <v-popup v-model="showBottom" position="bottom" round xclose title="標(biāo)題內(nèi)容">
              <ul class="goods-list" style="padding:50px;text-align:center;">
                  <li>雙肩包</li>
                  <li>鞋子</li>
                  <li>運(yùn)動(dòng)褲</li>
              </ul>
          </v-popup>
          • 設(shè)置按鈕禁用狀態(tài)

          按鈕設(shè)置disabled: true即可禁用按鈕事件。

          <v-popup v-model="showActionSheet" anim="footer" type="actionsheet" :z-index="2020"
              content="彈窗內(nèi)容,描述文字盡量控制在三行內(nèi)"
              :btns="[
                  {text: '拍照', style: 'color:#09f;', disabled: true, click: handleInfo},
                  {text: '從手機(jī)相冊(cè)選擇', style: 'color:#00e0a1;', click: handleInfo},
                  {text: '保存圖片', style: 'color:#e63d23;', click: () => null},
                  {text: '取消', click: () => showActionSheet=false},
              ]"
          />

          另外還支持自定義slot插槽內(nèi)容,當(dāng) content 和 自定義插槽 內(nèi)容同時(shí)存在,只顯示插槽內(nèi)容。

          <v-popup v-model="showComponent" xclose xposition="bottom" content="這里是內(nèi)容信息"
              :btns="[
                  {text: '確認(rèn)', style: 'color:#f60;', click: () => showComponent=false},
              ]"
              @open="handleOpen" @close="handleClose"
          >
              <template #content>當(dāng) content 和 自定義插槽 內(nèi)容同時(shí)存在,只顯示插槽內(nèi)容!</template>
              <div style="padding:30px 15px;">
                  <img src="assets/apple3.jpg" style="width:100%;" @click="handleContextPopup" />
              </div>
          </v-popup>

          好了,就分享到這里。希望對(duì)大家有所幫助。目前該組件正在項(xiàng)目中實(shí)戰(zhàn)測(cè)試,后續(xù)會(huì)分享相關(guān)使用情況。

          嗨,各位極客;在你的瀏覽器中裝上了多少插件呢?讓我猜猜:tampermonkey 油猴腳本,Chrono下載管理器,bilibilihelper,喔當(dāng)然還有必不可少的 Adblock。有了解過(guò)這些插件是怎么運(yùn)作的么?想要完成一個(gè)自己的插件么?快和我一起動(dòng)手吧!


          基礎(chǔ)知識(shí)

          本文參考 Chrome Extensions V3版本 開(kāi)發(fā)指南,接下來(lái)我們簡(jiǎn)單地介紹一下一個(gè)插件的組成,

          Chrome 插件通常由以下幾部分組成:

          • manifest.json:插件的 meta 信息,包含插件的名稱(chēng)、版本號(hào)、圖標(biāo)、腳本文件名稱(chēng)等信息,從這里你可以看到全部的參數(shù)。
          • popup:點(diǎn)擊插件觸發(fā)的彈框頁(yè)面,會(huì)創(chuàng)建一個(gè)獨(dú)立的瀏覽器頁(yè)面實(shí)例。
          • options:插件的擴(kuò)展配置頁(yè)面,會(huì)創(chuàng)建一個(gè)獨(dú)立的瀏覽器頁(yè)面實(shí)例。
          • background.js:插件的后臺(tái)運(yùn)行腳本,單獨(dú)地運(yùn)行在一個(gè)瀏覽器實(shí)例中。


          manifest.json 示例

          {
            "manifest_version": 3,
            "name": "Chrome 插件開(kāi)發(fā) 示例",
            "description": "這是一個(gè) Chrome 開(kāi)發(fā)示例工程",
            "version": "1.0",
            "permissions": [ // 插件需要的權(quán)限信息 依次為:數(shù)據(jù)存儲(chǔ)、訪問(wèn)活躍的標(biāo)簽頁(yè)、執(zhí)行插入腳本
              "storage", "activeTab", "scripting"
            ],
            // 時(shí)間
            "action": {
              // 設(shè)置插件在插件區(qū)域的icon
              "default_icon": {
                "16": "readIcon.png",
                "32": "readIcon.png",
                "64": "readIcon.png",
                "128": "readIcon.png"
              },
              // 插件在插件區(qū)域被點(diǎn)擊時(shí)的彈出頁(yè)面
              "default_popup": "popup.html"
            },
            // 后臺(tái)運(yùn)行腳本
            "background": {
              "service_worker": "background.js"
            },
            // 全局icon 會(huì)出現(xiàn)在配置頁(yè)面的icon中
            "icons": {
              "16": "bookIcon.png",
              "32": "bookIcon.png",
              "64": "bookIcon.png",
              "128": "bookIcon.png"
            },
            // 配置頁(yè)面
            "options_page": "options.html"
          }

          popup 事件

          在插件區(qū)域點(diǎn)擊咱們插件后將觸發(fā)popup 事件,喚起 popup.html 頁(yè)面

          option 事件

          點(diǎn)擊右鍵插件中的選項(xiàng)按鈕,將觸發(fā)option 事件,喚起 options.html 頁(yè)面

          background 事件

          當(dāng)插件被載入后,將后臺(tái)執(zhí)行 background.js 腳本

          開(kāi)始動(dòng)手

          我們將按照官方示例完成一個(gè)示例工程,在這個(gè)工程中,我們將提供一個(gè)可以設(shè)置網(wǎng)頁(yè)背景顏色的小工具,并且在配置頁(yè)面提供多個(gè)顏色供用戶選擇。


          那我們就開(kāi)始吧!先創(chuàng)建一個(gè)文件夾,命名為 start,然后用編輯器打開(kāi)文件夾,開(kāi)始編碼啦,我使用的是vscode,當(dāng)然任何編輯器都可以完成這項(xiàng)編碼。

          創(chuàng)建 manifest.json 描述文件

          創(chuàng)建一個(gè) manifest.json 文件

          {
            "manifest_version": 3,
            "name": "Chrome 插件開(kāi)發(fā) 示例",
            "description": "這是一個(gè) Chrome 開(kāi)發(fā)示例工程",
            "version": "1.0",
            "permissions": [
              "storage", "activeTab", "scripting"
            ],
            "background": {
              "service_worker": "background.js"
            },
            "icons": {
              "16": "icon.png",
              "32": "icon.png",
              "64": "icon.png",
              "128": "icon.png"
            },
          }

          找一張你喜歡的照片,命名為icon并添加到文件夾中,這里先沒(méi)有配置popup頁(yè)面和option頁(yè)面,不著急,一步步來(lái)。

          Background Js 后臺(tái)執(zhí)行程序

          創(chuàng)建一個(gè) background.js 文件

          // 初始化一個(gè)顏色值
          let color = '#3aa757';
          
          // 在chrome瀏覽器創(chuàng)建的時(shí)候,設(shè)置顏色初始值
          chrome.runtime.onInstalled.addListener(() => {
            // 需要注意的是,此時(shí)設(shè)置的持久對(duì)象的鍵名為 color 其值為 #3aa757
            chrome.storage.sync.set({ color });
            console.log('設(shè)置一個(gè)默認(rèn)的顏色,默認(rèn)顏色值為綠色 %cgreen', `color: ${color}`);
          });

          然后就可以嘗試一下插件的運(yùn)行啦,進(jìn)入插件頁(yè)面,先在右上角開(kāi)啟開(kāi)發(fā)者模式,然后點(diǎn)擊加載已解壓的擴(kuò)展程序,找到你的 start 文件夾加載進(jìn)來(lái)。

          此時(shí)頁(yè)面上就會(huì)出現(xiàn)你的插件了,你會(huì)發(fā)現(xiàn)在有一個(gè)Service Worker視圖可以點(diǎn)擊,點(diǎn)擊查看一下

          你就可以看到 background.js 成功運(yùn)行并打印了日志

          Popup 彈出頁(yè)面

          接下來(lái)我們配置一個(gè)彈出頁(yè)面,創(chuàng)建 popup.html

          <!doctype html>
          <html>
            <head>
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
              <title>插件彈出頁(yè)面</title>
              <link rel="stylesheet" href="button.css">
            </head>
            <body>
              <button id="changeColor"></button>
              <img url="icon.png"/>
              <!-- 引入js -->
              <script src="popup.js"></script>
            </body>
          </html>

          創(chuàng)建 popup.js

          // 獲得 改變顏色的按鈕
          let changeColor = document.getElementById("changeColor");
          
          // 獲取當(dāng)前已設(shè)置顏色
          chrome.storage.sync.get("color", ({ color }) => {
            changeColor.style.backgroundColor = color;
          });
          
          // 創(chuàng)建按鈕點(diǎn)擊事件 觸發(fā)對(duì)當(dāng)前激活的瀏覽器窗口中的當(dāng)前激活的選項(xiàng)卡設(shè)置背景顏色
          changeColor.addEventListener("click", async () => {
            let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
            
            // 注入執(zhí)行js代碼
            chrome.scripting.executeScript({
              target: { tabId: tab.id },
              function: setPageBackgroundColor,
            });
          });
          
          // 注入執(zhí)行的方法塊
          // 設(shè)置body的背景顏色為目標(biāo)顏色
          function setPageBackgroundColor() {
            chrome.storage.sync.get("color", ({ color }) => {
              document.body.style.backgroundColor = color;
            });
          }

          創(chuàng)建 button.css

          body {
            min-width: 357px;
            overflow-x: hidden;
          }
          
          img {
            margin: 5px;
            border: 2px solid black;
            vertical-align: middle;
            width: 75px;
            height: 75px;
          }
          
          button {
            height: 30px;
            width: 30px;
            outline: none;
            margin: 10px;
            border: none;
            border-radius: 2px;
          }
          
          button.current {
            box-shadow: 0 0 0 2px white,
                        0 0 0 4px black;
          }

          喔當(dāng)然,還要修改 manifest.json,添加上 popup.html的配置,還需要準(zhǔn)備一張?jiān)诓寮^(qū)域展示的 popupIcon 照片。

          {
            "manifest_version": 3,
            "name": "Chrome 插件開(kāi)發(fā) 示例",
            ... 省略 ...
              "128": "icon.png"
            },
            "action": {
              "default_icon": {
                "16": "popupIcon.png",
                "32": "popupIcon.png",
                "64": "popupIcon.png",
                "128": "popupIcon.png"
              },
              "default_popup": "popup.html"
            }
          }

          然后在插件頁(yè)面刷新重新加載

          這時(shí)候我們就可以點(diǎn)擊插件啦,按照1點(diǎn)擊插件,然后點(diǎn)擊2,觸發(fā)按鈕事件

          bingo! 當(dāng)前頁(yè)面的背景顏色變成綠色了。

          似乎只有一個(gè)綠色不太合適,我們得為用戶提供更多的選擇,那就再做一個(gè)選項(xiàng)頁(yè)面,提供配置功能吧。


          Option 選項(xiàng)配置頁(yè)面

          創(chuàng)建 options.html

          <!DOCTYPE html>
          <html>
          
          <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
            <title>插件選項(xiàng)配置頁(yè)面</title>
            <link rel="stylesheet" href="button.css">
          </head>
          
          <body>
            <div id="buttonDiv">
            </div>
            <div>
              <p>選擇一個(gè)新的背景顏色</p>
            </div>
            <script src="options.js"></script>
          </body>
          
          </html>

          創(chuàng)建 options.js

          // 獲取按鈕區(qū)域 div
          let page = document.getElementById("buttonDiv");
          // button.css 有一個(gè) button current css 樣式,為選中的顏色添加出黑色邊框
          let selectedClassName = "current";
          // 設(shè)置待選顏色按鈕
          const presetButtonColors = ["#3aa757", "#e8453c", "#f9bb2d", "#4688f1"];
          
          // 創(chuàng)建按鈕事件 通過(guò)標(biāo)記所選按鈕 保存顏色
          function handleButtonClick(event) {
            // 從事件的父級(jí)中找到之前被選中的按鈕
            let current = event.target.parentElement.querySelector(
              `.${selectedClassName}`
            );
            // 從他的class列表中去掉選中狀態(tài)
            if (current && current !== event.target) {
              current.classList.remove(selectedClassName);
            }
          
            // 獲取按鈕攜帶的數(shù)據(jù)信息 也就是我們想要的顏色
            let color = event.target.dataset.color;
            // 添加選中狀態(tài)
            event.target.classList.add(selectedClassName);
            // 設(shè)置當(dāng)前選中顏色
            chrome.storage.sync.set({ color });
          }
          
          // 按顏色列表依次添加按鈕到頁(yè)面
          function constructOptions(buttonColors) {
            // 獲取當(dāng)前已設(shè)置的顏色
            chrome.storage.sync.get("color", (data) => {
              let currentColor = data.color;
              // 循環(huán)顏色列表
              for (let buttonColor of buttonColors) {
                // 創(chuàng)建按鈕 賦予按鈕顏色
                let button = document.createElement("button");
                button.dataset.color = buttonColor;
                button.style.backgroundColor = buttonColor;
          
                // 如果是當(dāng)前已選中的按鈕,則設(shè)置
                if (buttonColor === currentColor) {
                  button.classList.add(selectedClassName);
                }
          
                // 創(chuàng)建點(diǎn)擊事件
                button.addEventListener("click", handleButtonClick);
                // 添加回頁(yè)面上
                page.appendChild(button);
              }
            });
          }
          
          // js 被加載后 自執(zhí)行初始化方法 創(chuàng)建按鈕
          constructOptions(presetButtonColors);

          然后再修改一次 manifest.json

          {
            "manifest_version": 3,
            "name": "Chrome 插件開(kāi)發(fā) 示例",
            ... 省略 ...
              "default_popup": "popup.html"
            },
            "options_page": "options.html"
          }

          然后再重載一次插件,bingo!右鍵我們的插件就多出選項(xiàng)頁(yè)面啦

          點(diǎn)擊進(jìn)入選項(xiàng)頁(yè)面,出現(xiàn)了我們?cè)诖a中配置的四個(gè)顏色了,隨便點(diǎn)選其他三種顏色。

          我們就可以驚喜的發(fā)現(xiàn)在popup頁(yè)面的按鈕顏色也發(fā)生了變化了。

          小結(jié)

          至此,我們的起步示例工程的開(kāi)發(fā)就完成了。

          在這次工程中,我們完成了配置基本信息、開(kāi)發(fā)了popup 彈出頁(yè)面、option 配置頁(yè)面,并實(shí)現(xiàn)了多頁(yè)面間的數(shù)據(jù)共享功能,并了解到各個(gè)頁(yè)面間的通信都需要通過(guò)第三者進(jìn)行處理,因?yàn)楸举|(zhì)上每個(gè)頁(yè)面都是獨(dú)立的進(jìn)程。


          那我想提個(gè)小問(wèn)題,如果我想在選項(xiàng)配置頁(yè)面選擇了顏色之后,然后再點(diǎn)擊到一個(gè)具體的選項(xiàng)卡中自動(dòng)幫我修改背景顏色,應(yīng)該怎么實(shí)現(xiàn)呢?


          谷歌插件示例工程

          https://github.com/GoogleChrome/chrome-extensions-samples

          谷歌插件官方文檔

          https://developer.chrome.com/docs/extensions/


          Vue中實(shí)現(xiàn)打印預(yù)覽和打印功能,你可以使用原生的JavaScript方法,或者使用第三方庫(kù),如vue-html2pdf 或 print.js。

          以下是使用原生JavaScript方法實(shí)現(xiàn)打印功能的基本步驟:

          1. 創(chuàng)建一個(gè)新的窗口或者iframe,將要打印的內(nèi)容寫(xiě)入。
          2. 調(diào)用新窗口或iframe的print()方法。

          以下是一個(gè)簡(jiǎn)單的Vue組件示例,它包含一個(gè)打印按鈕,點(diǎn)擊該按鈕會(huì)觸發(fā)打印功能:

          <template>  
            <div>  
              <div ref="printSection">  
                <h1>{{ title }}</h1>  
                <p>{{ description }}</p>  
              </div>  
              <button @click="print">打印</button>  
            </div>  
          </template>  
            
          <script>  
          export default {  
            data() {  
              return {  
                title: 'Vue 打印示例',  
                description: '這是一個(gè)Vue打印功能的簡(jiǎn)單示例。'  
              }  
            },  
            methods: {  
              print() {  
                let printContents = this.$refs.printSection.innerHTML;  
                let originalContents = document.body.innerHTML;  
            
                document.body.innerHTML = printContents;  
            
                window.print();  
            
                document.body.innerHTML = originalContents;  
              }  
            }  
          }  
          </script>

          但是這種方法有個(gè)問(wèn)題,就是會(huì)改變當(dāng)前頁(yè)面的內(nèi)容。為了避免這個(gè)問(wèn)題,我們可以使用一個(gè)新的窗口或者iframe來(lái)進(jìn)行打印。

          這是一個(gè)使用新窗口進(jìn)行打印的示例:

          <template>  
            <div>  
              <div ref="printSection">  
                <h1>{{ title }}</h1>  
                <p>{{ description }}</p>  
              </div>  
              <button @click="print">打印</button>  
            </div>  
          </template>  
            
          <script>  
          export default {  
            data() {  
              return {  
                title: 'Vue 打印示例',  
                description: '這是一個(gè)Vue打印功能的簡(jiǎn)單示例。'  
              }  
            },  
            methods: {  
              print() {  
                let printContents = this.$refs.printSection.innerHTML;  
                let popup = window.open('', '_blank');  
                popup.document.write(printContents);  
                popup.document.close();  
                popup.print();  
              }  
            }  
          }  
          </script>

          以上代碼實(shí)現(xiàn)了基本的打印功能,但并未實(shí)現(xiàn)打印預(yù)覽功能。實(shí)現(xiàn)打印預(yù)覽功能通常需要使用到第三方庫(kù),或者利用瀏覽器的打印對(duì)話框進(jìn)行預(yù)覽。

          如果你想要實(shí)現(xiàn)更復(fù)雜的打印和預(yù)覽功能,我建議查看vue-html2pdf或print.js這樣的庫(kù)。它們提供了更多的配置選項(xiàng),并且可以更好地控制打印和預(yù)覽的行為。

          例如,使用vue-html2pdf庫(kù),你可以很容易地將HTML轉(zhuǎn)換為PDF,并提供下載或預(yù)覽功能。而print.js庫(kù)則提供了更多的打印選項(xiàng),包括打印到PDF,打印到紙張,以及自定義打印布局等。

          注意:以上代碼在真實(shí)環(huán)境中可能需要進(jìn)行一些調(diào)整,以適應(yīng)你的具體需求。例如,你可能需要處理跨域問(wèn)題,或者調(diào)整樣式以適應(yīng)打印布局。


          主站蜘蛛池模板: 精品日本一区二区三区在线观看| 国产高清在线精品一区二区三区 | 中文字幕日本精品一区二区三区| 中文字幕一区视频| 奇米精品一区二区三区在| 精品一区二区三区无码免费直播| 伊人久久大香线蕉AV一区二区| 精品一区二区三区免费| 精品国产亚洲一区二区三区| 一区二区三区免费高清视频| 国产伦精品一区二区| 国产91精品一区| 人妻无码一区二区三区| 日本一区二区三区不卡视频中文字幕 | 日韩一区二区超清视频| 末成年女AV片一区二区| 日韩高清国产一区在线| 一区二区视频在线播放| 国产成人精品日本亚洲专一区| 亚洲视频一区二区在线观看| 韩国一区二区视频| 久久精品日韩一区国产二区| 国产成人精品一区二三区熟女 | 亚洲高清毛片一区二区| 亚洲av无码一区二区三区天堂| 久久久久人妻精品一区三寸| 日本一区二区三区精品视频| 福利电影一区二区| 亚洲无线码一区二区三区| 无码av免费一区二区三区试看| 精品一区二区三区四区在线播放| 国产主播在线一区| 一区在线免费观看| 国产高清视频一区三区| 精品少妇ay一区二区三区| 无码日本电影一区二区网站| 国产一区二区三区小向美奈子| 精品亚洲一区二区三区在线观看| 在线观看午夜亚洲一区| 无码人妻精品一区二区三区99性| 九九无码人妻一区二区三区 |