主頁 > 企業開發 > 記錄--使用Vue開發Chrome插件

記錄--使用Vue開發Chrome插件

2022-10-23 08:19:49 企業開發

這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

環境搭建

Vue Web-Extension - A Web-Extension preset for VueJS (vue-web-extension.netlify.app)

npm install -g @vue/cli
npm install -g @vue/cli-init
vue create --preset kocal/vue-web-extension my-extension
cd my-extension
npm run server

會提供幾個選項,如Eslint,background.js,tab頁,axios,如下圖

選擇完后,將會自動下載依賴,通過npm run server將會在根目錄生成dist檔案夾,將該檔案拖至Chrome插件管理便可安裝,由于使用了webpack,所以更改代碼將會熱更新,不用反復的編譯匯入,

專案結構

├─src
|  ├─App.vue
|  ├─background.js
|  ├─main.js
|  ├─manifest.json
|  ├─views
|  |   ├─About.vue
|  |   └Home.vue
|  ├─store
|  |   └index.js
|  ├─standalone
|  |     ├─App.vue
|  |     └main.js
|  ├─router
|  |   └index.js
|  ├─popup
|  |   ├─App.vue
|  |   └main.js
|  ├─override
|  |    ├─App.vue
|  |    └main.js
|  ├─options
|  |    ├─App.vue
|  |    └main.js
|  ├─devtools
|  |    ├─App.vue
|  |    └main.js
|  ├─content-scripts
|  |        └content-script.js
|  ├─components
|  |     └HelloWorld.vue
|  ├─assets
|  |   └logo.png
├─public
├─.browserslistrc
├─.eslintrc.js
├─.gitignore
├─babel.config.js
├─package.json
├─vue.config.js
├─yarn.lock

根據所選的頁面,并在src與vue.config.js中配置頁面資訊編譯后dist目錄結構如下

├─devtools.html
├─favicon.ico
├─index.html
├─manifest.json
├─options.html
├─override.html
├─popup.html
├─_locales
├─js
├─icons
├─css

安裝組件庫

安裝elementUI

整體的開發和vue2開發基本上沒太大的區別,不過既然是用vue來開發的話,那肯定少不了組件庫了,

要匯入Element-ui也十分簡單,Vue.use(ElementUI); Vue2中怎么匯入element,便怎么匯入,演示如下

不過我沒有使用babel-plugin-component來按需引入,按需引入一個按鈕打包后大約1.6m,而全量引入則是5.5左右,至于為什么不用,因為我需要在content-scripts.js中引入element組件,如果使用babel-plugin-component將無法按需匯入組件以及樣式(應該是只支持vue檔案按需引入,總之就是折騰了我一個晚上的時間)

安裝tailwindcss

不過官方提供了如何使用TailwindCSS,這里就演示一下

在 Vue 3 和 Vite 安裝 Tailwind CSS - Tailwind CSS 中文檔案

推薦安裝低版本,最新版有兼容性問題

npm install tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9

創建postcss.config.js檔案

// postcss.config.js
module.exports = {
  plugins: [
    // ...
    require('tailwindcss'),
    require('autoprefixer'), // if you have installed `autoprefixer`
    // ...
  ]
}

創建tailwind.config.js檔案

// tailwind.config.js
module.exports = {
  purge: {
    // Specify the paths to all of the template files in your project
    content: ['src/**/*.vue'],
  
    // Whitelist selectors by using regular expression
    whitelistPatterns: [
        /-(leave|enter|appear)(|-(to|from|active))$/, // transitions
        /data-v-.*/, // scoped css
    ],
  }
  // ...
}

在src/popup/App.vue中匯入樣式,或在新建style.css在mian.js中import "../style.css";

<style>
/* purgecss start ignore */
@tailwind base;
@tailwind components;
/* purgecss end ignore */

@tailwind utilities;
</style>

從官方例子匯入一個登陸表單,效果如下

專案搭建

頁面搭建

頁面搭建就沒什么好說的了,因為使用的是element-ui,所以頁面很快就搭建完畢了,效果如圖

懸浮窗

