npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@wulechuan/vue2-ui--page

v0.1.9

Published

针对在 Vue 2.x 框架的用户界面组件:视觉页(Page)。并支持 TypeScript 语法。

Downloads

16

Readme

吴乐川的针对 Vue 2.x 的用户界面组件:可视页,即 Page(支持 TypeScript 语法)

Multilingual Editions of this Article

NPM 页

@wulechuan/vue2-ui--page

简介

顾名思义,本组件系面向 Vue 2.x 框架制作的一种用户界面(UI)成分(或者说零件)。该零件之功用为轻松构建一个视觉上的所谓“页面”。

本组件认为,一个视觉上的页面由三个重要部分组成:【页眉】(page-header)、【页脚】(page-footer)和【页面主体】(page-body)。本组件同时提供此三个组成部分。并且,【页眉】与【页脚】为可选配件,可通过输入项(即 Vue 组件之所谓 prop)配置二者存在与否。【页面主体】之存在性不可配置,即【页面主体】恒存在。

本组件可解决一些用程序迎合美术设计思路之痛点。具体而言,常见之页面设计之布局有若干种,每种设计对应的程序实现均有所区别。本工具之设计目的即是一应俱全(流行语所谓“提供‘一站式’解决方案”),令采用者单用这一个可配置的“页面”组件,就可灵活应对多种设计要求。本组件所能满足的设计形式不妨列举如下:

  • 有否【页眉】。

  • 有否【页脚】。

  • 【页眉】是否悬挂在页面顶部,不随【页面主体】滚动。

  • 【页脚】是否沉淀在页面底部,不随【页面主体】滚动。

  • 【页眉】是否总是覆盖【页面主体】。这一设计要求往往为了追求美观,且【页眉】本身会有半透明底色,以使衬于其下的【页面主体】若隐若现。

  • 【页脚】是否总是覆盖【页面主体】。这一设计要求往往为了追求美观,且【页脚】本身会有半透明底色,以使衬于其下的【页面主体】若隐若现。

  • 是否强制【页面主体】之高度至少应充满整个窗口,即 min-height100%

又,以上设计要求组合变化,会得到有些复杂的结果。特进一步做如下琐碎之说明:

  • 即便【页眉】不悬挂于页面顶部,本组件仍允许将【页眉】配置为“覆盖于【页面主体】之上层”。如是,尽管【页眉】会随【页面主体】而滚动,但【页眉】恒定覆盖【页面主体】之首部。【页眉半透明】,【页面主体】之首部衬于【页眉】下方,若隐若现。

    诚然,如果此时【页面主体】之首部一片空白,则此设计之意义不大。因此,实践中,此种设计往往是在【页面主体】之首部设计了装饰性的图案。透过半透明的【页眉】,【页面主体】首部的该装饰依稀可见,微妙动人。

  • 即便【页脚】不沉淀于页面底部,本组件仍允许将【页脚】配置为“覆盖于【页面主体】之上层”。参见上一条目。

  • 为防止覆盖在【页面主体】上层的【页眉】遮挡【页面主体】之正文内容,本组件会自动根据【页眉】之高度,为必要的页面构成 DOM 元素设置准确的 padding-top。采用本组件之程序无需担心这些细节。

  • 为防止覆盖在【页面主体】上层的【页脚】遮挡【页面主体】之正文内容,本组件会自动根据【页脚】之高度,为必要的页面构成 DOM 元素设置准确的 padding-bottom。采用本组件之程序无需担心这些细节。

  • 当【页眉】须悬挂于页面顶部时,本组件故意采用 position: absolute 而非 position: fixed。因此,为确保【页眉】不随【页面主体】滚动,本组件故意要求【页面主体】之外层容器之高度恰好充满整个浏览器窗口,并令【页面主体】按需自动配备滚动条。【页面主体】位于 HTML 层级之较内层,其内容之滚动不至于带动【页眉】,故而达到目的。

  • 当【页脚】须沉淀于页面底部是,本组件故意要求【页面主体】之高度恰好充满整个浏览器窗口。此举与上一条目类同。

