修改Nav渲染方式,使支持数据绑定

This commit is contained in:
洛洛希雅Lolosia 2023-08-21 14:35:50 +08:00
parent 96557fb255
commit 6ff36a9436
3 changed files with 110 additions and 30 deletions

View File

@ -1,25 +1,24 @@
<template>
<div class="app-page">
<slot/>
<slot v-if="false" name="left"/>
<slot v-if="false" name="center"/>
<slot v-if="false" name="right"/>
<slot />
<slot v-if="false" name="left" />
<slot v-if="false" name="center" />
<slot v-if="false" name="right" />
</div>
</template>
<script lang="ts">
import type { VNode } from 'vue'
import { useBasicStore } from '@/store/basic'
import { v4 } from "uuid";
import { v4 } from 'uuid'
export default defineComponent({
name: 'AppPage',
data() {
return {
left: [] as VNode[],
right: [] as VNode[],
center: [] as VNode[],
default: [] as VNode[],
left: () => [] as VNode[],
right: () => [] as VNode[],
center: () => [] as VNode[],
default: () => [] as VNode[],
id: v4()
}
},
@ -36,30 +35,30 @@ export default defineComponent({
this.onHide()
},
created() {
const { left, right, center, default: d } = this.$slots;
this.left = left?.() ?? [];
this.right = right?.() ?? [];
this.center = center?.() ?? [];
this.default = d?.() ?? [];
const noop = () => []
const { left, right, center, default: d } = this.$slots
this.left = left ?? noop
this.right = right ?? noop
this.center = center ?? noop
this.default = d ?? noop
},
methods: {
onShowing() {
useBasicStore().$patch(({ navbar }) => {
navbar.left.set(this.id, this.left);
navbar.right.set(this.id, this.right);
navbar.center.set(this.id, this.center);
navbar.cursor++;
});
navbar.left.set(this.id, this.left)
navbar.right.set(this.id, this.right)
navbar.center.set(this.id, this.center)
navbar.cursor++
})
},
onHide() {
useBasicStore().$patch(({ navbar }) => {
navbar.left.delete(this.id);
navbar.right.delete(this.id);
navbar.center.delete(this.id);
navbar.cursor++;
});
navbar.left.delete(this.id)
navbar.right.delete(this.id)
navbar.center.delete(this.id)
navbar.cursor++
})
}
}
},
})
</script>

View File

@ -0,0 +1,81 @@
import { useBasicStore } from '@/store/basic'
import {Comment} from "@vue/runtime-core";
import { v4 } from 'uuid'
import type {Prop, VNode} from 'vue'
import {defineComponent} from 'vue'
export default defineComponent({
name: 'NavContainer',
props: {
align: {
type: String,
required: false,
default: 'left'
} as Prop<'left' | 'center' | 'right' | undefined>
},
data() {
return {
left: () => [] as VNode[],
right: () => [] as VNode[],
center: () => [] as VNode[],
default: () => [] as VNode[],
id: v4(),
show: false
}
},
watch: {
align(value: 'left' | 'center' | 'right' = 'left', old: string) {
if (!this.show || value === old) return;
const noop = () => [];
this.left = this.right = this.center = noop;
this[value] = this.$slots['default'] ?? noop;
useBasicStore().$patch(({ navbar }) => {
navbar.left.set(this.id, this.left)
navbar.right.set(this.id, this.right)
navbar.center.set(this.id, this.center)
navbar.cursor++
})
}
},
mounted() {
this[this.align!] = this.$slots['default'] ?? (() => []);
this.onShowing()
},
activated() {
this.onShowing()
},
beforeUnmount() {
this.onHide()
},
deactivated() {
this.onHide()
},
created() {
const noop = () => []
const { default: d } = this.$slots
this.default = d ?? noop
},
methods: {
onShowing() {
this.show = true
useBasicStore().$patch(({ navbar }) => {
navbar.left.set(this.id, this.left)
navbar.right.set(this.id, this.right)
navbar.center.set(this.id, this.center)
navbar.cursor++
})
},
onHide() {
this.show = false
useBasicStore().$patch(({ navbar }) => {
navbar.left.delete(this.id)
navbar.right.delete(this.id)
navbar.center.delete(this.id)
navbar.cursor++
})
}
},
render(){
return h(Comment, "nav container");
}
})

View File

@ -36,9 +36,9 @@ export const useBasicStore = defineStore('basic', {
settings: defaultSettings,
navbar: {
cursor: 0,
left: new Map<string, VNode[]>(),
right: new Map<string, VNode[]>(),
center: new Map<string, VNode[]>()
left: new Map<string, () => VNode[]>(),
right: new Map<string, () => VNode[]>(),
center: new Map<string, () => VNode[]>()
}
}
},