懸浮窗其實可有可無,不過之前寫Chrome插件的時候就寫了懸浮窗,所以vue版的也順帶寫一份,

要注意的是懸浮窗是內嵌到網頁的(且在document加載前載入,也就是"run_at": "document_start"),所以需要通過content-scripts.js才能操作頁面Dom元素,首先在配置清單manifest.json與vue.confing.js中匹配要添加的網站,以及注入的js代碼,如下

  "content_scripts": [
    {
      "matches": ["https://www.bilibili.com/video/*"],
      "js": ["js/jquery.js", "js/content-script.js"],
      "css": ["css/index.css"],
      "run_at": "document_start"
    },
    {
      "matches": ["https://www.bilibili.com/video/*"],
      "js": ["js/jquery.js", "js/bilibili.js"],
      "run_at": "document_end"
    }
  ]

 

	contentScripts: {
          entries: {
            'content-script': ['src/content-scripts/content-script.js'],
            bilibili: ['src/content-scripts/bilibili.js'],
          },
        },

由于是用Vue,但又要在js中生成組件,就使用document.createElement來進行創建元素,Vue組件如下(可拖拽)

:::danger

如果使用babel-plugin-component按需引入,組件的樣式將無法載入,同時自定義組件如果撰寫了style標簽,那么也同樣無法載入,報錯:Cannot read properties of undefined (reading 'appendChild')

大致就是css-loader無法加載對應的css代碼,如果執意要寫css的話,直接在manifest.json中注入css即可

:::

完整代碼
// 注意,這里引入的vue是運行時的模塊,因為content是插入到目標頁面,對組件的渲染需要運行時的vue, 而不是編譯環境的vue (我也不知道我在說啥,反正大概意思就是這樣)
import Vue from 'vue/dist/vue.esm.js';
import ElementUI, { Message } from 'element-ui';
Vue.use(ElementUI);

// 注意,必須設定了run_at=document_start此段代碼才會生效
document.addEventListener('DOMContentLoaded', function() {
  console.log('vue-chrome擴展已載入');

  insertFloat();
});

// 在target頁面中新建一個帶有id的dom元素,將vue物件掛載到這個dom上,
function insertFloat() {
  let element = document.createElement('div');
  let attr = document.createAttribute('id');
  attr.value = 'https://www.cnblogs.com/smileZAZ/archive/2022/10/22/appPlugin';
  element.setAttributeNode(attr);
  document.getElementsByTagName('body')[0].appendChild(element);

  let link = document.createElement('link');
  let linkAttr = document.createAttribute('rel');
  linkAttr.value = 'https://www.cnblogs.com/smileZAZ/archive/2022/10/22/stylesheet';
  let linkHref = https://www.cnblogs.com/smileZAZ/archive/2022/10/22/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);

  let left = 0;
  let top = 0;
  let mx = 0;
  let my = 0;
  let onDrag = false;

  var drag = {
    inserted: function(el) {
      (el.onmousedown = function(e) {
        left = el.offsetLeft;
        top = el.offsetTop;
        mx = e.clientX;
        my = e.clientY;
        if (my - top > 40) return;

        onDrag = true;
      }),
        (window.onmousemove = function(e) {
          if (onDrag) {
            let nx = e.clientX - mx + left;
            let ny = e.clientY - my + top;
            let width = el.clientWidth;
            let height = el.clientHeight;
            let bodyWidth = window.document.body.clientWidth;
            let bodyHeight = window.document.body.clientHeight;

            if (nx < 0) nx = 0;
            if (ny < 0) ny = 0;

            if (ny > bodyHeight - height && bodyHeight - height > 0) {
              ny = bodyHeight - height;
            }

            if (nx > bodyWidth - width) {
              nx = bodyWidth - width;
            }

            el.style.left = nx + 'px';
            el.style.top = ny + 'px';
          }
        }),
        (el.onmouseup = function(e) {
          if (onDrag) {
            onDrag = false;
          }
        });
    },
  };

  window.kz_vm = new Vue({
    el: '#appPlugin',
    directives: {
      drag: drag,
    },
    template: `
      <div  ref="float" v-drag>
        <el-card  :body-style="{ padding: '15px' }">
          <div slot="header"  style="cursor: move">
            <span>懸浮窗</span>
            <el-button style="float: right; padding: 3px 0" type="text" @click="toggle">{{ show ? '收起' : '展開'}}</el-button>
          </div>
          <transition name="ul">
            <div v-if="show" >
              <span> {{user}} </span>
            </div>
          </transition>
        </el-card>
      </div>
      `,
    data: function() {
      return {
        show: true,
        list: [],
        user: {
          username: '',
          follow: 0,
          title: '',
          view: 0,
        },
      };
    },
    mounted() {},
    methods: {
      toggle() {
        this.show = !this.show;
      },
    },
  });
}
因為只能在js中撰寫vue組件,所以得用template模板,同時使用了directives,給組件添加了拖拽的功能(尤其是window.onmousemove,如果是元素系結他自身的滑鼠移動事件,那么拖拽滑鼠將會十分卡頓),還使用了transition來進行緩慢影片效果其中注入的css代碼如下
.float-page {
  width: 400px;
  border-radius: 8px;
  position: fixed;
  left: 50%;
  top: 25%;
  z-index: 1000001;
}

