Your Name 3 lat temu
rodzic
commit
81e8f75e0b

+ 2
- 1
package.json Wyświetl plik

16
     "js-base64": "^3.7.2",
16
     "js-base64": "^3.7.2",
17
     "nprogress": "^0.2.0",
17
     "nprogress": "^0.2.0",
18
     "vue": "^3.2.25",
18
     "vue": "^3.2.25",
19
-    "vue-router": "4"
19
+    "vue-router": "4",
20
+    "vue-simple-context-menu": "^4.0.4"
20
   },
21
   },
21
   "devDependencies": {
22
   "devDependencies": {
22
     "@vitejs/plugin-vue": "^2.3.3",
23
     "@vitejs/plugin-vue": "^2.3.3",

+ 36
- 43
src/components/ContextMenu.vue Wyświetl plik

1
 <template>
1
 <template>
2
-  <div class="content-menu-box">
3
-    <a-menu @click="handleMenu" v-model:selectedKeys="selectedKeys">
4
-      <a-menu-item key="save">
5
-        新建文件
6
-      </a-menu-item>
7
-      <a-menu-divider />
8
-      <a-menu-item key="newfolder">
9
-        新建文件夹
10
-      </a-menu-item>
11
-    </a-menu>
12
-  </div>
13
-  <a-modal v-model:visible="visible" title="新建" @ok="confirmNew">
2
+  <vue-simple-context-menu
3
+    element-id="my-context-menu"
4
+    :options="contextMenuOptions"
5
+    :ref="el => contextMenuRef = el"
6
+    @option-clicked="optionClicked"
7
+  />
8
+  <a-modal v-model:visible="modelProps.visible" :title="modelProps.title" @ok="confirmNew">
14
     <a-input v-model:value="inputText" placeholder="请输入名称" />
9
     <a-input v-model:value="inputText" placeholder="请输入名称" />
15
   </a-modal>
10
   </a-modal>
16
 </template>
11
 </template>
17
 
12
 
18
 <script setup>
13
 <script setup>
19
-import { computed, ref } from 'vue'
20
-// import { useModel } from '@zjxpcyc/vue-tiny-store'
14
+import { reactive, ref } from 'vue'
21
 import eventBus from '@/utils/eventBus'
15
 import eventBus from '@/utils/eventBus'
22
 
16
 
23
-const visible = ref(false)
17
+const modelProps = reactive({ visible: false, title: undefined })
24
 const inputText = ref()
18
 const inputText = ref()
25
-const menuKey = ref()
26
-const selectedKeys = ref([])
27
-// const { curMenu } = useModel('menu')
28
-// const saveDisabledItem = computed(() => {
29
-//   return !curMenu.value || curMenu.value.type !== 'file'
30
-// })
31
 
19
 
32
-const emit = defineEmits(['menuClick'])
20
+const menuRef = ref()
21
+const contextMenuRef = ref()
22
+const contextMenuOptions = [
23
+  { id: 'newFolder', name: '新建文件夹' },
24
+  { id: 'newFile', name: '新建文件' },
25
+]
26
+const optionRef = ref()
33
 
27
 
34
-const confirmNew = () => {
35
-  const inputValue = inputText.value
28
+const emit = defineEmits(['newFile', 'newFolder'])
36
 
29
 
37
-  switch (menuKey.value) {
38
-    case 'save':
39
-      eventBus.dispatchEvent('menu.newFile', inputValue)
40
-      break;
41
-    case 'newfolder':
42
-      eventBus.dispatchEvent('menu.newFolder', inputValue)
43
-      break;
44
-    default:
45
-      break;
46
-  }
47
-  visible.value = false
48
-  inputText.value = undefined
30
+const onContextMenu = ({ event, menu }) => {
31
+  contextMenuRef.value.showMenu(event)
32
+  menuRef.value = menu
49
 }
33
 }
50
 
34
 
51
-const handleMenu = (e) => {
52
-  menuKey.value = e.key
53
-  visible.value = true
54
-  // 主要是为了清除样式, 但是暂时不起作用, 不知道为啥
55
-  selectedKeys.value = []
56
-  emit('menuClick')
35
+const optionClicked = (event) => {
36
+  modelProps.visible = true
37
+  modelProps.title = event.option.name
38
+  optionRef.value = event.option
57
 }
39
 }
58
 
40
 
41
+const confirmNew = () => {
42
+  const option = optionRef.value
43
+  const data = { menu: menuRef.value, name: inputText.value }
44
+  emit(option.id, data)
45
+  modelProps.visible = false
46
+  inputText.value = undefined
47
+}
48
+
49
+eventBus.addEventListener('menu.contextMenu', onContextMenu)
50
+
59
 </script>
51
 </script>
60
 
52
 
61
 <style lang="less" scoped>
53
 <style lang="less" scoped>
62
-.content-menu-box {
54
+.my-context-menu {
63
   width: 200px;
55
   width: 200px;
56
+  background-color: #fff;
64
 }
57
 }
65
 </style>
58
 </style>

+ 8
- 25
src/components/SubMenu.vue Wyświetl plik

4
       v-if="menu.type === 'dir'"
4
       v-if="menu.type === 'dir'"
5
       :key="`/@@dir@@/${menu.path}`"
5
       :key="`/@@dir@@/${menu.path}`"
6
     >
6
     >
7
-      <template #title>
8
-        <a-tooltip v-model:visible="tipVisible" trigger="no-trigger" placement="bottom" overlayClassName="menu-tooltip">
9
-          <template #title>
10
-            <ContextMenuVue @menuClick="tipVisible = false" />
11
-          </template>
12
-          <div class="dir-context-menu" @contextmenu.stop="handleContextMenu(`/@@dir@@/${menu.path}`)">
13
-            {{menu.name}}
14
-          </div>
15
-        </a-tooltip>
7
+      <template #title>        
8
+        <div class="dir-context-menu" @contextmenu.prevent.stop="event => onContextMenu(event, menu)">
9
+          {{menu.name}}
10
+        </div>
16
       </template>
11
       </template>
17
       <template v-if="menu.children">
12
       <template v-if="menu.children">
18
-        <SubMenu :menus="menu.children" :sub-menu="SubMenu" @contextfolder="handleContextMenu" />
13
+        <SubMenu :menus="menu.children" :sub-menu="SubMenu" />
19
       </template>
14
       </template>
20
     </a-sub-menu>
15
     </a-sub-menu>
21
     <a-menu-item v-else :key="`/@@file@@/${menu.path}`">{{ menu.name }}</a-menu-item>
16
     <a-menu-item v-else :key="`/@@file@@/${menu.path}`">{{ menu.name }}</a-menu-item>
23
 </template>
18
 </template>
24
 
19
 
25
 <script setup>
20
 <script setup>
26
-import { ref } from 'vue'
27
-import ContextMenuVue from './ContextMenu.vue';
28
-
21
+import eventBus from '@/utils/eventBus'
29
 const props = defineProps({
22
 const props = defineProps({
30
   menus: {
23
   menus: {
31
     type: Array,
24
     type: Array,
34
   subMenu: undefined,
27
   subMenu: undefined,
35
 })
28
 })
36
 
29
 
37
-const emit = defineEmits([ 'contextfolder' ])
38
-
39
 const SubMenu = props.subMenu
30
 const SubMenu = props.subMenu
40
 
31
 
41
-const tipVisible = ref(false)
42
-
43
-const handleContextMenu = (key) => {
44
-  tipVisible.value = true
45
-
46
-  if (Array.isArray(key)) {
47
-    emit('contextfolder', key)
48
-  } else {
49
-    emit('contextfolder', [key])
50
-  }
32
+const onContextMenu = (event, menu) => {
33
+  eventBus.dispatchEvent('menu.contextMenu', { event, menu })
51
 }
34
 }
52
 
35
 
53
 </script>
36
 </script>

+ 10
- 22
src/layouts/components/SiderBar.vue Wyświetl plik

10
     >
10
     >
11
       <a-menu-item-group key="g1">
11
       <a-menu-item-group key="g1">
12
         <template #title>
12
         <template #title>
13
-          <a-tooltip trigger="contextmenu" placement="bottom" overlayClassName="menu-tooltip">
14
-            <template #title>
15
-              <ContextMenuVue />
16
-            </template>
17
-            <div>我的日记</div>
18
-          </a-tooltip>
13
+          <div>我的日记</div>
19
         </template>
14
         </template>
20
       </a-menu-item-group>
15
       </a-menu-item-group>
21
-      <SubMenu :menus="fileTree" :sub-menu="SubMenu" @contextfolder="handleOpenChange"></SubMenu>
16
+      <SubMenu :menus="fileTree" :sub-menu="SubMenu"></SubMenu>
22
     </a-menu>
17
     </a-menu>
18
+    <ContextMenu :newFile="createNewFile" :newFolder="createNewFolder" />
23
   </div>
19
   </div>
24
 </template>
20
 </template>
25
 
21
 
26
 <script setup>
22
 <script setup>
23
+import { ref } from 'vue'
27
 import { useModel } from '@zjxpcyc/vue-tiny-store'
24
 import { useModel } from '@zjxpcyc/vue-tiny-store'
28
-import ContextMenuVue from '@/components/ContextMenu.vue';
25
+import ContextMenu from '@/components/ContextMenu.vue';
29
 import SubMenu from '@/components/SubMenu.vue';
26
 import SubMenu from '@/components/SubMenu.vue';
30
 import eventBus from '@/utils/eventBus'
27
 import eventBus from '@/utils/eventBus'
31
 
28
 
36
   }
33
   }
37
 })
