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

vue-starport

v0.4.0

Published

Shared Vue component across routes with animations

Downloads

1,790

Readme

Note:随着 View Transitions API 的到来,你可能不再需要这个库了(尽管它不是完全的替代品,因为 View Transition 不会保留 DOM 和状态)。

由来

我们经常会在在不同的路由(页面)上使用统一组件,但他们的位置和大小可以不尽相同。这时你可能会希望在用户进行路由跳转时,想让它们展示流畅的过渡动画。尽管这样的动画在原生应用中较为常见,但要在 Web 中实现却有一些挑战。

Vue 的组件结构以 的形式呈现,在不同分支中的子组件有其各自的实例,这意味着当用户在路由之间跳转时,同样的组件并不会跨路由共享。

因为它们是两个不同的实例,这意味着你无法直接为它们的添加补间动画。幸运的是,有一种叫做 FLIP 的技术可以模拟不同组件之间的过渡动画。

然而,FLIP 只解决了过渡的问题,我们仍然还是会有两个组件实例。在跳转过程中,组件的内部状态将会丢失。

因此,我开始实验一个新的解决方案用于满足这一需求,并将其取名为 Starport

解决方案

既然我们无法在组件树的不同分支之间共享组件,我们其实上可以将组件提升到根节点上,从而它们独立于路由而存在。

为了让每个页面仍然可以控制组件,我们引入了一个 代理组件 来表示该组件的预期大小和位置。代理组件将把 props 和位置信息传递给真实的组件,并让它通过补间动画 “飞” 到代理组件的位置。

当动画结束并且它到达预期位置时,它将使用 <Teleport/> 组件来 “着陆” 到 DOM 树的实际节点。

有了这种 “着陆” 的机制,DOM 树将保留原始的结构。当跳转到另一路由时,组件又将 “起飞” 变回漂浮的状态,“飞行” 到新的位置,然后再次 “着陆”。

这与星际争霸中的人族建筑非常相似(能够离开地面飞往新地点),它也是项目名称Starport的灵感来源。

安装

⚗️ 实验性

npm i vue-starport

Vue Starport 仅支持 Vue 3

使用

vue-starport 导出并添加 <StarportCarrier> 组件到根组件 (app.vue)。 所有的 <Starport> 组件调用需要在 <StarportCarrier> 组件内部。

<script setup>
  import { StarportCarrier } from "vue-starport";
</script>

<template>
  <StarportCarrier> <!-- 这里 -->
    <RouterView />
  </StarportCarrier>
</template>

在路由中,使用 <Starport> 来包装组件。

<!-- PageA.vue -->
<script setup>
  import { Starport } from "vue-starport"
</script>

<template>
  <div>
    <!-- ... -->
    <Starport port="my-id" style="height:400px">
      <MyComponent :prop="value" />
    </Starport>
  </div>
</template>

在另一个路由上,我们使用 相同的 port ID 让 Starport 得以进行匹配。

<!-- PageB.vue -->
<script setup>
  import { Starport } from "vue-starport";
</script>

<template>
  <div>
    <!-- ... -->
    <Starport port="my-id" style="height:600px">
      <MyComponent :prop="value" />
    </Starport>
  </div>
</template>

请注意,你可能需要对 <Starport> 添加一些样式,使其在没有内容时也能拥有的大小从而指示着陆的区域。

查看 Playground 以获取更多示例。

全局组件注册

// main.ts
import StarportPlugin from 'vue-starport'

app.use(StarportPlugin())

然后你可以在不导入的情况下使用 <Starport><StarportCarrier> 组件。

组件持久化

默认情况下,当跳转到没有相应 <Starport> 代理着陆的页面时,组件将被销毁。如果你想在组件没有出现在当前路由中时仍然保留组件的状态,你也可以将该实例的 keepAlive 设置为 true

<Starport keep-alive port="my-id">
  <MyComponent />
</Starport>

要全局配置它,你可以在插件中设置:

// main.ts
import StarportPlugin from 'vue-starport'

app.use(StarportPlugin({ keepAlive: true }))

调试

要调试过渡动画,你可以添加以下 CSS 来突出显示部件

[data-starport-craft] {
  background: #0805;
}
[data-starport-proxy]:not([data-starport-landed]) {
  background: #8005;
}

鸣谢

感谢 @hangsman,他帮助提供了使用 <Teleport> 的最初解决方案,从而让这个想法得以实装。也感谢 我在 Bilibili 的直播观众,与我一起研究这个想法并在直播期间提供了许多宝贵的反馈。

你可以在哔哩哔哩观看我实现此项目的 直播录像

赞助者

License

MIT License © 2022 Anthony Fu