用法

基本使用思路说明

鄙人自以为本组件之用法符合直觉。而略显讽刺之处在于,鄙人觉得有必要多费口舌,讲解本品之使用思路。此举看似自相矛盾,实则非也。符合直觉并非同义于简单。 欲应对灵活多变之设计要求,本组件之用法亦不得不有繁复、琐碎之处须理解、注意。

目前,本组件之用法思路由 3 部分内容组成:

  1. 核心组件之引用。

    此部分既包含模板(<template>)和逻辑(<script>),也包含用于布局的、故而不可或缺的最基础之样式(<style>)。应用好该部分功能,则【页面】大体成形。但某些尺寸尚且未定。

  2. 所谓“关键但不确定”之样式的运用。

    这是指一些虽然必不可少,但却因项目而异的样式配置。典型的例子是【页眉】之高度、【页脚】之高度。于此两数值,本组件不便冒然给出所谓默认值,故而有意空缺,留待本组件之外的代码补充给出。 换而言之,诸君采用本组件时,莫要忘记自行定义这些样式,以获得正确的效果。

    还需指出,于这部分样式之定义、配置,本组件有推荐做法。参阅下文《所谓“关键但不确定”的样式》一节。

  3. 非必须的所谓“额外的样式预设”之运用。

    这些额外样式视同所谓“预设”,系为达成某些习惯提供方便而已。这些样式亦由本组件附带,可供选用。它们存在于 .vue 文件中,而是存在于一些独立的 .css 中。这些独立的 .css 文件源于一些由本组件提供的 .styl 源文件,而这些 .styl 文件显然也是独立于 .vue 文件的,否则不成其为 .styl 文件。

开发任务拆解

于开发者而言,使用思路明确之后,还需明白开发的具体任务。众所周知,在基于 Vue 框架的开发过程中,不论你采用 Vue 的【单文件组件】(所谓 Single-filed Component,SFC)与否,开发任务总可以为三个部分:模板部分、脚本逻辑部分和样式部分。下文将分此三个部分,并结合前述使用思路和示例,介绍本组件之用法。

模板(<template>)部分

撰写模板的任务,又可进一步细分为三个小任务:

  1. 在模板上按需给出 Props。例如 :has-header="true"
  2. 将内容插入本组件模板预先设计好的插槽(slot)中。
  3. 为了令【页眉】悬挂等特定风格的布局正常呈现,须小心配置本组件(即整个视觉页)的【根 div的祖先元素,即包裹着本组件的、不属于本组件的那些外层 DOM。
模板的 Props

暂略。见下文中的示例。另见下文《应用编程接口(所谓 API)》一节。

