Files
test-repo/docs/.vitepress/theme/components/appendix/computer-fundamentals/EncodingDemo.vue
T
2026-02-24 00:18:09 +08:00

283 lines
6.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="encoding-demo">
<div class="demo-header">
<span class="title">数字编码 0 1 表示一切</span>
<span class="subtitle">字符数字图像如何变成二进制</span>
</div>
<div class="demo-content">
<div class="encoding-tabs">
<button
v-for="tab in tabs"
:key="tab.name"
:class="['tab-btn', { active: activeTab === tab.name }]"
@click="activeTab = tab.name"
>
{{ tab.label }}
</button>
</div>
<div class="encoding-area">
<div class="input-section">
<label>输入内容</label>
<input
v-model="inputValue"
class="input-field"
:placeholder="currentTab.placeholder"
/>
</div>
<div class="output-section">
<div class="output-label">编码结果</div>
<div class="output-box">
<code>{{ encodedResult }}</code>
</div>
<div v-if="currentTab.name === 'text'" class="output-info">
<span>字符数: {{ inputValue.length }}</span>
<span>字节数: {{ byteCount }}</span>
</div>
</div>
<div
v-if="currentTab.name === 'text' && inputValue"
class="encoding-table"
>
<div class="table-title">字符编码详情</div>
<div class="char-list">
<div
v-for="(char, i) in inputValue.slice(0, 10)"
:key="i"
class="char-item"
>
<span class="char-display">{{ char }}</span>
<span class="char-unicode">U+{{
char.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0')
}}</span>
<span class="char-binary">{{
char.charCodeAt(0).toString(2).padStart(8, '0')
}}</span>
</div>
</div>
</div>
</div>
</div>
<div class="info-box">
<strong>核心思想</strong>所有数据最终都要变成 0
1不同类型的数据用不同的编码规则字符用
ASCII/Unicode数字用二进制图像用像素值
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const activeTab = ref('text')
const inputValue = ref('Hello')
const tabs = [
{ name: 'text', label: '文本编码' },
{ name: 'number', label: '数字编码' },
{ name: 'color', label: '颜色编码' }
]
const currentTab = computed(() => {
const tab = tabs.find((t) => t.name === activeTab.value)
return {
...tab,
placeholder:
tab.name === 'text'
? '输入文字...'
: tab.name === 'number'
? '输入数字...'
: '输入颜色值(如 #FF5733)'
}
})
const encodedResult = computed(() => {
if (!inputValue.value) return ''
switch (activeTab.value) {
case 'text':
return Array.from(inputValue.value)
.map((c) => c.charCodeAt(0).toString(2).padStart(8, '0'))
.join(' ')
case 'number':
const num = parseInt(inputValue.value)
if (isNaN(num)) return '请输入有效数字'
return num.toString(2)
case 'color':
const hex = inputValue.value.replace('#', '')
if (!/^[0-9A-Fa-f]{6}$/.test(hex)) return '请输入有效的颜色值(如 #FF5733)'
const r = parseInt(hex.slice(0, 2), 16)
const g = parseInt(hex.slice(2, 4), 16)
const b = parseInt(hex.slice(4, 6), 16)
return `R: ${r.toString(2).padStart(8, '0')} G: ${g.toString(2).padStart(8, '0')} B: ${b.toString(2).padStart(8, '0')}`
default:
return ''
}
})
const byteCount = computed(() => {
return new Blob([inputValue.value]).size
})
</script>
<style scoped>
.encoding-demo {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
background: var(--vp-c-bg-soft);
padding: 1rem;
margin: 1rem 0;
}
.demo-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.75rem;
}
.demo-header .title {
font-weight: bold;
font-size: 1rem;
}
.demo-header .subtitle {
color: var(--vp-c-text-2);
font-size: 0.85rem;
margin-left: 0.5rem;
}
.encoding-tabs {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
}
.tab-btn {
padding: 0.4rem 0.8rem;
border: 1px solid var(--vp-c-divider);
background: var(--vp-c-bg);
border-radius: 4px;
cursor: pointer;
font-size: 0.85rem;
}
.tab-btn.active {
background: var(--vp-c-brand);
color: white;
border-color: var(--vp-c-brand);
}
.encoding-area {
display: flex;
flex-direction: column;
gap: 1rem;
}
.input-section {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.input-section label {
font-size: 0.85rem;
font-weight: bold;
}
.input-field {
padding: 0.5rem;
border: 1px solid var(--vp-c-divider);
border-radius: 4px;
background: var(--vp-c-bg);
font-size: 1rem;
}
.output-section {
background: var(--vp-c-bg);
padding: 0.75rem;
border-radius: 6px;
}
.output-label {
font-size: 0.85rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
.output-box {
background: var(--vp-c-bg-alt);
padding: 0.5rem;
border-radius: 4px;
font-family: monospace;
font-size: 0.85rem;
word-break: break-all;
}
.output-info {
display: flex;
gap: 1rem;
margin-top: 0.5rem;
font-size: 0.8rem;
color: var(--vp-c-text-2);
}
.encoding-table {
background: var(--vp-c-bg-alt);
padding: 0.75rem;
border-radius: 6px;
}
.table-title {
font-size: 0.85rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
.char-list {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.char-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 0.5rem;
background: var(--vp-c-bg);
border-radius: 4px;
min-width: 80px;
}
.char-display {
font-size: 1.2rem;
font-weight: bold;
}
.char-unicode {
font-size: 0.7rem;
color: var(--vp-c-brand);
}
.char-binary {
font-size: 0.65rem;
font-family: monospace;
color: var(--vp-c-text-2);
}
.info-box {
background: var(--vp-c-bg-alt);
padding: 0.75rem;
border-radius: 6px;
font-size: 0.85rem;
color: var(--vp-c-text-2);
margin-top: 0.75rem;
display: flex;
gap: 0.25rem;
}
</style>