34
 })
38
 
35
 
36
+
39
 const { user } = useModel('user')
37
 const { user } = useModel('user')
40
 const { curMenu, menus, getMenus } = useModel('menu')
38
 const { curMenu, menus, getMenus } = useModel('menu')
41
 const { fileArr, fileTree, getNote, getFiles } = useModel('note')
39
 const { fileArr, fileTree, getNote, getFiles } = useModel('note')
51
 const handleMenu = (e) => {
49
 const handleMenu = (e) => {
52
   const menuId = e.key
50
   const menuId = e.key
53
   const path = menuId.replace('/@@file@@/', '')
51
   const path = menuId.replace('/@@file@@/', '')
54
-
55
-  // const note = fileArr.filter(x => x.name === path)[0]
56
-  // curMenu.value = menu
57
-
58
   getNote(user, path)
52
   getNote(user, path)
59
 }
53
 }
60
 
54
 
63
   if (!menuId) return;
57
   if (!menuId) return;
64
 
58
 
65
   const path = menuId.replace('/@@dir@@/', '')
59
   const path = menuId.replace('/@@dir@@/', '')
66
-
67
-  // const menu = getDeep(menus, path, 'dir');
68
-  // curMenu.value = menu
69
-
70
   getFiles(user, path, repo)
60
   getFiles(user, path, repo)