.el-card__header {
  padding: 10px 15px !important
}

.ul-box {
  height: 200px;
  overflow: hidden;
}

.ul-enter-active,
.ul-leave-active {
  transition: all 0.5s;
}
.ul-enter,
.ul-leave-to {
  height: 0;
}

相關邏輯可自行觀看,這里不在贅述了,并不復雜,

也順帶是復習一下HTML中滑鼠事件和vue自定義命令了

功能實作

主要功能

  • 檢測視頻頁面,輸出對應up主,關注數以及視頻標題播放(引數過多就不一一顯示了)

  • 監控關鍵詞根據內容判斷是否點贊,例如文本出現了下次一定,那么就點贊,

輸出相關資訊

這個其實只要接觸過一丟丟爬蟲的肯定都會知道如何實作,通過右鍵審查元素,像這樣

然后使用dom操作,選擇對應的元素,輸出便可

> document.querySelector("#v_upinfo > div.up-info_right > div.name > a.username").innerText
< '老番茄'

當然使用JQuery效果也是一樣的,后續我都會使用JQuery來進行操作

在src/content-script/bilibili.js中寫下如下代碼

window.onload = function() {
  console.log('加載完畢');

  function getInfo() {
    let username = $('#v_upinfo > div.up-info_right > div.name > a.username').text();
    let follow = $(`#v_upinfo > div.up-info_right > div.btn-panel > div.default-btn.follow-btn.btn-transition.b-gz.following > span > span > span`).text();
    let title = $(`#viewbox_report > h1 > span`).text();
    let view = $('#viewbox_report > div > span.view').attr('title');

    console.log(username, follow, title, view);
  }
  
  getInfo();
};

重新加載插件,然后輸出查看結果

加載完畢
bilibili.js:19 老番茄 1606.0萬 頂級畫質 總播放數2368406

這些資料肯定單純的輸出肯定是沒什么作用的,要能顯示到內嵌懸浮視窗,或者是popup頁面上(甚至發送ajax請求到遠程服務器上保存)

對上面代碼微改一下

window.onload = function() {
  console.log('加載完畢');

  function getInfo() {
    let username = $('#v_upinfo > div.up-info_right > div.name > a.username').text().trim()
    let follow = $(`#v_upinfo > div.up-info_right > div.btn-panel > div.default-btn.follow-btn.btn-transition.b-gz.following > span > span > span`).text();
    let title = $(`#viewbox_report > h1 > span`).text();
    let view = $('#viewbox_report > div > span.view').attr('title');

    //console.log(username, follow, title, view);
    window.kz_vm.user = {
      username,
      follow,
      title,
      view,
    };

  }
  getInfo();
};
其中window.kz_vm是通過window.kz_vm = new Vue() 初始化的,方便我們操作vm物件,就需要通過jquery選擇元素在添加屬性了,如果你想的話也可以直接在content-script.js上撰寫代碼,這樣就無需使用window物件,但這樣導致一些業務邏輯都堆在一個檔案里,所以我習慣分成bilibili.js 然后注入方式為document_end,然后在操作dom元素嗎,實作效果如下 如果像顯示到popup頁面只需要通過頁面通信就行了,不過前提得先popup打開才行,所以一般都是通過background來進行中轉,一般來說很少 content –> popup(因為操作popup的前提都是popup要打開),相對更多的是content –> background 或 popup –> content

