我打开终端,习惯性地敲下nvim,进入编辑器的那一秒,先看到的不是代码,而是一整个启动画面。这个画面在 Vim 时代是静态字符,在 Neovim 早期是一屏版本信息,到了现在,很多人的启动页已经变成了带最近文件列表、快捷键按钮、Git 分支甚至会话恢复的“工作台”。作为一个每天和终端编辑器打交道超过十年的人,我越来越觉得,启动画面就是编辑器的“门面”,它决定了你进入开发状态的第一感受,也最能体现一个人对配置细节的在意程度。
这篇内容不打算只聊“怎么把启动页做得好看”,而是想顺着 Neovim 启动画面的进化线索,把背后的设计逻辑、主流插件的选型思路、可落地的配置方案和常见的坑位一起讲透。适合正在给 Neovim 折腾配置、对 dashboard 类插件有兴趣但还没动手的开发者,也适合那些已经装了 alpha-nvim、mini.starter,却不知道怎么按自己习惯做深度定制的人。
1. 为什么说启动画面是终端编辑器的“门面”
1.1 每次启动都看到的第一屏,决定了进入状态的速度
我见过不少同事,装完 Neovim 没做任何配置,敲nvim进去看到一屏大字符和帮助提示,然后就愣住了,不知道下一步该干嘛。这不是能力问题,而是启动画面在承担“引导入口”的角色时没有做到位。
想想看,打开编辑器后你最想做什么?是打开最近改到一半的文件,是搜索某个项目里的目标文件,还是恢复上一次的会话。如果这些操作都能在启动页上直接完成,那启动页就不再是“过场动画”,而是一个真正的效率入口。我自己的体验是,启动页上能少敲三五个命令,一天下来的体感差异非常明显,尤其在频繁切换项目的时候。
从心理层面讲,一个好的启动画面也会影响使用意愿。终端编辑器已经很“硬核”了,如果第一屏还显得粗糙,新手很容易被劝退。反过来,一个干净、有信息量的启动页,会让老手觉得这个环境是被认真打理的,写起代码来也更顺手。
1.2 “门面”不只是情怀,它承载了旧文件、快捷键和会话恢复
这里说的“门面”,不是单纯指视觉上的美观。我的判断标准只有一个:启动页上能否直接触达下一步操作。
最核心的三个信息维度是:
- 最近文件列表。通过
oldfiles或者 shada 历史记录,快速回到刚才的编辑现场。 - 常用快捷键。比如打开文件搜索、全局搜索、终端面板、退出编辑器。
- 会话状态。如果能从启动页直接恢复上次的窗口布局和未保存的 buffer,基本上可以做到“打开编辑器即回到上次离开的位置”。
这三个能力才是启动页真正的价值所在。它不是为了“炫”,而是为了减少编辑器启动后那几秒钟的迷路成本。很多 dashboard 插件之所以流行,就是因为它把这几个能力做成了默认配置,开箱即用。
1.3 从 Vim 到 Neovim,门面演进的几条主线
我梳理了一下这条演进线,大概能分三个阶段。
第一阶段是 Vim 时代。启动画面基本是静态的“VIM - Vi Improved”大字符,加上版本信息和帮助提示,作用是告诉用户“这是 Vim,按:help看文档,按:q退出”。它非常朴素,也没有交互可言,属于极客工具刚诞生时的“门面”。
第二阶段是 Neovim 早期。继承了类似的大字符展示方式,但把 logo 换成了 NEOVIM,版本信息增加了 git commit hash 等更“开发者友好”的内容。这个阶段仍然没有把启动页当成一个产品来做,更像是一个占位提示页。
第三阶段就是近几年插件生态爆发之后。dashboard-nvim、alpha-nvim、mini.starter 这些插件把启动页从“静态文本”带进了“可编程组件”时代。你可以任意组合 header、按钮、最近文件、项目列表、git 信息,甚至在启动页上嵌入一个按需加载的菜单系统。这一阶段的启动页,已经从“门面”变成了名副其实的“控制台入口”。
2. Neovim 官方启动画面与第三方插件生态
2.1 官方默认启动画面:朴素但一直在微调
先说官方默认行为。当你直接敲nvim不跟文件名时,Neovim 会创建一个“启动缓冲区”,里面显示 NEOVIM 大字符、当前版本号、build 信息,以及几行操作提示,比如按q退出、按:help查看帮助、按:checkhealth检查环境。不同发行版和不同版本之间,具体措辞和排版会有差异,我建议以你自己机器上nvim --version对应的实际输出为准。
说实话,官方这个默认页不算出彩,但它的意义在于:Neovim 从早期开始就意识到“无文件启动”是一个值得处理的场景,而不是让用户面对一个空 buffer 发呆。近几年官方也在调整启动 buffer 的交互细节,包括提示文字、退出方式,以及与oldfiles的配合,但整体上仍然偏保守。
所以,社区里绝大多数人都会选择忽略这个默认页,直接上第三方启动插件。这也就引出了更热闹的插件生态。
2.2 第三方 dashboard 类插件为什么会出现
第三方插件出现的原因很直接:官方默认页只解决了“有提示”的问题,没有解决“能办事”的问题。
dashboard-nvim 是早期最有名的方案,我从 Vim 时代就开始用它的前身 vim-dashboard。它的思路很清晰:把最近文件列表、快捷键、会话恢复整合到启动画面里,以doom风格或默认风格的 dash 页面展示。后来 alpha-nvim 出现,用纯 Lua 重新实现了启动页引擎,把 sections 和 layout 的概念引入了进来,形成了一套更灵活的配置模型。
mini.starter 则是极简路线的代表,它不强加任何视觉风格,而是提供一套构造成“item + hook”的机制,由配置者自己决定展示什么、如何展示。startup.nvim、nord 主题配套的 dashboard 等也都有自己的受众,但我最常用的还是前面三个。
这些插件之所以能替代默认启动页,是因为它们把“启动页”从一个“提示页”变成了“可编程的组件树”。你能在 header 放 ASCII logo,在 buttons 里绑定任意命令,在 mru_files 里展示历史文件,在 footer 里放版本信息,一切都是配置驱动的,改动即时生效,还不污染你的vimrc。
2.3 启动页组件的关键概念:header、section、button、layout
如果只看官方 README,几个概念可能会让人犯迷糊,我来用大白话拆一下。
header 是启动页最上方的大片文字区域,通常放 ASCII 字符画或者一行项目名。它承担“第一眼印象”,也是很多人最愿意花时间折腾的地方。
section 是整个启动页里的一个“区块”,比如“最近文件”是一个 section,“快捷键按钮”是另一个 section,“footer 版本号”也可以算一个 section。每个 section 负责展示一类数据。
button 是 section 里可点击/可按的交互项。alpha-nvim 里配置 button 时,一般给一个快捷键字符、一段说明文字、一个要执行的 Ex 命令。按下对应键时就会触发动作,比如f打开文件搜索,q退出。
layout 是区块在页面上的排列方式。alpha-nvim 允许你控制每个 section 的 x 位置、y 位置、宽度、对齐方式。我对 layout 的建议是别过度设计,越简单越不容易在窄终端里翻车。
理解了这四个概念,再看任何 dashboard 插件的配置,基本都能一眼看懂。它们的差异只是 API 命名和实现细节不同,核心思想是相通的。
3. 主流启动页方案怎么选
3.1 dashboard-nvim:老牌方案,胜在经验积累
dashboard-nvim 的前身是 vim-dashboard,插件仓库目前由 nvimdev 维护。它的优势是功能全,默认就带 MRU 文件列表、快捷键面板、会话恢复、项目列表等能力,配置门槛也比较低。
我早期用它的理由是省心:装好之后,稍微改一改 header 和快捷键,马上就能用。它的配置方式偏向“声明式”,你把标题、按钮、动作往 table 里一填,视觉和逻辑基本就出来了。
但用久了我也发现几个问题。首先是它的 Lua API 和新版 Neovim 的兼容性偶尔会有滞后,某些边缘情况下需要手动 patch;其次是内部抽象不够干净,做复杂布局时限制较多。如果追求“开箱即用,改动不多”,dashboard-nvim 仍然是不错的选择。
一个典型的最小配置:
{ "nvimdev/dashboard-nvim", event = "VimEnter", config = function() require("dashboard").setup({ theme = "doom", config = { header = { " ███╗ ██╗ ███████╗ ██████╗ ██╗ ██╗██╗███╗ ███╗", " ████╗ ██║ ██╔════╝██╔═══██╗██║ ██║██║████╗ ████║", " ██╔██╗ ██║ █████╗ ██║ ██║██║ ██║██║██╔████╔██║", " ██║╚██╗██║ ██╔══╝ ██║ ██║╚██╗ ██╔╝██║██║╚██╔╝██║", " ██║ ╚████║ ███████╗╚██████╔╝ ╚████╔╝ ██║██║ ╚═╝ ██║", " ╚═╝ ╚═══╝ ╚══════╝ ╚═════╝ ╚═══╝ ╚═╝╚═╝ ╚═╝", }, shortcut = { { desc = "Find File", group = "@label", action = "Telescope find_files", key = "f" }, { desc = "Recent Files", group = "@label", action = "Telescope oldfiles", key = "r" }, { desc = "Quit", group = "@label", action = "qa", key = "q" }, }, }, }) end, }注意,dashboard-nvim 各个版本的配置字段有差异,我这里是社区里比较常见的一种写法,具体以仓库最新 README 为准。
3.2 alpha-nvim:更现代的启动页引擎
如果你愿意稍微多花一点学习成本,换一个更灵活、更贴合 Neovim 生态的启动页底座,我优先推荐 alpha-nvim。
alpha-nvim 的优势在于,它把启动页拆成了“布局”和“组件”两层。你既可以躺平用默认 dashboard 主题,也可以完全自定义 layout,把 header、buttons、mru_files 任意摆放。这种设计非常适合那些已经对 Neovim 有明确掌控欲的人。
我实际使用 alpha-nvim 两年多的感受是,它的启动速度足够快,配置模型清晰,与 lazy.nvim、telescope.nvim、session 管理插件集成都很顺手。大多数情况下,不需要担心它拖慢 Neovim 启动时间,因为纯 Lua 的渲染开销很小。
不过,自由度高也有代价:新手容易在 layout 上反复横跳。我见过不少人在 alpha 上折腾半天,最后只是为了让 header 居中一两个像素。没必要,真的没必要。先把最常用的三个 section 配好,剩下的以后再说。
3.3 mini.starter:极简主义者的最爱
mini.starter 是 echasnovski 的 mini 系列之一,和我前面说的两个项目气质完全不同。它默认不提供任何华丽的视觉模板,而是给出一个非常干净的“条目列表”抽象。
你可以把任何东西变成 item,比如打开某个文件、执行某个命令、罗列最近文件。再通过 content_hooks 给整个列表加标题、加分割线、加 footer。我偶尔会在无插件环境中配置一个极简版 mini.starter,效果相当清爽。
它适合作风极简、不愿意被大项目束缚的人。缺点是新手要自己拼出一个比较满意的页面,代码量会稍微多一点。如果你希望启动页“一眼看过去就很克制”,mini.starter 绝对值得试。
一个基本配置示例:
{ "echasnovski/mini.starter", version = false, config = function() local starter = require("mini.starter") starter.setup({ items = { starter.sections.recent_files(10), starter.sections.recent_sessions(5), { name = "Find File", action = ":Telescope find_files", }, }, content_hooks = { starter.gen_hook.add_title("MY NEOVIM"), starter.gen_hook.align_center(), }, }) end, }3.4 几个方案放在一起怎么选
| 插件 | 配置风格 | 扩展性 | 依赖 | 推荐场景 |
|---|---|---|---|---|
| dashboard-nvim | 声明式,偏简单 | 一般,layout 控制有限 | 较少 | 希望装完即用,改动不多 |
| alpha-nvim | 组件式,较灵活 | 很好,支持自定义 layout | 可选 devicons | 愿意花时间定制,追求可控 |
| mini.starter | 极简抽象,手动拼装 | 很高,但需要写 item/hook | 无 | 干净、极简、依赖少 |
我的个人倾向是,如果只想快速体验“启动页能干什么”,dashboard-nvim 最方便;想长期打磨配置,alpha-nvim 上限更高;想感受最小依赖和最大自由,mini.starter 不会让你失望。
4. 实操:基于 alpha-nvim 打造“工作台”式启动页
4.1 安装前需要准备的组件
在开始配置之前,我先确认自己已经装好了下面这些基础组件,缺一不可:
- Neovim 0.9 及以上版本,推荐使用最新稳定版。
- 一套插件管理器,我用 lazy.nvim,配置示例也按 lazy.nvim 写。
- 可选:nvim-web-devicons,用于在文件图标区域渲染文件类型图标。
- 可选:telescope.nvim 或 fzf-lua,作为文件搜索后端。
如果你用的不是 lazy.nvim,也没关系,alpha-nvim 的安装思路是一样的,只是插件声明写法略有不同。下面所有示例默认你已经在 lazy.nvim 的 plugins 目录里写配置。
4.2 基础配置:header、buttons、最近文件
下面这份配置是我在实际项目中验证过的。我把它放在~/.config/nvim/lua/plugins/alpha.lua(如果你用 lazy.nvim 自动加载,确认文件路径在 plugins 扫描范围内)。
return { { "goolord/alpha-nvim", dependencies = { "nvim-tree/nvim-web-devicons" }, config = function() local alpha = require("alpha") local dashboard = require("alpha.themes.dashboard") -- header:可以换成你自己喜欢的 ASCII 字符画 dashboard.section.header.val = { " ╔═══╗╔══╗╔═══╗╔══╗╔╗─╔╗╔═══╗", " ║╔═╗║╚╣╠╝║╔═╗║╚╣╠╝║╚═╝║║╔══╝", " ║╚═╝║─║║─║╚═╝║─║║─║╔╗─║║╚══╗", " ║╔╗╔╝─║║─║╔╗╔╝─║║─║╚╝╔╝╚══╗║", " ║║╚╝╔╝╔╣╠╗║║╚╝╔╝╔╣╠╗╚╗╔╝─╔═╝║", " ╚╝──╚╝╚══╝╚╝──╚╝╚══╝─╚╝──╚══╝", } -- 最近文件列表 dashboard.section.mru_cwd.val = { { "Recent files", "<cmd>Telescope oldfiles<CR>" }, } -- 快捷键按钮 dashboard.section.buttons.val = { dashboard.button("f", " Find file", "<cmd>Telescope find_files<CR>"), dashboard.button("r", " Recent files", "<cmd>Telescope oldfiles<CR>"), dashboard.button("s", " Restore last session", "<cmd>SessionManager load_last_session<CR>"), dashboard.button("q", " Quit nvim", "<cmd>qa<CR>"), } -- footer:放点版本号或鼓舞人心的话 dashboard.section.footer.val = "Have fun with Neovim!" -- 可选:对齐布局 dashboard.opts.opts.hl_headers = { "Title" } dashboard.opts.opts.hl_buttons = { "Keyword" } alpha.setup(dashboard.opts) end, }, }配置完成后,重启 Neovim 再敲nvim,应该就能看到一个新的启动页。header 在上方,最近文件或者按钮区域在中间,footer 在底部。如果按下f、r、s、q,会分别触发对应命令。
这里加两个提醒。第一,如果你的oldfiles列表为空,最近文件区域可能只显示一个空标题,这不是 bug,只是 shada 历史里暂无文件。第二,SessionManager插件需要单独安装,如果没装,把s按钮的 action 改成自己熟悉的方式,或者干脆删除这个按钮。
4.3 扩展:接入 Telescope、会话与 Git 信息
基础配置跑通之后,大多数人会开始往里面加“私货”。我自己的启动页就扩展了几块内容,在这里分享给你。
第一块是文件搜索。我不喜欢在启动页上再写死的文件路径,而是直接绑定 Telescope 的find_files和oldfiles。这样无论项目目录里有什么变化,启动页都能动态覆盖当前项目文件,不需要手动维护。建议使用:Telescope find_files而不是:e指定路径,因为后者很容易让启动页看起来“很废”。
第二块是会话恢复。会话恢复最舒服的体验是“打开 nvim 就能回到上次的窗口布局”。我用的是nvim-session-manager,在启动页上给它留一个按钮,绑定load_last_session。你也可以写成自动恢复,不需要按钮,但我更喜欢手动触发,避免每次打开都跳进一个很大的历史会话。
第三块是 Git 信息。如果你的项目在版本控制下,可以在 footer 显示当前分支名。alpha 插件本身不关心 git,你需要在配置里自己读取,比如:
local function git_branch() local handle = io.popen("git branch --show-current 2>/dev/null") if not handle then return "" end local branch = handle:read("*l") or "" handle:close() return branch end dashboard.section.footer.val = "branch: " .. git_branch()注意,频繁调用io.popen在启动阶段可能会有微小的性能损耗,所以我只在 footer 里用一次,不作为高频刷新逻辑。
如果想把启动页做成更完整的“工作台”,可以考虑引入键盘快捷键提示而非按钮。比如用which-key在启动页上实现一个自定义菜单,按空格弹出操作面板。这是个人习惯问题,我倾向于在启动页上保留高频操作,低频操作交给which-key。
4.4 不要让启动页拖慢 Neovim 的启动时间
很多人在配置完一个华丽启动页之后,会突然发现nvim打开变慢了,于是怀疑是启动页插件的问题。其实大多数情况下,慢的不是 alpha-nvim 本身,而是启动阶段被塞进配置里的其他初始化逻辑。
我习惯用这种方式排查:
nvim --startuptime startup.log然后看startup.log里时间最长的几行,通常问题出在以下几类地方:
- 启动时同步执行了
vim.fn.system、io.popen等外部命令。 - 在
config里拉取远程资源或编译 treesitter parser。 - 在启动阶段加载了大型插件,但没有设置
lazy = true或合适的event触发时机。
alpha-nvim 本身我用下来,启动阶段开销通常在几毫秒到十几毫秒之间,完全可以忽略。如果它出现在startup.log的耗时头部,多半是nvim-web-devicons或lazy.nvim在解析文件图标时消耗了一点时间,这个也不大。
为了稳妥,我会把 alpha 的加载时机设置为event = "VimEnter",这样它在启动初期不会抢占事件循环,等到真正进入编辑器时再渲染。这也是社区里最常见的写法。
5. 常见问题与排查技巧
5.1 启动页不显示,或者闪一下就被覆盖
如果你装了 alpha-nvim、dashboard-nvim 等插件,重启后却看不到启动页,先检查两件事。
第一,确认插件是否真的被 lazy.nvim 正确加载了。到 Neovim 里执行:
:Lazy load alpha-nvim如果命令报错,说明插件的 spec name 和实际定义不一致。检查 lazy.nvim 的name字段,或者直接看~/.local/share/nvim/lazy目录下是否存在对应插件。
第二,确认是否存在 buffer 覆盖。当VimEnter事件触发时,如果其他插件同时打开了窗口,比如nvim-tree的自动打开逻辑,启动页可能被新的 buffer 顶掉。我的做法是让文件树不要自动打开,或者把 alpha 的加载时机调到VimEnter之后。
你还可以手动执行:Alpha命令(如果你用 alpha-nvim),看看启动页能否被正常渲染。如果能,问题大概率集中在加载时机上;如果直接报错,优先检查配置里的dashboard.section字段是否写错。
5.2 最近文件列表为空,或者显示的内容不符合预期
列表为空的直接原因是oldfiles没有历史数据。Neovim 把文件历史存在 shada 文件里,默认路径是~/.local/state/nvim/shada/main.shada。如果你经常用nvim --clean、nvim -u NONE测试,或者在沙箱环境使用,就不会有持久化的历史记录。
处理办法:
- 先正常打开几个文件,再重启 Neovim,看
:oldfiles是否非空。 - 确认
vim.o.shadafile没有被设置为空字符串。 - 如果用的是
exrc或 IDE 启动器,注意工作目录变更可能导致 shada 路径不同。
另一种情况是列表已经有数据,但显示了一堆不相关路径,比如/tmp/xxx或插件缓存文件。我一般会对oldfiles做一层过滤,只保留当前目录下的文件,或者按文件扩展名过滤。
这里给一个简单的过滤思路,在配置里把最近文件列表替换成自定义 section:
local function get_recent_files() local files = vim.fn.stdpath("data") .. "/shada/main.shada" local oldfiles = vim.v.oldfiles or {} local result = {} for _, f in ipairs(oldfiles) do if vim.startswith(f, vim.loop.cwd()) then table.insert(result, { f, "<cmd>edit " .. f .. "<CR>" }) end if #result >= 10 then break end end return result end这个代码不是唯一答案,想扩展可以自己加上忽略规则和分组规则。
5.3 header 显示乱码,或者在某些终端下错位
ASCII art 错位是最常见的问题。原因有两类。
第一类是终端宽度不足。一个 30 字符宽的字符画,在 80 列窗口里没问题,在窄侧边栏里就会换行乱掉。解决办法是不要设计过宽的 header。我建议 header 单行控制在 50 个字符以内,适配大多数终端宽度;如果你经常在 120 列宽的终端里工作,可以放宽到 80。
第二类是字体宽度问题。中文环境或等宽字体配置不一致时,特殊字符(比如圆角框、块字符)可能导致半角/全角宽度判断错误。最简单的规避办法是使用纯 ASCII 的字符画,或者使用vim.o.ambiwidth = "double"来统一环境。如果你不想折腾字体,直接换成字母组成的文字 header,最稳。
第三类是配色问题。启动页背景和文字颜色如果和主题不匹配,会出现文字看不见的情况。我一般会为 header 单独设置高亮组,比如dashboard.header或Title,并在配置里手动指定hl_headers或hl_buttons,确保在不同主题下都保持对比度。
5.4 启动页不再更新了,或者快捷键没反应
快捷键没反应,通常分几种情况。
- 启动页插件在你按快捷键时没有触发对应命令。先确认按钮的 action 是否是正确的 Ex 命令。比如
dashboard.button("f", "Find file", "<cmd>Telescope find_files<CR>")中,<cmd>和<CR>不能输错,否则会匹配失败。 - 与用户自定义映射冲突。如果你在
vim.keymap.set里把f、r、q等键做了其他映射,启动页上的按钮可能被全局映射截胡。这个坑我踩过,后来把启动页按钮的 key 换成了ctrl配合字母,或者直接使用不常碰的键。 - 点击之后跳到普通 buffer,但启动页没被关闭。这是某些插件的预期行为,你可以给按钮 action 追加
:bwipeout逻辑,或者使用 alpha 的dashboard.button内部处理。
如果配置完全没问题但页面内容不刷新,重启 Neovim 通常能解决。alpha-nvim 会缓存部分配置,部分设置在运行时修改后需要重新 setup。
5.5 问题排查速查表
| 现象 | 可能原因 | 快速处理 |
|---|---|---|
| 启动页不显示 | 插件未加载 / 被其他 buffer 覆盖 | :Lazy load alpha-nvim,检查 event |
| 最近文件为空 | shada 无历史 | 正常打开几个文件后重启 |
| header 乱码 | 终端宽度不足 / 非等宽字体 | 缩短 header,避免特殊字符 |
| 快捷键没反应 | 映射冲突 / action 写错 | 用<cmd>和<CR>,避开全局映射 |
| 启动变慢 | 外部命令同步调用 / 插件懒加载配置不当 | 用--startuptime定位耗时项 |
| footer 不显示 | 字段名写错 / 主题高亮问题 | 检查 dashboard.section.footer 字段名 |
6. 我在 dotfiles 里沉淀下来的几点启动页配置心得
折腾启动页这么多年,最后留在我的配置里的东西越来越简单。我对启动页最深的体会是,它应该是一个“克制的工作台”,而不是一个“炫耀的展示台”。
第一,header 不要堆太多。以前我放过一整块 20 行的 ASCII 字符画,启动虽然不慢,但每次看都觉得喧宾夺主。后来换成 4 到 6 行的 logo,整个页面清爽了很多。如果实在想放长字符,建议加一个条件判断,只在终端宽度足够时才显示完整 header。
第二,按钮不要超过六个。我的启动页上只保留四个核心动作:找文件、最近文件、恢复会话、退出。其他功能交给which-key和命令行,否则启动页会变成第二个菜单栏,反而失去了“快速进入工作状态”的意义。
第三,最近文件列表比任何花哨装饰都有用。启动页最值得投入精力的地方,就是让oldfiles和当前项目目录结合得足够顺滑。真实感受是,一个能在两秒内打开昨天正在编辑的文件、又能按项目过滤掉临时文件的启动页,比任何炫酷的动画都提升幸福感。
最后再分享一个小技巧:配置完启动页后,别只在宽屏终端里看效果。在 tmux 分屏、窄侧边栏、不同字体环境下都过一遍,确认不会错位。我早期折腾 dashboard-nvim 时,就因为没检查窄屏,结果在远程服务器上一打开就是乱版,非常狼狈。
启动页终究是为“下一步动作”服务的,能让你舒服地进入编辑状态,它就是一个合格的“门面”。