前言
使用原生 html 寫 vue 專案。注意:是專案,而不是頁面,此方式是不推薦的,畢竟有腳手架,但在一些及其特殊場景下,可能會需要類似的方式,因此作為一個記錄。
這種方式唯一的優點就是寫完可以直接扔伺服器上了-_-
對 html 寫 vue 的認知
很多人對 在 html 中執行 vue 專案這種內容,認知只停留在引入 vue 的 cdn 檔案,然後在 html 裡一頓寫,就覺得 html 寫 vue 不是很簡單嘛,但請注意用詞,是專案,而不是頁面,你能寫一個 .vue
頁面引入讓 html 去執行嗎?顯然不可以,而此文章就是說這個的。
正常想要在原生 html 中直接寫 .vue
檔案是不現實的,因為 html 壓根就不認識 .vue 檔案,只有腳手架才能識別,那如何才能讓 html 識別 .vue
檔案呢?其實也很簡單,核心就是一個包 vue3-sfc-loader
如何獲取 vue 等 npm 的離線包
- jsdelivr 推薦
- 優點:更新及時,所有 npm 包都可查詢到
- 缺點:自行區分 es 和 umd 包,且部分包依賴檔案需自行查詢
- cdnjs
- 優點:有明確的 es 和 umd 包,專案相關包羅列較為完整,如果 jsdelivr 上無法找到 es 和 umd 包的可以使用此網站
- 缺點:更新並不是最快,很多 npm 包缺失,比如此次的
vue3-sfc-loader
在 cdnjs 上無法搜尋到
- unpkg
- 優點:與以上兩個相比,暫無
- 缺點:需要知道想要下載的檔名,包括區分 es 和 umd
什麼是 es 包和 umd 包
es 包支援 import 匯入的寫法,比如這樣
<script type="module">
import { createApp, ref } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
</script>
而 umd 包是直接執行在瀏覽器的,比如我引入了 vue.global.js
這就是一個 browser 包,我可以在 window 上訪問到 Vue
例項
使用時就是這樣
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
const { createApp, ref } = Vue // window.Vue
</script>
es 包是需要
script
標籤新增type="module"
,匯入方式為import
。
而 umd 包引入之後,會自動掛載到 window 上,匯入方式為解構const {...} = Vue
讓 html 識別 .vue
檔案
需由一個前提條件,由於下載的都是生產檔案,開啟 html 頁面時需要使用 Live Server
外掛開啟,普通開啟方式無法執行
這裡統一用 es 檔案,模仿腳手架結構進行搭建
- 下載
vue
離線 es 檔案: vue.esm-browser.prod.min.js - 下載
vue3-sfc-loader
離線 es 檔案:vue3-sfc-loader.esm.js - 新建
index.html
,並引入下載好的 vue 和 sfc 解析檔案
這種 Import maps
寫法在 vue 官網上有 示例
特性: 其實就是一個路徑對映,此時 import {} from "vue"
等價於 import {} from "./lib/es/vue.esm-browser.prod.min.js"
優點:
- 可以非腳手架專案中可以支援
import {} from "vue"
。 - 如果不使用,就需要
import {} from "./lib/es/vue.esm-browser.prod.min.js"
引入相對或絕對路徑,冗餘且意義不大
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- vue 的掛載節點 -->
<div id="app"></div>
</body>
<script type="importmap">
{
"imports": {
"vue": "./lib/es/vue.esm-browser.prod.min.js",
"vue3-sfc-loader": "./lib/es/vue3-sfc-loader.esm.js",
}
}
</script>
<script type="module" src="./main.js"></script>
</html>
- 新建
main.js
檔案,寫入 sfc 解析 vue 檔案的規則,並掛載 vue 例項,由於 html 的 script 標籤上寫了type="module"
,所以可以在main.js
中使用import
語法
import { loadModule } from "vue3-sfc-loader";
import * as Vue from "vue";
const { defineAsyncComponent, createApp } = Vue;
const options = {
moduleCache: {
vue: Vue,
},
async getFile(url) {
const res = await fetch(url);
if (!res.ok) return;
return {
getContentData: (asBinary) => (asBinary ? res.arrayBuffer() : res.text()),
};
},
addStyle(textContent) {
const style = Object.assign(document.createElement("style"), {
textContent,
});
const ref = document.head.getElementsByTagName("style")[0] || null;
document.head.insertBefore(style, ref);
},
};
// 引入 App.vue 根檔案
const loadComponent = defineAsyncComponent(() =>
loadModule("./pages/App.vue", options)
);
// 掛載 vue
createApp(loadComponent).mount("#app");
addStyle
是為了解析 .vue
檔案中的 style
樣式插入到 header 中。
- 新建
App.vue
檔案,寫入測試內容,然後使用Live Server
開啟 html 檔案
<script setup>
import { ref } from "vue";
const count = ref(0);
</script>
<template>
<h1>123</h1>
<div class="title">count: {{ count }}</div>
<button @click="count++">+1</button>
</template>
<style scoped>
.title {
color: red;
}
</style>
效果如圖所示
使用第三方元件庫
這個需要對元件庫有一定的熟悉程度,瞭解其構成結構,而且需要官方對 es 格式的元件庫檔案有相當完善的支援。
目前測試下來,只有 antd vue
對此方式的支援度最完善,可以在 cdnjs 中搜尋下載。
element plus
arco vue
這些元件庫對 es 的支援度並不是特別好,如果想要使用,只能退而求其次,使用 umd 格式,這種方式就不能 import 匯入,而是從 window 上獲取使用。
- 下載
antd vue
相關的 min.js 和 css 並在index.html
使用 map 對映(官網上還明確標註依賴了 dayjs 的 plugin 外掛)
<link rel="stylesheet" href="./lib/es/antd.reset.min.css" />
<script type="importmap">
{
"imports": {
// ...
"antd": "./lib/es/antd.esm.min.js"
}
}
</script>
- 和
main.js
中註冊元件庫
import * as antd from "antd";
const options = {
moduleCache: {
vue: Vue,
antd: antd, // 元件庫等第三方包不在 use 註冊,在此處註冊,否則 sfc 會將 antd 識別為專案內部的 vue 元件,找不到而報錯
},
// ...
};
- 使用元件庫
<script setup>
import { ref } from "vue";
import { Button } from "antd";
const count = ref(0);
</script>
<template>
<span class="title">count: {{ count }}</span>
<Button @click="count++"> +1 </Button>
</template>
至此,離線方式搭建 vue 專案就此完成。
其實這種方式的缺點還是蠻多的,如果想用的元件庫 es 支援度不夠或有問題,只能選擇 umd 格式使用