Browse Source

添加组件:脱敏输入框;修复生产环境无法预览和下载

gbtomr 1 month ago
parent
commit
e848498774

+ 1 - 1
package-lock.json

@@ -8,6 +8,7 @@
       "name": "zhjg-ui",
       "version": "0.0.0",
       "dependencies": {
+        "@element-plus/icons-vue": "^2.3.1",
         "element-plus": "^2.9.3",
         "highlight.js": "^11.11.1",
         "vue": "^3.5.13",
@@ -91,7 +92,6 @@
       "version": "2.3.1",
       "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz",
       "integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==",
-      "license": "MIT",
       "peerDependencies": {
         "vue": "^3.2.0"
       }

+ 1 - 0
package.json

@@ -9,6 +9,7 @@
     "preview": "vite preview"
   },
   "dependencies": {
+    "@element-plus/icons-vue": "^2.3.1",
     "element-plus": "^2.9.3",
     "highlight.js": "^11.11.1",
     "vue": "^3.5.13",

+ 9 - 0
src/assets/styles/global.scss

@@ -11,4 +11,13 @@
 .title-2 {
   font-size: 18px;
   color: var(--el-text-color-regular);
+}
+
+.tip {
+  font-size: 13px;
+  color: var(--el-text-color-secondary);
+
+  a {
+    color: var(--el-color-primary);
+  }
 }

+ 34 - 17
src/components/CodeArea.vue

@@ -1,9 +1,13 @@
 <template>
   <el-container class="code-container">
     <el-header>
-      <el-button plain type="primary" @click="handlePreview" :loading="loading.preview"
-        :disabled="isPreviewed">预览</el-button>
-      <el-button plain type="primary" @click="handleDownload" :loading="loading.download">下载</el-button>
+      <el-button link type="primary" @click="handlePreview" :loading="loading.preview" v-show="!isPreviewed"><el-icon>
+          <ArrowDown />
+        </el-icon>预览</el-button>
+      <el-button link type="primary" class="btn-download" @click="handleDownload" :loading="loading.download">
+        <el-icon>
+          <Download />
+        </el-icon>下载</el-button>
     </el-header>
     <el-main v-if="isPreviewed" v-loading="loading.preview">
       <pre class="pre">
@@ -14,9 +18,9 @@
 </template>
 
 <script setup>
-import { ref, defineProps, reactive, nextTick, computed } from 'vue'
 import hljs from 'highlight.js';
 import 'highlight.js/styles/default.css';
+import { ArrowDown, Download } from '@element-plus/icons-vue'
 
 const props = defineProps({
   src: {
@@ -25,10 +29,6 @@ const props = defineProps({
   }
 })
 
-const filePath = computed(() => {
-  return new URL(props.src + '?raw', import.meta.url).href
-})
-
 const isPreviewed = ref(false)
 
 const codeBlock = ref(null)
@@ -42,8 +42,9 @@ function handlePreview() {
   loading.preview = true
   isPreviewed.value = true
   nextTick(() => {
-    import(filePath.value).then(fileRaw => {
-      codeBlock.value.textContent = fileRaw.default
+    fetch(props.src).then(async (response) => {
+      const fileContent = await response.text();
+      codeBlock.value.textContent = fileContent
       hljs.highlightElement(codeBlock.value)
       loading.preview = false
     }).catch(() => {
@@ -56,9 +57,10 @@ function handlePreview() {
 
 function handleDownload() {
   loading.download = true
-  const fileName = props.src.slice(props.src.lastIndexOf('/') + 1)
-  import(filePath.value).then(fileRaw => {
-    const blob = new Blob([fileRaw.default], { type: 'text/plain' })
+  let fileName = props.src.slice(props.src.lastIndexOf('/') + 1, -4)
+  fetch(props.src).then(async (response) => {
+    const fileContent = await response.text();
+    const blob = new Blob([fileContent], { type: 'text/plain' })
     const url = URL.createObjectURL(blob);
     const link = document.createElement('a');
     link.href = url;
@@ -69,8 +71,9 @@ function handleDownload() {
     document.body.removeChild(link);
     loading.download = false
   }).catch(() => {
-    ElMessage.error('下载失败')
-    loading.download = false
+    ElMessage.error('获取失败')
+    loading.preview = false
+    isPreviewed.value = false
   })
 }
 
@@ -82,9 +85,23 @@ function handleDownload() {
   border-radius: 5px;
 
   .el-header {
-    display: flex;
-    align-items: center;
+    position: relative;
+    height: 50px;
+    text-align: center;
     border-bottom: 1px solid var(--el-border-color);
+
+    .el-button {
+      height: 100%;
+    }
+
+    .el-icon {
+      margin-right: 5px;
+    }
+
+    .btn-download {
+      position: absolute;
+      right: 20px;
+    }
   }
 
   .el-main {

+ 1 - 1
src/data/component-list.js

@@ -10,7 +10,7 @@ const components = [
     id: 'element-based',
     title: 'element组件',
     children: [
-
+      { id: 'e-1', title: '脱敏输入框', fileName: 'InputDesen' }
     ]
   }
 ]

+ 0 - 1
src/layouts/cpns/NavBar.vue

@@ -10,7 +10,6 @@
 </template>
 
 <script setup>
-import { ref } from 'vue'
 
 const activeIndex = ref('1')
 

File diff suppressed because it is too large
+ 80 - 0
src/views/components/com-file/InputDesen.vue


+ 0 - 1
src/views/components/cpns/ConfigTable.vue

@@ -13,7 +13,6 @@
 </template>
 
 <script setup>
-import { defineProps } from 'vue'
 import CodeText from '@/components/CodeText.vue'
 
 const props = defineProps({

+ 3 - 2
src/views/components/pages/ImageList.vue

@@ -10,12 +10,11 @@
     <ConfigTable :data="tableData" />
 
     <h5 class="title-2">组件代码</h5>
-    <CodeArea src="/src/views/components/com-file/ImageList.vue" />
+    <CodeArea :src="fileSrc" />
   </div>
 </template>
 
 <script setup>
-import { ref } from 'vue'
 import ImageList from '../com-file/ImageList.vue'
 import { useRoute } from 'vue-router'
 import ConfigTable from '../cpns/ConfigTable.vue'
@@ -23,6 +22,8 @@ import CodeArea from '@/components/CodeArea.vue'
 
 const route = useRoute()
 
+const fileSrc = ref(new URL('/src/views/components/com-file/ImageList.vue?raw', import.meta.url).href)
+
 const tableData = ref([
   { prop: 'limit', des: '可选图片最大个数', type: 'number', default: '100' },
   { prop: 'disabled', des: '是否禁用(仅查看)', type: 'boolean', default: 'false' },

+ 45 - 0
src/views/components/pages/InputDesen.vue

@@ -0,0 +1,45 @@
+<template>
+  <div>
+    <h4 class="title-1">{{ route.meta.name }}</h4>
+    <p class="des">用于敏感信息输入框的脱敏</p>
+
+    <h5 class="title-2">组件展示</h5>
+    <el-row :gutter="20">
+      <el-col :span="4">
+        <InputDesen v-model="inputVal" />
+      </el-col>
+      <el-col :span="4">
+        <InputDesen v-model="displayVal" disabled />
+      </el-col>
+    </el-row>
+
+    <h5 class="title-2">参数和配置</h5>
+    <ConfigTable :data="tableData" />
+    <p class="tip">
+      其它属性参考
+      <a href="https://element-plus.org/zh-CN/component/input.html#attributes" target="_blank">ElInput 组件配置</a>
+    </p>
+
+    <h5 class="title-2">组件代码</h5>
+    <CodeArea :src="fileSrc" />
+  </div>
+</template>
+
+<script setup>
+import InputDesen from '../com-file/InputDesen.vue'
+import { useRoute } from 'vue-router'
+import ConfigTable from '../cpns/ConfigTable.vue'
+import CodeArea from '@/components/CodeArea.vue'
+
+const fileSrc = ref(new URL('/src/views/components/com-file/InputDesen.vue?raw', import.meta.url).href)
+
+const inputVal = ref('18988889999')
+
+const displayVal = ref('17677776666')
+
+const route = useRoute()
+
+const tableData = ref([
+  { prop: 'modelValue', des: '输入框绑定值', type: 'string', default: '""' },
+])
+</script>

+ 2 - 0
vite.config.js

@@ -7,9 +7,11 @@ import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
 
 // https://vite.dev/config/
 export default defineConfig({
+  base: '/',
   plugins: [
     vue(),
     AutoImport({
+      imports: ['vue'],
       resolvers: [ElementPlusResolver()],
     }),
     Components({