资讯专栏INFORMATION COLUMN

【译】一个小时搭建一个全栈Web应用框架(下)——美化与功能

Cheng_Gang / 661人阅读

摘要:点击直达前文译一个小时搭建一个全栈应用框架上如果没有,但还是要继续学习本教程,可以到我的页面下载代码。从服务器返回随机语言的每当我们与服务器上的端点进行通话时,为了能够请求一个随机的欧洲语言,必须更改文件中的功能。

翻译:疯狂的技术宅
原文标题:Creating a full-stack web application with Python, NPM, Webpack and React — Beauty and Functionality
原文链接:https://codeburst.io/creating...
本文首发微信公众号:充实的脑洞。转载需注明出处!

如果你遵循前面的教程中的步骤,现在应该有了一个可以工作的全栈Web应用程序框架。

点击直达前文 >> 【译】一个小时搭建一个全栈Web应用框架(上)

如果没有,但还是要继续学习本教程,可以到我的GitHub页面下载代码。

对于下一个魔术,我们将把一个显示“Hello World!”的简单静态页面转换成一个漂亮的单页面WEB应用。 这个页面能够与后端通信,并且在收到新信息时立即更新,而无需用户刷新页面。我们即将创建的页面,在每次点击按钮时,会以随机的欧洲语言返回“Hello”。

这是我们的页面:

为了能够实现这一点,我们需要先弄清楚以下的问题:

每次调用 /hello 端点时,如何返回一个随机的欧洲语言“Hello”。

如何从服务器请求信息。

如何将返回的信息无缝显示给用户,从而无需刷新页面。

如何在页面上添加样式,可以在页面上创建一个大的居中的按钮并添加文本。

最后,我们必须搞清楚应该如何添加一个背景图像。

从服务器返回随机语言的“Hello”

每当我们与服务器上的 /hello 端点进行通话时,为了能够请求一个随机的欧洲语言“Hello”,必须更改 server/server.py 文件中的功能。每次调用它时,都不会返回静态的“Hello World”,而是从“Hello”列表中选择一个随机语言的“Hello”。为了实现这个功能,需要进行以下更改:

import random
def get_hello():
  greeting_list = [‘Ciao’, ‘Hei’, ‘Salut’, ‘Hola’, ‘Hallo’, ‘Hej’]
  return random.choice(greeting_list)

这个函数定义了一个欧洲语言的“hello”列表, 然后我们调用这个函数时,使用 random.choice()从列表中随机选择一个项目。

修改 hello() 函数,以便在每次调用它时返回get_hello()

@app.route("/hello")
def hello():
  return get_hello()

修改 /hello 以返回我们感兴趣的信息,我们现在需要弄清楚如何从前端得到这些信息。

组件化的重要性 - 在 React 中创建一个Hello类

把问题分解被认为是良好的编程习惯。 只要有可能,你应该尽量使自己的函数只做一件事情,并且做好。这点同样适用于类。你可以考虑将每个函数或类都作为多带带的组件。

React是为组件化而设计的。这意味着它是用多个较小的部分来构建你的网站的。就像玩乐高一样,可以轻松地将一个组件替换成另外一个,也可以复用组件,这也能帮助其他开发人员了解你的代码。我们应该努力的编写可理解的代码,因为这样可以使我们的程序更容易维护和扩展。

考虑到组件化,我们创建一个 Hello 类来处理我们网页上的问候语。该类将从服务器上的 /hello 端点点获取一个 “Hello” ,并将其显示给用户。 它也应该有一个“name”参数,这样就可以向某个具体的人进行问候。

通过更改 React App 类中的render函数,使其调用Hello类,我们就可以很快的完成功能,而不是使用旧的代码。传递名称“Rimini”作为参数。出于结构化的目的,我们将把Hello类放在一个 PageHeader 中。

创建Hello类

前面我们修改了 App 类使其能够调用 hello 类, 接下来需要创建 Hello 类。在 js/ 目录下创建一个名为 hello.jsx 的文件, 在此文件中定义一个名为 hello 的类。

export default class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {greeting: "Hello " + this.props.name};
    // This binding is necessary to make `this` work in the callback    
    this.getPythonHello = this.getPythonHello.bind(this);
  }
}
组件与道具

在这一点上,你可能对构造函数中发生了什么有很多疑问。

在 React 中有一种叫做组件和道具的东西。 Props是创建时传递给构造函数的不可变参数。 道具是公开的,修改他们将违反 React 的基本使用原则。状态是内部的,可变的。每次更新状态时,都会在UI中重新展现。如果希望更深入地了解其运作方式,我强烈建议你阅读React文档中有关生命周期和状态的部分。

我们将在Hello类中添加一个名为personaliseGreeting() 的函数。 当我们点击按钮获得一个新的问候语时,它将会处理网页上的问候语的更新操作。 请注意,我们使用this.setState()与名为“greeting”的key。你必须使用这个语法才能让 React 自动刷新网页上的“greeting”状态。