模板插槽
  1. 模板包含以下插槽(slot):

    • 默认插槽,被本组件内建的 div.page-body-content 所包裹,用于接纳【页面主体】之内容。
    • 名为 page-header-content 的插槽,被本组件内建的 div.page-header 所包裹。功能不言自明。
    • 名为 page-footer-content 的插槽,被本组件内建的 div.page-footer 所包裹。功能不言自明。
    • 名为 before-page-body-content 的插槽,被本组件内建的 div.before-page-body-content 所包裹。功能不言自明。
    • 名为 after-page-body-content 的插槽,被本组件内建的 div.after-page-body-content 所包裹。功能不言自明。
  2. 模板根标签所接纳的属性(attributes)。熟悉 Vue 开发的朋友都知道,它们实际上对应于本 Vue 组件的输入项(Props)。此处暂略,见下文《应用编程接口(所谓 API)》一节。

  3. 一段较完整的示例代码如下:

    <template>
        <page
            class="my-first-page"
            :has-header="true"
            :has-footer="true"
            :header-is-fixed-above="true"
            :footer-is-fixed-below="true"
            :header-should-cover-body="true"
            :footer-should-cover-body="true"
        >
            <template #page-header-content>
                <div class="my-first-page-header-content">
                    <h2>此乃页眉之内容</h2>
                </div>
            </template>
    
            <template #page-footer-content>
                <div class="my-first-page-footer-content">
                    <p>此乃页脚之内容</p>
                </div>
            </template>
    
            <div class="my-first-page-body-content">
                <p>为便于充分展示本组件之多个布局特性,本示例程序<em>有意枉顾美观</em>。见谅。</p>
                <hr>
                <dl>
                    <dt>复旦大学中国研究院院长张维为教授在其所著
                        《中国超越:一个文明型国家的光荣与梦想》
                        中写道:</dt>
                    <dd>
                        <p>中国人的爱国主义
                            是长江、黄河、珠穆朗玛峰;
                            是《诗经》、《楚辞》、先秦散文;
                            是唐诗、宋词、元曲、明清小说;
                            是屈原、岳飞、文天祥、毛泽东;
                            是普通话、四川话、广东粤语、上海方言;
                            是万里长城、北京故宫、桂林山水、陕西兵马俑;
                            是川菜、粤菜、鲁菜、淮扬菜;
                            是西湖龙井、黄山毛峰、武夷岩茶、洞庭碧螺春;
                            是《梅花三弄》、《高山流水》、《二泉映月》、《春江花月夜》;
                            是四合院、广东骑楼、徽派大院、江南民居;
                            是昆剧、京剧、粤剧、黄梅戏;
                            是南昌起义、平型关大捷、台儿庄血战、抗美援朝;
                            是两弹一星、北斗导航、神舟号飞船、高铁八纵八横;
                            是己所不欲,勿施于人;
                            是四海之内皆兄弟;
                            是胸怀祖国,放眼世界等等等等。</p>
                    </dd>
                </dl>
            </div>
        </page>
    </template>
正确配置本组件根元素的祖先元素

为实现诸如【页眉】悬挂于页面顶端的布局设计,本组件的【根 div 】须得知 100% 之高度具体几何。这显然要求 HTML 层级中自 <html> 以来的所有祖先元素均提供准确的 heightmin-height。而本组件有意尝试自动配置这类属性,于是,本组件明确要求,其【根 div】的直接父元素须配备 CSS 类名 .page-container

众所周知,常见的或者说典型的应用情景是:作为“视觉页面”的本组件,其【根 div 】的直接父元素应为 #app。而 #app 的直接父元素为 <body>。针对这种典型配置,本组件确有少量代码直接应对。故诸君唯一要做的是,不厌其烦的为诸君每个项目的 #app 添加一个 CSS 类名——.page-container。即有:

<div id="app" class="page-container">
    <!-- 此处省去实际的代码 -->
</div>

这样的设计看似繁琐,但私以为是必须的。

当然,类似 Nuxtjs 这样的应用平台,会在 #app 之上层额外插入更多的 div。此时,这些额外的祖先 div 显然超出本组件的掌控范围。换句话说,本组件的关于自动确定祖先元素 min-height 之尝试可能恰巧(恰不巧?)失败,无如期效果。于是失败之情形,本组件无可奈何。 但本组件会在浏览器控制台(console)中打印警告信息,以提示诸君须手工做额外的配置。而诸君须做的亦非难事,无非是确保 HTML 层级中自 <html> 以来的所有祖先元素均提供准确的 heightmin-height 仅此而已。


脚本语言(<script>)部分

针对 TypeScript 编程环境的用法示例

注意!采用本 Vue 组件之 TypeScript 版本时,import 语句的 from 须指向 ./source/index.vue

import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
import UIPage from '@wulechuan/vue2-ui--page/source/index.vue'

@Component({
    components: {
        'page': UIPage,
    },
})
export default class MyFirstPage extends Vue {}
针对 JavaScript 编程环境的用法示例

注意!采用本 Vue 组件之 JavaScript 版本时,import 语句的 from 须指向 ./dist/index.vue

import Vue from 'vue'
import UIPage from '@wulechuan/vue2-ui--page/dist/index.vue'

export default {
    components: {
        'page': UIPage,
    },
}

样式(<style>)部分

所谓“关键但不确定”的样式

