This commit is contained in:
yll 2025-06-29 21:16:02 +08:00
commit 9a92705f4b
5 changed files with 214 additions and 11 deletions

View File

@ -14,7 +14,7 @@
"dependencies": { "dependencies": {
"@ant-design/icons-vue": "^7.0.1", "@ant-design/icons-vue": "^7.0.1",
"ant-design-vue": "^4.2.5", "ant-design-vue": "^4.2.5",
"js-cookie": "^3.0.5", "lodash-es": "^4.17.21",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"vue": "^3.4.29", "vue": "^3.4.29",
"vue-router": "^4.3.3" "vue-router": "^4.3.3"
@ -25,8 +25,10 @@
"@vue/eslint-config-prettier": "^9.0.0", "@vue/eslint-config-prettier": "^9.0.0",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-plugin-vue": "^9.23.0", "eslint-plugin-vue": "^9.23.0",
"js-cookie": "^3.0.5",
"marked": "^15.0.12",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"vite": "5.4.6", "vite": "6.3.4",
"vite-plugin-vue-devtools": "^7.3.1" "vite-plugin-vue-devtools": "^7.3.1"
} }
} }

View File

@ -0,0 +1,52 @@
<script setup>
import { marked } from 'marked'
import { debounce } from 'lodash-es'
import { ref, computed } from 'vue'
const input = ref('# hello')
const output = computed(() => marked(input.value))
const update = debounce((e) => {
input.value = e.target.value
}, 100)
</script>
<template>
<div class="editor">
<textarea class="input" :value="input" @input="update"></textarea>
<div class="output" v-html="output"></div>
</div>
</template>
<style scoped>
.editor {
height: 100vh;
display: flex;
border: 1px solid #ccc;
}
.input,
.output {
overflow: auto;
width: 50%;
height: 100%;
box-sizing: border-box;
padding: 0 20px;
}
.input {
border: none;
border-right: 1px solid #ccc;
resize: none;
outline: none;
background-color: #f6f6f6;
font-size: 14px;
font-family: 'Monaco', courier, monospace;
padding: 20px;
}
code {
color: #f66;
}
</style>

View File

@ -0,0 +1,76 @@
<script setup>
defineProps({
show: Boolean
})
</script>
<template>
<Transition name="modal">
<div v-if="show" class="modal-mask">
<div class="modal-container">
<div class="modal-header">
<slot name="header">default</slot>
</div>
<div class="modal-body">
<slot name="body">default</slot>
</div>
<div class="modal-footer">
<slot name="footer">
default
<button class="modal-default-button" @click="$emit('close')">click</button>
</slot>
</div>
</div>
</div>
</Transition>
</template>
<style scoped>
.modal-mask {
position: fixed;
z-index: 9998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
transition: opacity 0.3s ease;
}
.modal-container {
width: 300px;
margin: auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 0 8px 0 rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
}
.modal-body {
margin-top: 0;
color: rgba(0, 0, 0, 0.5);
}
.modal-default-button {
float: right;
}
.modal-enter-from {
opacity: 0;
}
.modal-leave-to {
opacity: 1;
}
.modal-enter-from .modal-container,
.modal-leave-to .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
</style>

View File

@ -0,0 +1,46 @@
<script setup>
import { ref, computed } from 'vue'
const props = defineProps({
module: Object
})
const isFolder = computed(() => {
return props.module.children && props.module.children.length > 0
})
function toggle() {
isOpen.value = !isOpen.value
}
function changeType() {
if (!isFolder.value) {
isOpen.value = true
}
}
const emit = defineEmits(['add-child'])
function addChild() {
emit('add-child', props.module)
}
const isOpen = ref(false)
</script>
<template>
<li>
<div class="tree-item" @click="toggle" @dblclick="changeType">
{{ module.name }}<span v-if="isFolder">[{{ isOpen ? '-' : '+' }}]</span>
<CustomTreeItem
v-for="child in module.children"
:key="child.id"
:module="child"
@add-child="$emit('add-child', $event)"
></CustomTreeItem>
<li class="add" @click="addChild">+</li>
</div>
</li>
</template>
<style scoped></style>

View File

@ -5,6 +5,9 @@ import BlogPost from '@/components/BlogPost.vue'
import AlertBox from '@/components/AlertBox.vue' import AlertBox from '@/components/AlertBox.vue'
import HomeView from './HomeView.vue' import HomeView from './HomeView.vue'
import GameView from './GameView.vue' import GameView from './GameView.vue'
import CustomMarkDown from '@/components/CustomMarkDown.vue'
import CustomModal from '@/components/CustomModal.vue'
import CustomTreeItem from '@/components/CustomTreeItem.vue'
const posts = ref([ const posts = ref([
{ id: 1, title: 'test01' }, { id: 1, title: 'test01' },
@ -21,6 +24,15 @@ const tabs = {
GameView GameView
} }
const showModal = ref(false)
const modle = ref({
name: 'Root',
children: [
{ name: 'Child 1', children: [] },
{ name: 'Child 2', children: [{ name: 'Grandchild 1', children: [] }] }
]
})
</script> </script>
<template> <template>
@ -37,21 +49,36 @@ const tabs = {
></BlogPost> ></BlogPost>
</div> </div>
<AlertBox> <AlertBox> test </AlertBox>
test
</AlertBox>
<div class="demo"> <div class="demo">
<button <button v-for="(_, tab) in tabs" :key="tab" @click="currentTab = tab">
v-for="(_, tab) in tabs" {{ tab }}
:key="tab"
@click="currentTab = tab">
{{ tab }}
</button> </button>
<KeepAlive> <KeepAlive>
<component :is="tabs[currentTab]" /> <component :is="tabs[currentTab]" />
</KeepAlive> </KeepAlive>
</div> </div>
<div class="editor">
<CustomMarkDown />
</div>
<button id="show-modal" @click="showModal = true">Show Modal</button>
<Teleport to="body">
<CustomModal :show="showModal" @close="showModal = false">
<template #header>
<h3 style="color: #42b983">Custom Header</h3>
</template>
</CustomModal>
</Teleport>
<CustomTreeItem :module="modle" />
</template> </template>
<style scoped></style> <style scoped>
.editor {
width: 100%;
}
</style>