当前位置: 首页 > 后端技术 > Python

Django+React全栈开发:文章列表

时间:2023-03-26 12:54:22 Python

React现在我们有一个属于文章的API,可以对文章进行增删改查,但是对于我们的网站来说,我们还需要一个用户界面。现在让我们开始探索ReactJS。经常听说有Angular、React、Vue这三个前端框架,但是React的官网是这样介绍自己的:AJavaScriptlibraryforbuildinguserinterfaces是用于构建用户界面的JavaScript库。首先我们需要配置环境来使用React。首先,我们需要安装一个Node.js。我们不需要深入了解Node,只需要知道它可以帮助你在非浏览器环境下运行JS代码即可。官网是node.org,直接下载安装即可。建议Linux用户使用自带的包管理器进行安装。Node自带包管理器npm,有点类似于Python的pip,不过这里我们使用包管理器yarn。按照官网的说明安装好后,打开终端,进入我们的项目目录react_drf,为接下来的工作做准备。从头开始构建React项目涉及很多事情。这时,有一些方便的脚手架可供选择。脚手架可以帮助我们省去很多麻烦的配置。这里首先选择Facebook官方提供的create-react-app。$yarncreatereact-appfrontend使用上面的命令后,你会在react_drf目录下看到一个frontend文件夹:$cdfrontend$yarnstart现在你会看到浏览器跳转到localhost:3000,应该会看到一个页面有一个旋转的React标志,表示你已经安装成功。接下来,浏览前端目录中的文件,但不要进行任何更改。index.js现在让我们看一下frontend/src目录。基本上我们只需要关心这个目录下的内容即可。先看这里的frontend/src/index.js:importReactfrom'react';importReactDOMfrom'react-dom';import'./index.css';importAppfrom'./App';import*asserviceWorkerfrom'./serviceWorker';ReactDOM.render(,document.getElementById('root'));//如果你想让你的应用离线工作并加载更快,您可以在下面将//unregister()更改为register()。请注意,这会带来一些陷阱。//了解有关服务工作者的更多信息:https://bit.ly/CRA-PWAserviceWorker.unregister();我注意到代码中的部分。HTML中好像没有这个标签,为什么JS文件中会有这种类似HTML的东西呢?也许你脑子里已经充满了疑惑,没关系,我们先改一下这段代码:...

helloworld
,...我想,上面的写作应该让你看到你应该修改代码的地方。现在,打开浏览器并查看localhost:3000页面,您应该会看到页面发生变化并显示helloworld。如果您不小心关闭了终端,请记得重新打开它并在前端目录中运行yarnstart。这里我不打算详细介绍React的基础知识。我还没有看到比React官方文档更好的学习资料。即使你觉得自己的英文很烂,官方的中文文档也值得一看。这里我只是粗略的介绍一下接下来要接触的知识点。JSX:如果不合适但容易理解,可以考虑在React中将HTML、CSS、JavaScript混合在一起,将一个原本在HTML中的元素赋值给一个变量,比如constelement=

Hello,world!

;,JS也可以插入JSX中,比如constname='JoshPerez';//使用JS变量constelement=

Hello,{name}

