首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用preact创建页面转换?

如何使用preact创建页面转换?
EN

Stack Overflow用户
提问于 2020-10-17 13:20:41
回答 2查看 833关注 0票数 2

我正在尝试使用preact-router实现页面转换,我已经尝试了preact-transition-group包和preact-css-transition-group包,这给了我一个错误,无论如何,这里是我的基本设置:

代码语言:javascript
复制
import { h, FunctionComponent } from 'preact';
import Router from 'preact-router';

const App: FunctionComponent = () => {
  return (
    <Router>
      <div path="/1" style="padding: 50px">
        page 1 <a href="/2">page 2</a>
      </div>
      <div path="/2" style="padding: 50px">
        page 2 <a href="/1">page 1</a>
      </div>
    </Router>
  );
};

类型记录和/或preact-router解决方案更好,但不是必要的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-22 14:34:02

注意:这种方法可能不适用于嵌套路由。

使用这种方法,您需要使用一个类包装div中的每个路由,该类将激活路由,并将键和路径属性设置为路由的路径,如下所示:

代码语言:javascript
复制
function wrapRoute(route: h.JSX.Element): h.JSX.Element {
  return ( // the in class is the animation and the page class is makes sure that the old and new routes overlap
    <div path={route.props.path} class="in page" key={route.props.path}>
      {route}
    </div>
  );
}

然后需要添加两个反应变量,如下所示:

代码语言:javascript
复制
const [previousEl, setPreviousEl] = useState<ComponentChildren | null>(null);
const [outEl, setOutEl] = useState<JSX.Element | null>(null);

在此之后,您可以侦听preact-routerpreact-router事件,并将outEl设置为一个div,该div封装了previousEl,并有一个类将路由的出口动画化,然后添加一个onAnimationEnd侦听器,以便您可以将out动画完成后的outEl设置为null 1,最后需要将previousEl设置为e.current.props.children时,您的路由器组件侦听器应该如下所示:

代码语言:javascript
复制
<Router onChange={(e) => {
  if (previousEl) {
    setOutEl(
      <div class="out page" key={e.previous} onAnimationEnd={() => setOutEl(null)}>
        {previousEl}
      </div>
    );
  }
  if (e.current) {
    setPreviousEl(e.current.props.children);
  }
}}
>
{routes} // this is an array containing all the wrapped routes.
</Router>

最后一件您需要做的就是创建动画,请看下面的app.sass示例。

以下是完整的示例:

app.tsx

代码语言:javascript
复制
import { h, FunctionComponent, JSX, ComponentChildren, Fragment } from 'preact';
import Router from 'preact-router';
import { useState } from 'preact/hooks';
import './app.sass'

const routes = [
  <div style="padding: 50px; background: red" path="/1">
    page 1 <a href="/2">page 2</a> <a href="/3">page 3</a>
  </div>,
  <div style="padding: 50px; background: blue" path="/2">
    page 2 <a href="/1">page 1</a> <a href="/3">page 3</a>
  </div>,
  <div style="padding: 50px; background: green" path="/3">
    page 2 <a href="/1">page 1</a> <a href="/2">page 2</a>
  </div>,
].map((route) => wrapRoute(route));

function wrapRoute(route: h.JSX.Element): h.JSX.Element {
  return (
    <div path={route.props.path} class="in page" key={route.props.path}>
      {route}
    </div>
  );
}

const App: FunctionComponent = () => {
  const [previousEl, setPreviousEl] = useState<ComponentChildren | null>(null);
  const [outEl, setOutEl] = useState<JSX.Element | null>(null);

  return (
    <Fragment>
      <Router
        onChange={(e) => {
          if (previousEl) {
            setOutEl(
              <div class="out page" key={e.previous} onAnimationEnd={() => setOutEl(null)}>
                {previousEl}
              </div>
            );
          }
          if (e.current) {
            setPreviousEl(e.current.props.children);
          }
        }}
      >
        {routes}
      </Router>
      {outEl}
    </Fragment>
  );
};

export default App;

app.sass

代码语言:javascript
复制
.page
  position: absolute
  top: 0
  bottom: 0
  left: 0
  right: 0

.out
  animation: out 200ms forwards

@keyframes out
  0%
    opacity: 1
    transform: translateX(0)
  100%
    opacity: 0
    transform: translateX(100vw)

.in
  animation: in 200ms forwards

@keyframes in
  0%
    opacity: 0
    transform: translateX(-100vw)
  100%
    opacity: 1
    transform: translateX(0)
票数 1
EN

Stack Overflow用户

发布于 2020-10-22 04:43:25

最好的方法是创建一个动画,就是引入另一个特殊的高级组件来包装您的页面,并将其用作路由器目标。应该是这样的:

代码语言:javascript
复制
import { h, FunctionComponent } from 'preact';
import Router from 'preact-router';

const App: FunctionComponent = () => {
  return (
    <Router>
      <PageAnimation path="/1">
          <div style="padding: 50px">
            page 1 <a href="/2">page 2</a>
          </div>
      </PageAnimation>
      <PageAnimation path="/2">
        <div style="padding: 50px">
          page 2 <a href="/1">page 1</a>
        </div>
      </PageAnimation>
    </Router>
  );
};

您的实现代码将类似于- How to make transition animation

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64402930

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档