personaliseGreeting(greeting) {
  this.setState({greeting: greeting + " " + this.props.name + "!"});
}
渲染问候语

为了让问候语出现在页面上,必须在render函数中调用“{this.state.greeting}”。我们还必须添加一个带有回调函数的按钮,这个函数叫做getPythonHello(),我们很快就会实现它。这个函数在调用使用Python编写的后端时,将会得到一个新的“Hello”。

render () {
  return (
    

{this.state.greeting}


) }

请注意,我已经将标题和按钮HTML内嵌到了我的代码中,所以可以很轻松地控制他们在页面上的最终位置。

绑定“this”

因为JavaScript中的类方法没有做默认绑定,所以当我们想在函数回调中使用“this”时,就必须在构造函数中创建一个绑定。否则“this”将会是 undefined 的。 这适用于在 JavaScript 中调用without() 的情况。一个典型的例子就是 render() 中的 “onClick = {this.getPythonHello}”

从服务器请求信息

React 没有提供执行HTTP请求的内置方式。为了能够从服务器请求信息,我们将不得不找一个可以做这件事的库。 一个最简单的方法就是引入 jQuery 库。jQuery 是一个 javascript 库,通过在$符号后面提供缩写函数来简化标准的 JavaScript 功能。

首先安装jQuery依赖关系:

$ npm i jquery --save-dev

将 jQuery 依赖添加到要使用的 React 文件中,也就是 Hello.jsx 中。应该将此依赖添加到 Hello 类的定义前面。

var $ = require(‘jquery’);

将查询依赖添加到React文件中意味着可以在自己的React代码中使用标准的 jQuery 函数,只要它们以我们刚刚定义的“$”变量开始。下面让我们用它来从服务器获取一个“Hello”。

我们将使用 HTTP 协议的 GET 请求获取信息。GET 实质上是HTTP请求的“只读”模式。可以用来获取信息,但是不能要求服务器更改它。

在 hello.jsx 文件中的Hello类中添加以下函数:

getPythonHello() {
  $.get(window.location.href + "hello", (data) => {  
    console.log(data);
    this.personaliseGreeting(data);
  });
}

此函数通过jQuery 的 GET请求,连接 /hello 端点。然后得到从服务器返回的一个欧洲语言的“hello”信息,再它打印到浏览器的开发控制台,最后将它传递给Hello类中的另一个函数,调用 personaliseGreeting()

当 rebuild 前端代码(npm run watch),并重新启动 python 服务器后。 应该能看到以下内容:

有一行问候语,一个按钮,点击按钮可以更改问候语。 这个页面看起来很不错,因为我们在index.html中包含了Bootstrap样式。

使用CSS样式美化页面

我们终于有了一个能够与用户交互的产品。如果我们愿意,就可以到此为止了,并对自己说:我对这些成就感到满意。不过就我个人而言,我更喜欢在我的Web应用中添加一些设计元素,让他们变得更加漂亮。所以,我们将用CSS使标题能够覆盖整个屏幕,而不是在页面的顶部。CSS是为HTML设计的一种样式语言,它的作用相当于在Word文档中更改字体大小,样式和位置。

使 Webpack 能够处理 CSS

为了能够在我们的WEB应用中使用CSS,必须安装一些加载器和插件,并将它们添加到Webpack配置文件中。这是因为 Webpack 默认只能处理JavaScript。

安装下列插件:

css-loader

style-loader

extract-text-webpack-plugin

css-loader 和 style-loader 能够使 Webpack 处理 CSS。 通过添加这些加载器,Webpack 将能够将我们需要的任何 CSS 绑定到 bundle.js 中。 不过在这里存在一个问题,JavaScript 和 CSS 将不会在你的页面上多带带进行加载,这可能导致 UI 组件在 JavaScript 加载之前无法显示。这点很差劲,因为在糟糕的网络上,我们辛辛苦苦设计出来的页面可能会加载的非常缓慢。

不过可以通过添加 extract-text-webpack-plugin 来解决这个问题。 这个插件能够将 CSS 分解成一个多带带的包,我们可以把它附加到 HTML 上。 这样就可以使 CSS 再次独立于 JavaScript 进行加载。

在你的webpack.config.js文件的 modules.rules 部分添加下面的CSS规则:

{
  test: /.css$/,
  use: ExtractTextPlugin.extract({
         fallback: "style-loader",
         use: "css-loader",
       })
},

将ExtractTextPlugin插件添加到 webpack.config.js(如果您感到困惑,请查看我的 webpack 文件)。注意,在创建时,需要将捆绑的CSS文件名传给此插件。我们将调用文件"styles.css"。

plugins: [  new ExtractTextPlugin("styles.css") ]

最后,我们需要将 styles.css 包添加到index.html中,以确保样式被加载。将以下行添加到你的index.html文件中的 head 部分(可以参考我的代码):

添加CSS规则