;component:可以简单理解为,React认为UI应该组件化,就像搭积木一样,一个一个搭起来,让一个大页面的工作分解成很多小的组件,方便供多人重用和协作开发。之前看到的就是一个组件。生命周期函数:有一个有趣的类比。将组件比作蚂蚁,它的生命就是从绳子的一端爬到另一端。这条绳子上挂着很多牌,所以它会从头爬到尾。过程中会接触到不同的卡片,这些卡片就是生命周期函数。第一个组件在frontend/src目录下新建一个文件ArticleList.js,顾名思义,这是一个文章列表组件。importReact,{Component}from"react";classArticleListextendsComponent{constructor(props){super(props);现在我们定义一个类组件,它继承自React的Component类,这里我们写它的第一个生命周期函数,也就是构造函数,如果熟悉任何一种面向对象的语言,应该不难理解。构造函数并不是React独有的,而是JavaScript原生的一种写法,但是对于类组件来说,当然也可以算作生命周期的一部分。现在看第二个生命周期函数render:classArticleListextendsComponent{constructor(props){......}render(){return
第一个组件
;}}render函数是类组件中唯一必须实现的函数,组件会根据这个函数的返回值渲染内容。
第一个组件
这里是JSX。如果有多行嵌套,可以用括号括起来:return(
第一条
第二条
);那么如何让这个组件被渲染呢?聪明的你可能看过App.js的代码,我们在ArticleList.js的最后添加一行代码exportdefaultArticleList;同时修改index.js:importReactfrom'react';…//原来引入App的那一行可以删掉.....现在运行yarnstart你应该看到浏览器启动并显示你在渲染函数中返回的内容。当然,其实如果你之前没有停止过终端的运行,那么就不需要重新运行yarnstart了。如果更改了代码,它会自动重新渲染,并且不会提示以后如何查看我们的结果。接下来开始实现文章列表接口,先不要急于从API获取文章数据。我们先模拟文章数据:constarticleList=[{"id":2,"title":"React","body":"Reactisgood","created":"2020-03-21T21:19:31.732703","updated":"2020-03-21T21:19:31.732728"},{"id":1,"title":"React","body":"React很好","created":"2020-03-21T21:10:53.922033","updated":"2020-03-21T21:10:53.922128"}];classArticleListextendsComponent{constructor(props){super(props);this.state={articleList:articleList,}}......}注意这里添加了一个articleList列表,构造函数中多了一个this.state,为其设置articleList属性。现在修改渲染函数:render(){return({this.state.articleList.map(item=>

{item.title}

{item.body}
创建:{item.created}更新:{item.updated}/em>

)}
);}现在简单解释一下上面的代码,首先我们看到最外层的div标签,它有一个className属性,其实就是HTML的class属性的原因也很简单。JSX允许JS和HTML混在一起,但是在很多编程语言中(包括JS),class是用来创建类的关键字,所以改个名字方便区分。然后我们看到了如何在JSX中使用JavaScript。我们在花括号和箭头函数中使用了map方法,使不同的标签包含文章标题、正文等内容。注意包含行,如果您使用了yarnstart命令,您将在浏览器中看到一个简单的文章列表,如果您删除此key={item.id},在浏览器中按F12,您将在控制台中看到一条警告消息。简而言之,请记住React需要这样的列表元素,并且必须有一个唯一的键标识符以允许React识别哪些元素已被更改。在后台的真实数据中,id字段是主键,也就是唯一,刚好可以用。使用API。我们用假数据试过了。前面说过,前后端分离的一个好处就是,前后端在接口上达成一致后,就可以分开并行开发了。本质上,会有一些工具来帮助生成“假API”或者假前端请求来帮助测试,有兴趣的可以搜索一下。当然,我们是来学习的,也只有我们自己开发,所以现在就尝试使用真正的API吧。在同源策略正式开始之前,我们需要了解一下浏览器的同源策略。想象一下,如果你在a.com登录浏览了一会儿,然后去b.com浏览,结果是b.com直接拿到你在a.com的cookie,用来登录你的a.com的帐户,这非常可怕,尤其是当a.com是银行或购物网站时。基于此,浏览器使用同源策略作为基本的安全保障。简单来说,只要域名、端口、协议其中一项不同,就会限制访问:Cookie、LocalStorage、IndexDB都无法读取。无法获取DOM。无法发送AJAX请求。我们可以简单地尝试一下并修改ArticleList.js:>response.json()).then(result=>this.setState({articleList:result})).catch(e=>e);}......这里我们看到了一个新的生命周期函数,componentDidMount会在render之后执行。这里调用了原来的fetch函数,简单粗暴的直接请求API。在浏览器中按F12,会看到如下错误:虽然域名(IP)和协议一样,但是端口号不一样,而且Django后台在8000,React在3000,所以报错.这里有一个解决方案,可以在开发过程中使用,帮助我们解决这个问题。当然,这在实际部署时是做不到的。部署时的具体情况将在后面讨论。这里我们先找到frontend/package.json这个文件,在里面添加一行:{......,"proxy":"http://127.0.0.1:8000"}省略号代表前面的内容。如果你在文件末尾插入它,不要忘记在前面的逗号前加一个。然后修改源码:componentDidMount(){fetch('/articles/')......}让开发服务器识别你的请求并代理到http://127.0.0.1:8000那就是Django服务所在的地址。现在再次运行yarnstart,就可以在浏览器中看到你在后台添加的数据了。结束语这次就到此为止,下一章会讲优化这段代码的细节。本章有很多React基础知识没有讲解。如果读者对React还不是很了解,建议现在就去React官网看看,至少把基础教程看一遍。欢迎关注我的公众号《公子正的日常》,原创技术文章第一时间推送。