71
 }
61
 }
72
 
62
 
73
 // 创建新文件
63
 // 创建新文件
74
-const createNewFile = (newFileName) => {
75
-  const parentPath = curMenu.value ? curMenu.value.path : undefined
64
+const createNewFile = (parentMenu, newFileName) => {
65
+  const parentPath = parentMenu.path
76
   const newFilePath = parentPath ? `${parentPath}/${newFileName}.html` : `${newFileName}.html`
66
   const newFilePath = parentPath ? `${parentPath}/${newFileName}.html` : `${newFileName}.html`
77
 
67
 
78
   newFile('又是一篇崭新的日记...', newFilePath, user).then(() => {
68
   newFile('又是一篇崭新的日记...', newFilePath, user).then(() => {
88
 }
78
 }
89
 
79
 
90
 // 创建新目录
80
 // 创建新目录
91
-const createNewFolder = (newFolderName) => {
92
-  const parentPath = curMenu.value ? curMenu.value.path : undefined
81
+const createNewFolder = (parentMenu, newFolderName) => {
82
+  const parentPath = parentMenu.path
93
   const newFilePath = parentPath ? `${parentPath}/${newFolderName}` : newFolderName
83
   const newFilePath = parentPath ? `${parentPath}/${newFolderName}` : newFolderName
94
 
84
 
95
   newFolder(newFilePath, user).then(() => {
85
   newFolder(newFilePath, user).then(() => {
104
   })
94
   })
105
 }
95
 }
106
 
96
 
107
-eventBus.addEventListener('menu.newFile', createNewFile)
108
-eventBus.addEventListener('menu.newFolder', createNewFolder)
109
 </script>
97
 </script>

+ 3
- 0
src/main.js Wyświetl plik

1
 import { createApp } from 'vue'
1
 import { createApp } from 'vue'
2
 import Antd from 'ant-design-vue';
2
 import Antd from 'ant-design-vue';
3
+import VueSimpleContextMenu from 'vue-simple-context-menu';
4
+import 'vue-simple-context-menu/dist/vue-simple-context-menu.css';
3
 import 'ant-design-vue/dist/antd.css';
5
 import 'ant-design-vue/dist/antd.css';
4
 import 'nprogress/nprogress.css'
6
 import 'nprogress/nprogress.css'
5
 import App from './App.vue'
7
 import App from './App.vue'
11
 app.use(store)
13
 app.use(store)
12
 app.use(router)
14
 app.use(router)
13
 app.use(Antd)
15
 app.use(Antd)
16
+app.component('vue-simple-context-menu', VueSimpleContextMenu);
14
 app.mount('#app')
17
 app.mount('#app')

+ 12
- 0
yarn.lock Wyświetl plik

284
   optionalDependencies:
284
   optionalDependencies:
285
     fsevents "~2.3.2"
285
     fsevents "~2.3.2"
286
 
286
 
287
+click-outside-vue3@^4.0.1:
288
+  version "4.0.1"
289
+  resolved "https://registry.yarnpkg.com/click-outside-vue3/-/click-outside-vue3-4.0.1.tgz#81a6ac01696b301764b42db6fdbdf28e7cd8ef95"
290
+  integrity sha512-sbplNecrup5oGqA3o4bo8XmvHRT6q9fvw21Z67aDbTqB9M6LF7CuYLTlLvNtOgKU6W3zst5H5zJuEh4auqA34g==
291
+
287
 combined-stream@^1.0.8:
292
 combined-stream@^1.0.8:
288
   version "1.0.8"
293
   version "1.0.8"
289
   resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
294
   resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
945
   dependencies:
950
   dependencies:
946
     "@vue/devtools-api" "^6.0.0"
951
     "@vue/devtools-api" "^6.0.0"
947
 
952
 
953
+vue-simple-context-menu@^4.0.4:
954
+  version "4.0.4"
955
+  resolved "https://registry.yarnpkg.com/vue-simple-context-menu/-/vue-simple-context-menu-4.0.4.tgz#97aff25ee0ae0f82c0049797fdd60abbc3460b8d"
956
+  integrity sha512-Kn6rTXzKHpdTsPoKpBUQC4K+iZxpYiDU04BbGOgLuX/jLFIA7arzIstOp3+tFoV5JaWrjxGPLAuj2BAf8/G4pQ==
957
+  dependencies:
958
+    click-outside-vue3 "^4.0.1"
959
+
948
 vue-types@^3.0.0:
960
 vue-types@^3.0.0:
949
   version "3.0.2"
961
   version "3.0.2"
950
   resolved "https://registry.yarnpkg.com/vue-types/-/vue-types-3.0.2.tgz#ec16e05d412c038262fc1efa4ceb9647e7fb601d"
962
   resolved "https://registry.yarnpkg.com/vue-types/-/vue-types-3.0.2.tgz#ec16e05d412c038262fc1efa4ceb9647e7fb601d"