所谓“关键但不确定”的样式,是指那些运用本组件时必不可少,但本组件却不直接提供,而是要求用户自行确定的样式。 目前,实则仅涉及 3 个数据:

  1. 【页眉】之高度,
  2. 【页脚】之高度,
  3. 【页面主体】之背景色。

以上数据往往因设计稿而异,故本组件不便冒然给出所谓默认值,而是交由采纳本组件之项目自行明确之。

【页眉】与【页脚】之高度

需要格外注意的是,【页眉】之高度和【页脚】之高度是“牵一发而动全身”的。因为本组件在幕后负责自动协调、匹配好多个 HTML 元素的多处尺度。例如,倘若【页眉】覆盖【页面主体】,那么页面主体之最外层元素的 padding-top 应与【页眉】之高度吻合。要确保本组件的这些内部设计运转如期,在项目中对【页眉】、【页脚】之高度配置的 CSS 写法也必须遵照如下规则:

  • 避免直接为 .page-header 设置 height
  • 避免为直接 .page-footer 设置 height
  • 应该.page 上,设置由本组件设计好两个的 CSS 变量:--page-header-height--page-footer-height

简而言之,要用 CSS 变量,而不要直接用 height

以下是错误的做法:

// 直接设置 height 是错误的做法!
.page-header {
    height: 123px;
}

// 直接设置 height 是错误的做法!
.page-footer {
    height: 45px;
}

以下是正确的做法:

// 这是正确的做法。
.my-first-page {
    --page-header-height: 123px;
    --page-footer-height: 45px;
}

诸君如果好奇幕后起作用之代码,可参考下方的源代码片段。完整源代码在 ./source/index.vue样式代码块中,尊请阅读。

.page-header {
    height var(--page-header-height)
}

.page-footer {
    height var(--page-footer-height)
}

.page {
    // 此处省略了很多代码

    &.page-footer-should-cover-page-body {

        &,
        &.page-footer-is-fixed-below {
            padding-bottom 0
        }

        .page-footer {
            margin-top calc(-1 * var(--page-footer-decided-height))
        }

        .page-body {
            padding-bottom       var(--page-footer-decided-height)
        }
    }

    // 此处省略了很多代码
}
【页面主体】之背景色

页面背景色的配置是自由的,诸君直接给出即可。例如:

.my-first-page {
    background-color: white;
}
综合示例

综上,一个较完整的正确示例如下:

.my-first-page {
    // 以正确之方式配置【页眉】、【页脚】之高度。
    --page-header-height: 123px;
    --page-footer-height: 45px;

    // 自由配置页面之背景色。
    background-color: white;
}
锦上添花之样式 1:自由编写

本组件默认不迎合特定的视觉风格或要求,故而默认不包含任何与视觉风格有关的样式规则。诸君可以自由书写锦上添花的样式。

下面是所谓额外样式之示例代码。

.my-first-page {

    .page-header {
        color black
    }

    .page-footer {
        color white
        background-color rgba(black, 0.75)
    }

    .my-first-page-header-content,
    .my-first-page-footer-content {
        height 100%
        display flex
        justify-content center
        align-items center
    }
}
锦上添花之样式 2:本组件自带的额外样式

为多个项目甚至为同一项目的多个页面反复书写额外样式,未免乏味,甚至令人厌烦。于是,本组件亦附带了两种预设好的 .css 文件(共三个),以方便地实现符合本人喜好的样式。诸君若有兴趣,欢迎尝试。

我先逐一介绍这三个 CSS 文件之功用或目的。至于在代码层面如何将这三个 .css 文件用于诸君的 Vue 项目中,令其发挥效用,稍后再于《上述三个额外 CSS 文件的使用方法》一节统一介绍。

第 1 个自带的额外 CSS 文件之功用

第 1 个自带的额外 CSS 文件是./dist/default-shadings.css