现在可以确保我们的设置可以正确处理CSS了,我们将在css文件夹中创建一个名为fullstack.css 的文件。我已经添加了几个不同的规则,以确保文本和按钮出现在正确的位置,并且文本是大号的细体。

这是我的 fullstack.css 文件中的一个规则。 它使 “Hello Rimini” 文本变得越来越细:

.header-contents h1 { 
    font-size: 120px; 
    font-weight: 300;
}

在创建 fullstack.css 文件之后,我们需要将它添加到使用规则的 React 组件中,这样它们才能生效。由于标题在 App.jsx 中定义,所以需要添加以下代码:

require("../css/fullstack.css");

fullstack.css 文件中的标题样式现在将由 Webpack 拾取,并绑定到 styles.css 文件中。当我们刷新页面时,应该如下图所示。注意,如果你用的浏览器不是 Chrome 的话,字体可能和图中不一样:

被CSS装饰后的页面

完成 - 添加背景图

Webpack 本身并不理解图像的概念。因此,我们还需要添加一个可以在Web应用程序中使用它们的加载程序。我们需要安装名为“file-loader”的loader。

安装 file-loader:

$ npm i file-loader --save-dev

将file-loader规则添加到 webpack.config.js 文件中的modules.rules部分:

{
  test: /.(png|svg|jpg|gif)$/,
  use: "file-loader"
}

将要使用的图像添加到images/ folder。将其命名为“header.jpg”。

为了能够使图像成为网页头部的背景,我们需要将其作为背景图像添加到 fullstack.css 文件的页眉部分。

.page-header {
  background-image: url("../images/header.jpg");
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}

接下来要做的是把图像加载到使用它的 React 文件中。如果没有在 React 中显式加载图片,Webpack 将不会棒的它,也不会把它显示在页面上。这种行为不是很直观,在我第一次在自己的应用中添加一个背景图像时,曾经犯过这个错误。

在App.jsx中进行如下更改:

import HeaderBackgroundImage from "../images/header.jpg";

将此函数添加到你的App类:

addHeaderImg() {
  let headerBg = new Image();
  headerBg.src = HeaderBackgroundImage;
}

这个函数创建了一个新的Image对象,并将源设置为你的标题图片。

我们需要做的最后一件事是,确保在渲染页面时加载图像。 这意味着我们必须在render()函数中调用 addHeaderImg()函数。

将下列代码添加到render()函数中:

{this.addHeaderImg()}

刷新浏览器窗口时,应该看到以下内容:

恭喜你!你已成功创建了一个全栈 Web 应用程序!

关注微信公众号:充实的脑洞, 一个技术宅的保留地

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/40800.html

相关文章

  • 一个小时搭建一个全栈Web应用框架)——美化功能

    摘要:点击直达前文译一个小时搭建一个全栈应用框架上如果没有,但还是要继续学习本教程,可以到我的页面下载代码。从服务器返回随机语言的每当我们与服务器上的端点进行通话时,为了能够请求一个随机的欧洲语言,必须更改文件中的功能。 翻译:疯狂的技术宅原文标题:Creating a full-stack web application with Python, NPM, Webpack and Reac...

    Luosunce 评论0 收藏0
  • 一个小时搭建一个全栈Web应用框架(上)

    摘要:初始项目设置我们将使用包管理器来处理依赖项。使用包管理器可以使您的项目依赖项保持最新状态,并能够获取和安装最新的包。是小型应用的最佳选择之一。 翻译:疯狂的技术宅英文标题:Creating a full-stack web application with Python, NPM, Webpack and React英文原文:https://codeburst.io/creating....

    wizChen 评论0 收藏0
  • 一个小时搭建一个全栈Web应用框架(上)

    摘要:初始项目设置我们将使用包管理器来处理依赖项。使用包管理器可以使您的项目依赖项保持最新状态,并能够获取和安装最新的包。是小型应用的最佳选择之一。 翻译:疯狂的技术宅英文标题:Creating a full-stack web application with Python, NPM, Webpack and React英文原文:https://codeburst.io/creating....

    Doyle 评论0 收藏0
  • 前端相关大杂烩

    摘要:希望帮助更多的前端爱好者学习。前端开发者指南作者科迪林黎,由前端大师倾情赞助。翻译最佳实践译者张捷沪江前端开发工程师当你问起有关与时,老司机们首先就会告诉你其实是个没有网络请求功能的库。 前端基础面试题(JS部分) 前端基础面试题(JS部分) 学习 React.js 比你想象的要简单 原文地址:Learning React.js is easier than you think 原文作...

    fuyi501 评论0 收藏0
  • 2017-08-18 前端日报

    2017-08-18 前端日报 精选 [译] 关于 React Router 4 的一切腾讯祭出大招VasSonic,让你的H5页面首屏秒开用简单的方法学习ECMAScript 6【译】一个小时搭建一个全栈Web应用框架你应该知道的Debug技巧Understanding V8’s Bytecode – DailyJS – MediumAnnouncing TypeScript 2.5 RC 中文...

    AZmake 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<