實作評論

這邊簡單撰寫了一下頁面,通過popup給content,讓content輸入評論內容,與點擊發送,先看效果


bilibili_comment

同樣的,找到對應元素位置

// 評論文本框
$('#comment > div > div.comment > div > div.comment-send > div.textarea-container > textarea').val("要回復的內容");
// 評論按鈕
$('#comment > div > div.comment > div > div.comment-send > div.textarea-container > button').click();

接著就是寫頁面通信的了,可以看到是popup向content發送請求

window.onload = function() {
  console.log('content加載完畢');

  function comment() {
    chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
      let { cmd, message } = request;
      if (cmd === 'addComment') {
        $('#comment > div > div.comment > div > div.comment-send > div.textarea-container > textarea').val(message);
        $('#comment > div > div.comment > div > div.comment-send > div.textarea-container > button').click();
      }
  
      sendResponse('我收到了你的訊息!');
    });
  }
  
  comment();
};

 

<template>
  <div>
    <el-container>
      <el-header height="24">B站小工具</el-header>
      <el-main>
        <el-row :gutter="5">
          <el-input
            type="textarea"
            :rows="2"
            placeholder="請輸入內容"
            v-model="message"
            
          >
          </el-input>

          <div>
            <el-button @click="addComment">評論</el-button>
          </div>
        </el-row>
      </el-main>
    </el-container>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      message: '',
      list: [],
      open: false,
    }
  },
  created() {
    chrome.storage.sync.get('list', (obj) => {
      this.list = obj['list']
    })
  },
  mounted() {
    chrome.runtime.onMessage.addListener(function (
      request,
      sender,
      sendResponse
    ) {
      console.log('收到來自content-script的訊息:')
      console.log(request, sender, sendResponse)
      sendResponse('我是后臺,我已收到你的訊息:' + JSON.stringify(request))
    })
  },
  methods: {
    sendMessageToContentScript(message, callback) {
      chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        chrome.tabs.sendMessage(tabs[0].id, message, function (response) {
          if (callback) callback(response)
        })
      })
    },
    addComment() {
      this.sendMessageToContentScript(
        { cmd: 'addComment', message: this.message },
        function () {
          console.log('來自content的回復:' + response)
        }
      )
    },
  },
}
</script>

代碼就不解讀了,呼叫sendMessageToContentScript方法即可,相關原始碼可自行下載查看

實作類似點贊功能也是同理的,

整體體驗

當時寫Chrome插件的效率不能說慢,反正不快就是了,像一些tips,都得自行封裝,用過Vue的都知道寫網頁很方便,寫Chrome插件未嘗不是撰寫一個網頁,當時的我在接觸了Vue后就萌發了使用vue來撰寫Chrome的想法,當然肯定不止我一個這么想過,所以我在github上就能搜索到相應的原始碼,于是就有了這篇文章,

如果有涉及到爬取資料相關的,我肯定是首選使用HTTP協議,如果在搞不定我會選擇使用puppeteerjs,不過Chrome插件主要還是增強頁面功能的,可以實作原本頁面不具備的功能,

本文僅僅只是初步體驗,簡單撰寫了個小專案,后期有可能會實作一個百度網盤一鍵填寫提取碼,Js自吐Hooke相關的,(原本是打算做pdd商家自動回復的,客戶說要用客戶端而不是網頁端(客戶端可以多號登陸),無奈,這篇博客就拿B站來演示了)

本文轉載于:

https://juejin.cn/post/7009128182007742495

如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/518995.html

標籤:其他

上一篇:手動實作一個Promise

下一篇:使用react+redux實作彈出框案例

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more