该 CSS 达到的目的(或者说提供的效果)其实很简单,归纳起来有两点:

  1. 如果【页眉】被配置为“覆盖于【页面主体】之上层”,则给【页眉】添加流行的“毛玻璃”(一说“亚克力”)视觉效果,如此或许更加美观。【页脚】亦作类同处理。

    幕后的具体做法也很简单:如果浏览器支持 backdrop-filter: blur(1rem),则采用之;否则,不采用。

  2. 给【页眉】和【页脚】设置背景色。

    同样是令【页眉】或【页脚】具有半透明效果,取决于“毛玻璃”视觉效果应用与否,【页眉】或【页脚】的背景色之透明度也大相径庭。具体而言,一旦应用了“毛玻璃”效果,则背景透明度应较高,背景色的 alpha 通道取值不应高于 0.6,往往越低越好,即越透明越好;反之。遵循此原则,可令【页眉】、【页脚】之半透明效果悦目、舒适。

正因为上述琐碎细节,看似简单的“给【页眉】、【页脚】设置半透明背景色和特效”的任务,本组件用到了多达 6 个 css 变量。它们的定义如下:

.page {
    --page-header-backdrop-filter blur(1rem)
    --page-footer-backdrop-filter blur(1rem)

    --page-header-bg-color-with-backdrop-filter    rgba(black, 0)
    --page-header-bg-color-without-backdrop-filter rgba(black, 0)

    --page-footer-bg-color-with-backdrop-filter    rgba(white, 0.79)
    --page-footer-bg-color-without-backdrop-filter rgba(white, 0.79)
}

诚然,你可以故意避免采用这 6 个 CSS 变量,改为直接为 .page-header.page-footer 设置 background-colorbackdrop-filter。而采用上述 6 个 CSS 变量之微弱的好处是,幕后所涉及的 CSS 代码会确保毛玻璃效果仅在有必要时才得到采用,且总是自动据此选用对应的背景色方案。仅此而已。

顺便指出,如果你不喜欢“毛玻璃”效果,或设计师坚持避免采用该类视觉效果,仅需如下代码即可禁用之:

.page {
    --page-header-backdrop-filter: none;
    --page-footer-backdrop-filter: none;
}
第 2 个自带的额外 CSS 文件之功用

第 2 个自带的额外 CSS 文件是./dist/default-extra-measurements.css

该 CSS 文件达到的目的也很简单:

  1. .page-header.page-footer 分别定高。
  2. 为所谓“页面内容块”在水平方向配置统一的 padding,即 padding-leftpadding-right
  3. .page-body-content 配置较美观、实用的垂直方向的 padding,即其 padding-toppadding-bottom

其源代码很短,遂全文抄录于此:

.page {
    --page-header-height 5rem // 默认值而已
    --page-footer-height 3rem // 默认值而已

    // 所谓 page-contents 包括
    //     .page-header、
    //     .page-footer 和
    //     .page-body-content
    // 三者。
    --page-contents-horizontal-padding 2rem
}



.page-header,
.page-footer,
.page-body-content {
    padding-left  var(--page-contents-horizontal-padding, 1rem)
    padding-right var(--page-contents-horizontal-padding, 1rem)
}



.page-body-content {
    padding-top    1rem
    padding-bottom 5rem // 本人在此鼓吹,饱满的 padding-bottom 可改善阅读体验。
}
第 3 个自带的额外 CSS 文件之功用

第 3 个自带的额外 CSS 文件是./dist/default-extra-measurements-for-small-screen.css

该 CSS 文件借助 @import 语句导入了前述 ./dist/default-extra-measurements.css 之内容。换言之,该 CSS 系在前者基础上做额外增补。故而,如果采用该 CSS,则不必采用 ./dist/default-extra-measurements.css简而言之,二者取其一即可。

该 CSS 增补之功能有些古怪,或许仅适合鄙人。具体如下:

  1. 令页面的父容器,即 .page-container 拥有 padding
  2. 同时,令页面本身,即 .page,拥有最大宽度(max-width)。如此,当页面的布局面向较小的浏览器窗口做优化时,一旦令页面在较宽阔的浏览器(例如微软 Windows 平台的浏览器)上呈现时,布局不至于过分丑陋,或完全错乱,而是较好的保持其在窄小浏览器上的布局风貌。
  3. 在浏览器尺寸较大而 .page 本身较窄小时,给 .page 添加了一点微妙的 box-shadow,以期更加美观。
