使用Vue.js編寫命令列介面,前端開發CLI的利器
前言
大家好,我是webfansplz.繼 將 Vue 渲染到嵌入式液晶屏 後,今天要跟大家分享的是如何將Vue渲染到命令列工具 :).關於命令列工具,大家應該都比較熟悉了,比如vue-cli、Vite等.我們在編寫前端應用面向使用者時,通常會非常關注使用者體驗,作為開發者,我們在使用工具時,它給予我們的開發者體驗(DX)我們也會十分關注. 現代前端工程化離不開CLI的開發與使用、那麼是否能有較低成本的方案能讓前端小夥伴快速開發CLI,大家可以像編寫前端應用一樣搞定它.因此,Temir應運而生.
Temir
介紹
Temir,一個用Vue元件來編寫命令列介面應用的工具.開發者只需要使用Vue就可以編寫命令列應用,不需要任何額外的學習成本.
<script lang="ts" setup> import { ref } from '@vue/runtime-core' import { TBox, TText } from '@temir/core' const counter = ref(0) setInterval(() => { counter.value++ }, 100) </script> <template> <TBox> <TText color="green"> {{ counter }} tests passed </TText> </TBox> </template>
元件
Temir提供了一些基礎元件幫助開發者編寫與擴充套件命令列工具:
文字元件 (Text)
文字元件可以顯示文字,將其樣式更改為粗體、下劃線、斜體或刪除線.
<TText color="green"> I am green </TText> <TText color="black" background-color="white"> I am black on white </TText> <TText color="white"> I am white </TText> <TText :bold="true"> I am bold </TText> <TText :italic="true"> I am italic </TText> <TText :underline="true"> I am underline </TText> <TText :strikethrough="true"> I am strikethrough </TText> <TText :inverse="true"> I am inversed </TText>
盒子元件 (Box)
<Box>
是構建佈局必不可少的Temir元件.就像在瀏覽器中 <div style='display: flex'>.
它提供了一些構建佈局的常用屬性,比如尺寸、內外邊距、對齊方式等.
<template> <TBox justify-content="flex-start"> <TText>X</TText> </TBox> // [X ] <TBox justify-content="center"> <TText>X</TText> </TBox> // [ X ] <TBox justify-content="flex-end"> <TText>X</TText> </TBox> // [ X] <TBox justify-content="space-between"> <TText>X</TText> <TText>Y</TText> </TBox> // [X Y] <TBox justify-content="space-around"> <TText>X</TText> <TText>Y</TText> </TBox> // [ X Y ] </template>
換行元件 (Newline)
新增一個或多個換行符(\n)。 必須在 <Text>
元件中使用。
<script> import { TBox, TNewline, TText } from '@temir/core' </script> <template> <TBox> <TText> <TText color="green"> Hello </TText> <TNewline /> <TText color="red"> World </TText> </TText> </TBox> </template>
填充元件 (Spacer)
沿其包含佈局的主軸展開的靈活空間。 作為填充元素之間所有可用空間的快捷方式,它非常有用。
例如,在具有預設伸縮方向( row
)的 <Box>
中使用 <Spacer>
將把"Left"定位到左邊,並將"Right"推到右邊。
<script lang="ts" setup> import { TBox, TSpacer, TText } from '@temir/core' </script> <template> <TBox> <TText>Left</TText> <TSpacer /> <TText>Right</TText> </TBox> </template>
超連結元件 (Link)
<script lang="ts" setup> import { TBox, TText } from '@temir/core' import TLink from '@temir/link' </script> <template> <TBox :margin="5" width="20" border-style="round" justify-content="center" > <TLink url="http://github.com"> <TText color="yellow"> Hi </TText> <TText color="cyan"> Github </TText> </TLink> </TBox> </template>
載入中元件 (Spinner)
<script lang="ts" setup> import { TBox, TText } from '@temir/core' import TSpinner from '@temir/spinner' </script> <template> <TBox :margin="5" width="20" border-style="round" justify-content="center" > <TText> <TText color="yellow"> <TSpinner /> </TText> Loading </TText> </TBox> </template>
標籤頁元件 (Tab)
<script lang="ts" setup> import { computed, ref } from '@vue/runtime-core' import { TBox, TText } from '@temir/core' import { TTab, TTabs } from '@temir/tab' const tabs = ['Vue', 'React', 'Angular', 'Solid', 'Svelte'] const activeIndex = ref(0) const selectedText = computed(() => tabs[activeIndex.value]) </script> <template> <TBox> <TText> Selected Text : <TText color="red"> {{ selectedText }} </TText> </TText> </TBox> <TBox> <TTabs :on-change="(index) => activeIndex = +index"> <TTab v-for="item in tabs" :key="item"> {{ item }} </TTab> </TTabs> </TBox> </template>
選擇元件
<script lang="ts" setup> import TSelectInput from '@temir/select-input' const items = [ { label: 'Vue', value: 'Vue', }, { label: 'Vite', value: 'Vite', }, { label: 'Temir', value: 'Temir', }, ] function onSelect(value) { console.log('selected', value) } </script> <template> <TSelectInput :items="items" :on-select="onSelect" /> </template>
安裝
npm install @temir/core
使用
<script lang="ts" setup> import { ref } from '@vue/runtime-core' import { TBox, TText } from '@temir/core' const counter = ref(0) setInterval(() => { counter.value++ }, 100) </script> <template> <TBox> <TText color="green"> {{ counter }} tests passed </TText> </TBox> </template>
HMR支援
前面我們提到了開發者體驗(DX),在現在的前端工程中,對開發者很有幫助且提效的就是HMR,這麼香的東西Temir沒有理由不擁有它,話不多說,直接展示:
開箱即用
使用Temir定製化CLI非常簡單,我們提供了@temir/cli幫助你快速構建一個基於Temir的CLI.
mkdir my-temir-cli cd my-temir-cli touch main.ts npm install @temir/cl # Dev (開發) temir main.ts # Build (打包) temir build main.ts
你可以通過下載這個例子 來快速開始,你也可以開啟repl.it sandbox來線上體驗和嘗試它。
演示
Hi Temir
Borders
Table
Vitest
實現
- createRenderer
Temir的實現主要得益於Vue3出色的跨平臺能力,我們可以通過createRenderer API建立一個自定義渲染器,通過建立宿主環境中對應的Node和Element,並對元素進行增刪改查操作.
- Yoga
Vue提供了跑在命令列介面的介面,那我們就還缺少一個佈局引擎就能把Vue
跑在命令列工具了.Temir使用了Yoga,一款Flexbox佈局引擎.使用你在構建瀏覽器應用時使用過的類似CSS的屬性,為你的CLI構建出色的使用者介面。
致謝
- 這個專案的靈感來源於ink
- vite-node為實現HMR提供了強力的支援
結語
文章到這裡就結束了,如果我的文章和專案對你有所啟發和幫助,請給一個star支援作者 ✌
- 即刻報名!SegmentFault AIGC Hackathon 黑客馬拉松全新出發!
- SegmentFault 2022 年社群週報 Vol.9
- 社群精選 | 不容錯過的9個冷門css屬性
- 2022最新版 Redis大廠面試題總結(附答案)
- 手寫一個mini版本的React狀態管理工具
- 【vue3原始碼】十三、認識Block
- 天翼雲全場景業務無縫替換至國產原生作業系統CTyunOS!
- JavaScript 設計模式 —— 代理模式
- MobTech簡訊驗證ApiCloud端SDK
- 以羊了個羊為例,淺談小程式抓包與響應報文修改
- 這幾種常見的 JVM 調優場景,你知道嗎?
- 聊聊如何利用管道模式來進行業務編排(下篇)
- 通用ORM的設計與實現
- 如此狂妄,自稱高效能佇列的Disruptor有啥來頭?
- 為什麼要學習GoF設計模式?
- 827. 最大人工島 : 簡單「並查集 列舉」運用題
- 介紹 Preact Signals
- 手把手教你如何使用 Timestream 實現物聯網時序資料儲存和分析
- 850. 矩形面積 II : 掃描線模板題
- Java 併發程式設計解析 | 基於JDK原始碼解析Java領域中的併發鎖,我們可以從中學習到什麼內容?