diff --git a/src/context.ts b/src/context.ts
index 0949cc4..1194347 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -1,6 +1,11 @@
import type { Node } from '@babel/types'
import { isMp } from '@uni-helper/uni-env'
-import type { AttributeNode, DirectiveNode, ElementNode, SimpleExpressionNode } from '@vue/compiler-core'
+import type {
+ AttributeNode,
+ DirectiveNode,
+ ElementNode,
+ SimpleExpressionNode,
+} from '@vue/compiler-core'
import { babelParse, walkAST } from 'ast-kit'
import MagicString from 'magic-string'
import { kebabCase } from 'scule'
@@ -71,7 +76,9 @@ export class Context {
// layout name is empty
if (!pageLayoutName)
return
- pageLayout = this.layouts.find(l => l.name === (pageLayoutName as string))
+ pageLayout = this.layouts.find(
+ l => l.name === (pageLayoutName as string),
+ )
// can not find layout
if (!pageLayout)
return
@@ -100,18 +107,58 @@ export class Context {
})
}
+ // 检查是否有 page-meta 组件
+ let pageMetaNodes: ElementNode[] = []
+ if (sfc.template?.ast) {
+ pageMetaNodes = sfc.template.ast.children.filter(
+ v =>
+ v.type === 1
+ && (kebabCase(v.tag) === 'page-meta' || v.tag === 'page-meta'),
+ ) as ElementNode[]
+ }
+
if (disabled) {
// find dynamic layout
- const uniLayoutNode = sfc.template?.ast.children.find(v => v.type === 1 && kebabCase(v.tag) === 'uni-layout') as ElementNode
+ const uniLayoutNode = sfc.template?.ast!.children.find(
+ v => v.type === 1 && kebabCase(v.tag) === 'uni-layout',
+ ) as ElementNode
// not found
if (!uniLayoutNode)
return
- ms.overwrite(uniLayoutNode.loc.start.offset, uniLayoutNode.loc.end.offset, this.generateDynamicLayout(uniLayoutNode))
+ ms.overwrite(
+ uniLayoutNode.loc.start.offset,
+ uniLayoutNode.loc.end.offset,
+ this.generateDynamicLayout(uniLayoutNode),
+ )
}
else {
- if (sfc.template?.loc.start.offset && sfc.template?.loc.end.offset)
- ms.overwrite(sfc.template?.loc.start.offset, sfc.template?.loc.end.offset, `\n${sfc.template.content}\n`)
+ if (sfc.template?.loc.start.offset && sfc.template?.loc.end.offset) {
+ // 提取 page-meta 组件内容
+ const pageMetaContent = pageMetaNodes
+ .map(node => node.loc.source)
+ .join('\n')
+
+ // 从原内容中移除 page-meta 组件
+ let contentWithoutPageMeta = sfc.template.content
+ for (const node of pageMetaNodes) {
+ contentWithoutPageMeta = contentWithoutPageMeta.replace(
+ node.loc.source,
+ '',
+ )
+ }
+
+ // 在布局外部添加 page-meta
+ ms.overwrite(
+ sfc.template?.loc.start.offset,
+ sfc.template?.loc.end.offset,
+ `\n${pageMetaContent}${contentWithoutPageMeta}\n`,
+ )
+ }
}
if (ms.hasChanged()) {
@@ -155,42 +202,70 @@ export default {
v => v.type === 6 && v.name === 'name' && v.value?.content,
) as AttributeNode
const dynamicLayoutNameBind = node.props.find(
- v => v.type === 7 && v.name === 'bind' && v.arg?.type === 4 && v.arg?.content === 'name' && v.exp?.type === 4 && v.exp.content,
+ v =>
+ v.type === 7
+ && v.name === 'bind'
+ && v.arg?.type === 4
+ && v.arg?.content === 'name'
+ && v.exp?.type === 4
+ && v.exp.content,
) as DirectiveNode
const slotsSource = node.children.map(v => v.loc.source).join('\n')
- const nodeProps = node.props.filter(prop => !(prop === dynamicLayoutNameBind || prop === staticLayoutNameBind)).map(v => v.loc.source)
+ const nodeProps = node.props
+ .filter(
+ prop =>
+ !(prop === dynamicLayoutNameBind || prop === staticLayoutNameBind),
+ )
+ .map(v => v.loc.source)
- if (!(staticLayoutNameBind || dynamicLayoutNameBind))
- console.warn('[vite-plugin-uni-layouts] Dynamic layout not found name bind')
+ if (!(staticLayoutNameBind || dynamicLayoutNameBind)) {
+ console.warn(
+ '[vite-plugin-uni-layouts] Dynamic layout not found name bind',
+ )
+ }
if (isMp) {
const props: string[] = [...nodeProps]
if (staticLayoutNameBind) {
const layout = staticLayoutNameBind.value?.content
- return `${slotsSource}`
+ return `${slotsSource}`
}
const bind = (dynamicLayoutNameBind.exp as SimpleExpressionNode).content
const defaultSlot = node.children.filter((v) => {
if (v.type === 1 && v.tagType === 3) {
- const slot = v.props.find(v => v.type === 7 && v.name === 'slot' && v.arg?.type === 4) as any
+ const slot = v.props.find(
+ v => v.type === 7 && v.name === 'slot' && v.arg?.type === 4,
+ ) as any
if (slot)
return slot.arg.content === 'default'
}
return v
})
const defaultSlotSource = defaultSlot.map(v => v.loc.source).join('\n')
- const layouts = this.layouts.map((layout, index) => `${slotsSource}`)
+ const layouts = this.layouts.map(
+ (layout, index) => `${slotsSource}`,
+ )
layouts.push(`${defaultSlotSource}`)
return layouts.join('\n')
}
else {
const props: string[] = [...nodeProps]
- if (staticLayoutNameBind)
- props.push(`is="layout-${staticLayoutNameBind.value?.content}-uni"`)
- else
- props.push(`:is="\`layout-\${${(dynamicLayoutNameBind.exp as SimpleExpressionNode).content}}-uni\`"`)
+ if (staticLayoutNameBind) { props.push(`is="layout-${staticLayoutNameBind.value?.content}-uni"`) }
+ else {
+ props.push(
+ `:is="\`layout-\${${
+ (dynamicLayoutNameBind.exp as SimpleExpressionNode).content
+ }}-uni\`"`,
+ )
+ }
return `${slotsSource}`
}
}