上述三个额外 CSS 文件的使用方法

在了解了上述三个 CSS 文件之目的或作用之后,我介绍一下它们在诸君 Vue 项目中的正确用法。

凡 Vue 项目,均配备 main.jsmain.ts。诸君之 Vue 项目也不例外。为方便指代,不妨暂称其为“main 文件”。欲采用前述三个 CSS 文件之任一,即应在“main 文件”的首部引入此 CSS 文件。见下例:

import '@wulechuan/vue2-ui--page/dist/default-shadings.css'
import '@wulechuan/vue2-ui--page/dist/default-extra-measurements-for-small-screen.css'

import Vue from 'vue'
import App from './app.vue'

Vue.config.productionTip = false

new Vue({
    render: h => h(App),
}).$mount('#app')

须注意,我推荐令导入 css 之 import 语句位于“main 文件”之最顶端。此举可确保这些 CSS 之代码早于.vue 文件中书写的样式被纳入诸君项目最终编译得到的汇总 .css 文件中。


可运转的完整示例项目

本代码库自带的可运转的示例项目:


应用编程接口(所谓 API)

输入项(即 Vue 组件的 Props)

本人自信以下各 Props 之功用均不言自明。另,目前所有输入项之值类型均恰巧为布尔(boolean),且所有输入项之默认值均为 false

小驼峰(camelCase)记法

@Prop() hasHeader?:                                 boolean;
@Prop() hasFooter?:                                 boolean;
@Prop() headerIsFixedAbove?:                        boolean;
@Prop() footerIsFixedBelow?:                        boolean;
@Prop() headerShouldCoverBody?:                     boolean;
@Prop() footerShouldCoverBody?:                     boolean;
@Prop() pageMinHeightShouldFitScreen?:              boolean;
@Prop() shouldDisablePageContainerAncestorWarning?: boolean;

葫芦串(所谓 kebab)记法

<page
    :has-header="true"
    :has-footer="true"
    :header-is-fixed-above="true"
    :footer-is-fixed-below="false"
    :header-should-cover-body="true"
    :footer-should-cover-body="true"
    :page-min-height-should-fit-screen="false"
    :should-disable-page-container-ancestor-warning="false"
></page>

Vue 组件插槽(即 slot

  • 默认插槽,被本组件内建的 div.page-body-content 所包裹,用于接纳页面主体内容。
  • 名为 page-header-content 的插槽,被本组件内建的 div.page-header 所包裹。功能不言自明。
  • 名为 page-footer-content 的插槽,被本组件内建的 div.page-footer 所包裹。功能不言自明。
  • 名为 before-page-body-content 的插槽,被本组件内建的 div.before-page-body-content 所包裹。功能不言自明。
  • 名为 after-page-body-content 的插槽,被本组件内建的 div.after-page-body-content 所包裹。功能不言自明。

必须正确配置的 CSS 类名

注意!不论本组件【根 div 】的直接父元素是否为 #app,诸君总是必须为该直接父元素添加一个 CSS 类名——.page-container 即有:

<div class="page-container">
    <page ...></page>
</div>

层叠样式表自定义变量

必须正确配置的变量

以下 CSS 变量在 HTML 层级中全部源于 .page

  • --page-header-height
  • --page-footer-height

于额外 CSS 文件中设计的 CSS 变量

以下 CSS 变量在 HTML 层级中全部源于 .page

  • --page-header-backdrop-filter
  • --page-footer-backdrop-filter
  • --page-header-bg-color-with-backdrop-filter
  • --page-header-bg-color-without-backdrop-filter
  • --page-footer-bg-color-with-backdrop-filter
  • --page-footer-bg-color-without-backdrop-filter
  • --page-contents-horizontal-padding

未来计划

暂无。


许可证类型

WTFPL

注意:

我未研究过许可证的约束。因此姑且声明为 WTFPL 类型。但实际上该许可证类型可能与我采用的开源模块有冲突。