产品组样式联动,文字引用联动

main
一杯沧海 12 months ago
parent a635eead2a
commit 7666f0a378
  1. 103
      src/App.vue
  2. 20
      src/engineer/components/ConfigCurrentView.vue
  3. 36
      src/engineer/context.ts
  4. 18
      src/engineer/styles/NumberStyle.vue
  5. 3
      src/engineer/types.ts
  6. 3
      src/engineer/views/RenderTemplate.vue
  7. 1
      src/engineer/views/TextView.vue

@ -132,7 +132,8 @@ const categories = ref([{ icon: 'trash', text: '媒体' }, { icon: 'trash', text
categories.value.unshift({ categories.value.unshift({
icon: 'trash', icon: 'trash',
text: '基础', text: '基础',
modules: [{ modules: [
{
vid: hash(`${++nextId}`), vid: hash(`${++nextId}`),
mid: hash(`${++nextId}`), mid: hash(`${++nextId}`),
title: '轮播图', title: '轮播图',
@ -285,7 +286,8 @@ categories.value.unshift({
}, },
color: 'cyan', color: 'cyan',
}, },
children: [{ children: [
{
vid: hash(`${++nextId}`), vid: hash(`${++nextId}`),
theme: { theme: {
width: '100%', width: '100%',
@ -295,7 +297,8 @@ categories.value.unshift({
textAlign: 'center', textAlign: 'center',
}, },
children: '设置轮播图', children: '设置轮播图',
}, { },
{
theme: { theme: {
position: 'absolute', position: 'absolute',
flexible: true, flexible: true,
@ -306,18 +309,6 @@ categories.value.unshift({
height: 20, height: 20,
color: 'red', color: 'red',
}, },
// children: {
// type: 'each',
// key: 'indicator.position',
// handle: {
// theme: {
// width: 20,
// height: 20,
// radius: 10,
// color: 'black',
// }
// },
// }
children: { children: {
type: 'template', type: 'template',
key: 'indicator.style' key: 'indicator.style'
@ -325,9 +316,9 @@ categories.value.unshift({
}], }],
}, },
{ {
title: '产品组',
vid: hash(`${++nextId}`), vid: hash(`${++nextId}`),
mid: hash(`${++nextId}`), mid: hash(`${++nextId}`),
title: '产品组',
maxReferenceCount: -1, maxReferenceCount: -1,
referenceCount: 0, referenceCount: 0,
image: undefined, image: undefined,
@ -347,10 +338,15 @@ categories.value.unshift({
label: '说明', label: '说明',
field: 'content', field: 'content',
}, },
{
type: 'text',
label: '提示',
field: 'more',
},
] ]
}, },
{ {
help: '最多可添加10张图片,建议宽度750px;鼠标拖拽左侧圆点可调整图片顺序', help: '帮助',
addable: true, addable: true,
type: 'list', type: 'list',
field: 'groups', field: 'groups',
@ -385,23 +381,28 @@ categories.value.unshift({
], ],
init: { init: {
titleAndDesc: { titleAndDesc: {
mainTitle: '标题', mainTitle: '标题123',
content: '说明', content: '说明123',
more: '查看更多',
}, },
groups: [ groups: [
{ {
productTitle: '111', productTitle: '111',
} }
], ],
theme: {
color: 'blue',
}, },
children:{
theme: { theme: {
height: 200, radius: 12
padding: {
horizontal: 12.0,
}, },
color: 'pink', }
},
theme: {
height: 200,
padding: 12,
color: '@@theme.color',
}, },
children: { children: {
vid: hash(`${++nextId}`), vid: hash(`${++nextId}`),
@ -409,7 +410,8 @@ categories.value.unshift({
width: '100%', width: '100%',
height: '100%', height: '100%',
color: 'white', color: 'white',
radius: 12.0, clip: 'hidden',
radius: '@@children.theme.radius',
textAlign: 'center', textAlign: 'center',
}, },
children: [ children: [
@ -438,13 +440,19 @@ categories.value.unshift({
theme: { theme: {
fontSize: 16, fontSize: 16,
}, },
children: '左侧标题', children: {
type: 'text',
key: 'titleAndDesc.mainTitle'
},
}, },
{ {
theme: { theme: {
fontSize: 16, fontSize: 16,
}, },
children: '左侧说明', children: {
type: 'text',
key: 'titleAndDesc.content'
},
} }
] ]
}, },
@ -467,10 +475,14 @@ categories.value.unshift({
vertical: 1, vertical: 1,
horizontal: 5, horizontal: 5,
}, },
color: 'pink', color: '@@children.children.children.children.children.2.color',
textColor: '#fff',
radius: 16, radius: 16,
}, },
children: '查看更多', children: {
type: 'text',
key: 'titleAndDesc.more'
},
}, },
], ],
@ -490,20 +502,35 @@ categories.value.unshift({
}, },
padding: { padding: {
horizontal: 3, horizontal: 3,
}
}, },
children: [{ gap: 3,
clip: 'autoX',
},
children:
{
type: 'each',
key: 'groups',
handle: {
theme: { theme: {
width: '35%', width: '100px',
height: '100%', height: '100%',
mainAlign: "center", radius: 10,
color: '#fff', color: '#fff',
crossAlign: "center"
}, },
children: '产品' }
}, },
] // [{
// theme: {
// width: '35%',
// height: '100%',
// mainAlign: "center",
// color: '#fff',
// crossAlign: "center"
//
// },
// children: { }
// },
// ]
}, },
] ]
} }

@ -3,6 +3,7 @@ import type { View } from '../types';
import { computed } from 'vue'; import { computed } from 'vue';
import { useContext } from '../context'; import { useContext } from '../context';
import ColorConfig from '../configs/ColorConfig.vue'; import ColorConfig from '../configs/ColorConfig.vue';
import NumberStyle from '../styles/NumberStyle.vue'
defineOptions({ defineOptions({
name: 'ConfigCurrentView', name: 'ConfigCurrentView',
@ -17,17 +18,30 @@ const styles = computed(() => {
return undefined return undefined
} }
return Object.entries(view.value.theme).filter(([, value]) => { return Object.entries(view.value.theme).filter(([, value]) => {
return typeof value === 'string' && value.startsWith('@@theme.') return typeof value === 'string' && value.startsWith('@@')
}) as Array<[string, string]> }) as Array<[string, string]>
}) })
const label = computed(()=>{
if(!view.value?.title) {
return undefined
}
return view.value.title
})
</script> </script>
<template> <template>
{{ ctx.activeViewId }} {{ ctx.activeViewId }}
<hr/> <hr/>
<fieldset>
<legend>{{ label }}设置</legend>
<template v-for="([key, value]) in styles" :key="key"> <template v-for="([key, value]) in styles" :key="key">
<ColorConfig v-if="key === 'color'" :field="value.slice(2)" label="背景颜色" /> <ColorConfig v-if="key === 'color'" :field="value.slice(2)" label="背景颜色" />
<div v-else>{{ key }}:{{ value }}</div> <NumberStyle v-if="key === 'radius'" :field="value.slice(2)" label="圆角设置" />
<!-- <div v-else>{{ key }}:{{ value }}</div>-->
</template> </template>
<pre><code>{{ view }}</code></pre> </fieldset>
<!--<pre><code>{{ view }}</code></pre>-->
</template> </template>

@ -51,7 +51,7 @@ export interface EngineContextBase {
nextId: number nextId: number
/** 数据源 */ /** 数据源 */
sources: Record<string, Record<string, unknown>> sources: Record<string, Record<string, unknown>>
/** 到处数据 */ /** 导出数据 */
export: () => Exported export: () => Exported
/** 获取动态数据 */ /** 获取动态数据 */
value: <T>(blockId: string, key: string) => T | undefined value: <T>(blockId: string, key: string) => T | undefined
@ -62,7 +62,7 @@ export type EngineContext = UnwrapNestedRefs<EngineContextBase>
export const contextKey: InjectionKey<EngineContext> = Symbol.for('ddd:engine') export const contextKey: InjectionKey<EngineContext> = Symbol.for('ddd:engine')
const must = <T>(v: T | undefined, error: string): T => { const must = <T>(v: T | undefined, error: string): T => {
if (v == null) { if(v==null){
throw new Error(error) throw new Error(error)
} }
return v return v
@ -74,8 +74,8 @@ export function useContext(): EngineContext {
export const parentViewIdKey: InjectionKey<string> = Symbol.for('ddd:view:parent:id') export const parentViewIdKey: InjectionKey<string> = Symbol.for('ddd:view:parent:id')
export function useParentViewId(): string | undefined { export function useParentViewId(): string {
return inject(parentViewIdKey) return must(inject(parentViewIdKey), 'no parentViewId no found')
} }
export function provideParentViewId(id: string | undefined): void { export function provideParentViewId(id: string | undefined): void {
@ -86,7 +86,7 @@ export function provideParentViewId(id: string | undefined): void {
const blockIdKey: InjectionKey<string> = Symbol.for('ddd:block:id') const blockIdKey: InjectionKey<string> = Symbol.for('ddd:block:id')
export function useBlockId(): string { export const useBlockId = (): string => {
return must(inject(blockIdKey), "no block found") return must(inject(blockIdKey), "no block found")
} }
@ -94,8 +94,9 @@ export function provideBlockId(id: string): void {
provide(blockIdKey, id) provide(blockIdKey, id)
} }
export const currentViewDOMRectKey: InjectionKey<UnwrapNestedRefs<Partial<DOMRect>>> = Symbol.for('ddd:view:current:domrect') type ReactingDomRect = InjectionKey<UnwrapNestedRefs<Partial<DOMRect>>>
export const parentViewDOMRectKey: InjectionKey<UnwrapNestedRefs<Partial<DOMRect>>> = Symbol.for('ddd:view:parent:domrect') export const currentViewDOMRectKey: ReactingDomRect = Symbol.for('ddd:view:current:domrect')
export const parentViewDOMRectKey: ReactingDomRect = Symbol.for('ddd:view:parent:domrect')
export function useCurrentViewDOMRect(): UnwrapNestedRefs<Partial<DOMRect>> { export function useCurrentViewDOMRect(): UnwrapNestedRefs<Partial<DOMRect>> {
return must(inject(currentViewDOMRectKey), 'no DOMReact found') return must(inject(currentViewDOMRectKey), 'no DOMReact found')
@ -106,9 +107,9 @@ export function useParentViewDOMRect(): UnwrapNestedRefs<Partial<DOMRect>> {
} }
export function getModule(ctx: UnwrapNestedRefs<EngineContextBase>, mid: string): Module | undefined { export function getModule(ctx: UnwrapNestedRefs<EngineContextBase>, mid: string): Module | undefined {
for (const category of ctx.categories) { for(const category of ctx.categories){
for (const module of category.modules) { for(const module of category.modules){
if (module.mid === mid) { if(module.mid === mid) {
return module return module
} }
} }
@ -116,15 +117,15 @@ export function getModule(ctx: UnwrapNestedRefs<EngineContextBase>, mid: string)
return undefined return undefined
} }
export function useModule() { export function useModule(){
const ctx = useContext() const ctx = useContext()
return computed((): Module | undefined => { return computed((): Module | undefined => {
for (const block of ctx.blocks) { for(const block of ctx.blocks){
if (block.vid !== ctx.activeBlockId) { if(block.vid !== ctx.activeBlockId){
continue continue
} }
const module = getModule(ctx, block.mid) const module = getModule(ctx,block.mid)
if (module != null) { if (module != null) {
return module return module
} }
@ -163,7 +164,9 @@ export interface TreeData {
value: any value: any
} }
const treeDataKey: InjectionKey<UnwrapNestedRefs<TreeData>|WritableComputedRef<TreeData> | null> = Symbol.for('ddd:view:tree:data') type RefTreeData = InjectionKey<UnwrapNestedRefs<TreeData>|WritableComputedRef<TreeData>|null>
const treeDataKey: RefTreeData = Symbol.for('ddd:view:tree:data')
export function provideTreeData(data: UnwrapNestedRefs<TreeData> | WritableComputedRef<TreeData> | null) { export function provideTreeData(data: UnwrapNestedRefs<TreeData> | WritableComputedRef<TreeData> | null) {
provide(treeDataKey, data) provide(treeDataKey, data)
@ -175,7 +178,9 @@ export function useSource<T = unknown>(source: string | undefined, fallback?: T)
const blockId = useBlockId() const blockId = useBlockId()
return computed<T | undefined>({ return computed<T | undefined>({
get(): T | undefined { get(): T | undefined {
console.log('get',source,'source',blockId || ctx.activeBlockId,'id')
if (!source) { if (!source) {
return fallback return fallback
} }
@ -193,6 +198,7 @@ export function useSource<T = unknown>(source: string | undefined, fallback?: T)
return valueOf(ctx.sources[id], source) ?? fallback return valueOf(ctx.sources[id], source) ?? fallback
}, },
set(value: T | undefined) { set(value: T | undefined) {
console.log('set',value,'value',source,'source',blockId || ctx.activeBlockId,'id')
if (!source || source.startsWith("$")) { if (!source || source.startsWith("$")) {
return return
} }

@ -0,0 +1,18 @@
<script lang="ts" setup>
import { useSource } from '../context.ts'
defineOptions({
name: 'DddRadiusStyle'
})
const props = defineProps<{
field: string
help?: string
label?: string
}>()
const tempStr = useSource<string>(props.field)
</script>
<template>
<div style="display: flex;justify-content: space-between">
<label>{{props.label}}</label>
<input type="range" min="1" max="50" v-model="tempStr">
</div>
</template>

@ -274,7 +274,7 @@ export type ClipBehavior =
| 'visible' | 'visible'
| 'auto' | 'auto'
| 'autoX' // overflow-x: auto; overflow-y: hidden | 'autoX' // overflow-x: auto; overflow-y: hidden
| 'autoY' // overflow-x: hidden; overflow-y: auto | 'autoY' // overflow-y: hidden; overflow-y: auto
/** /**
* *
@ -405,6 +405,7 @@ export interface View {
*/ */
// theme?: Theme | Widget // theme?: Theme | Widget
theme?: DynamicTheme theme?: DynamicTheme
title?: string
/** /**
* *
*/ */

@ -9,11 +9,12 @@ const props = defineProps<{
const mod = useModule() const mod = useModule()
const name = useSource(props.source) const name = useSource(props.source)
const view = computed(() => { const view = computed(()=>{
const ts = mod.value?.templates const ts = mod.value?.templates
const key = name.value const key = name.value
return ts && key ? ts[key] : undefined return ts && key ? ts[key] : undefined
}) })
</script> </script>
<template> <template>

@ -1,6 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useSource } from '../context' import { useSource } from '../context'
defineOptions({ defineOptions({
name: 'DddTextView', name: 'DddTextView',
inheritAttrs: false, inheritAttrs: false,

Loading…
Cancel
Save