07-login-case

183 阅读3分钟

场景:

image.png

实现组件切换

image.png

实现:

定义初始数据:

isLogin=false,即默认没有登陆;当点击按钮时将isLogin设置为true。用来切换函数组件。

 state = { isLogin: false }  //false 未登录
  return (
                    <div>
                      <div>123<div/>
                    </div>
         )

书写函数组件:

两个函数组件:登录与欢迎。对应login与Welcome

 function Login() {
            return (
                <div>
                    <h1>请先登录</h1>
                    <button>登录</button>
                </div>
            )
}

function Welcome() {
            return (
                <div>
                    <h1>欢迎,您已登录</h1>
                    <button >退出</button>
                </div>
            )
}

于是可以将render的页面修改为:

  return (
                    <div>
                     <Login/> //默认为登陆页面
                    </div>
         )

使用isLogin实现组件切换,首先定义两个函数修改isLogin状态。

handleLogin = async () => {
                this.setState({ isLogin: true })
            }

handleLogout = async () => {
                this.setState({ isLogin: false })
            }

然后将修改状态的true,false的两个函数分别传入到函数组件中

  return (
<div>
{
this.state.isLogin ? <Welcome logout={this.handleLogout} /> : <Login login={this.handleLogin} />
}
</div>
)

在两个函数组件中通过props实现点击后切换组件

 function Login(props) {
             const {login} = props
            return (
                <div>
                    <h1>请先登录</h1>
                    <button onClick={login}>登录</button>
                </div>
            )
}

function Welcome(props) {
            const {logout} = props
            return (
                <div>
                    <h1>欢迎,您已登录</h1>
                    <button onClick={logout}>退出</button>
                </div>
            )
}

完成。

大致流程总结:

分析:状态 页面 事件

        定义状态(state)

        定义页面 (两个函数组件)

        状态和页面关系 (true,false分别对应两个组件)

        定义改变状态事件  (状态在哪 定义事件就在哪里,点击切换true/false的两个方法)

        button 和 事件关系(组件实例上定义)  事件传递(props)

就是这样。


增加功能,登陆后显示简单的标题,

显示,如下:

image.png

image.png

两个页面通过点击按钮自由交换。

开始编写:

首先写好标题内容的数据存放在数组中,当页面渲染完之后调用,放于钩子函数中。

   state = { isLogin: false, posts: [] }  //未登录,初始数据为空

在函数组件中传入post的初始数据:

<Welcome logout={this.handleLogout} posts={this.state.posts} /> 

当render完之后自动调用钩子函数,改变posts的状态内容。

  componentDidMount() {
                //获取文章数据
                const posts = [{
                    id: 1, title: 'title1', content: 'welcome to habin heilongjiang'
                }, {
                    id: 2, title: 'title2', content: 'welcome to habin heilongjiang'
                }, {
                    id: 3, title: 'title2', content: 'welcome to habin heilongjiang'
                }]
                //同步组件状态👇
                this.setState({ posts: posts })

            }

写好文章内容的函数组件:

function Posts() {
            return (
                <div>
                   内容
                </div>
            )
        }

将post组件放置欢迎页面中一同显示:并将post数据传给Post函数组件方便调用

  function Welcome(props) {
            const { logout, posts } = props
            return (
                <div>
                    <h1>欢迎,您已登录</h1>
                    <button onClick={logout}>退出</button>

                    {/*文章内容列表*/}
                    <Posts posts={posts} />
                </div>
            )
        }

现在已经接收到post数据了,于是可以开始排版Post函数组件了。通过props接收到post数组。

将内容又分为:左侧边栏sidbar组件与中间正文content组件。先利用数组中的map遍历出每一项内容

function Posts(props) {
            const {posts} = props
              const contents = posts.map(item => {
              return (
                    <Content key={item.id} title={item.title} content={item.content} />
                )
            })
             const sidbar = <ListContainer data={posts} />
            return (
                <div>
                    <div>{sidbar}</div>
                    <div>{contents}</div>
                </div>
            )
        }

已经遍历出数据,下一步将数据通过props在函数组件中使用。

 function Content(props) {
            const { title, content } = props
            return (
                <div >
                    <h3>{title}</h3>
                    <span>{content}</span>
                </div>
            )
        }

内容组件书写完毕👆。

下面书写左侧边栏组件。

 function ListContainer(props) {
            let { data } = props
             let listItems = data.map(item=><li key={item.id}><span>{item.title}</span></li>) // jsx => {变量}
            return (
                <ul>
                    {listItems}
                </ul>
            )
        }

观察上面代码,在第三行的索引key被放置在li中,是会报错的,以为li本身就是单独的一小只,加上key是多此一举,例如将每个li再次封装成一个组件。

解决方法:将几个li再次封装成函数组件,通过map遍历数组得到每一条数据,实现显示,实现在组件中添加key。

于是更改为:

 function ListContainer(props) {
            let { data } = props
            let listItems = data.map(item => <Title key={item.id} title={item.title} />) // jsx => {变量}
            return (
                <ul>
                    {listItems}
                </ul>
            )
        }

Title组件用li去接收遍历数组得到的每一条数据。

 function Title(props) {
            const { title, id } = props
            return (
                <li ><span>{title}</span></li>
            )
        }

以上:完成一个简易的登录、退出,以及显示数据的过程。

知识点涉及:

我认为该案例只是在反复的巩固如何书写jsx语法,如何让抽离出函数组件,如何让在类组件中写状态值,并且修改状态值,以及如何通过props去传递数据 进而接收数据的过程。是前几篇文章知识点的综合。

额外的知识点只是以前学过的数组中map方法,遍历得到每一条item内容。

今天的自己真棒。