阅读:124
基于知识图谱的前后端(vue3+django)分离的问答系统的设计与实现(一):总体介绍
基于知识图谱的前后端(vue3+django)分离的问答系统的设计与实现(二):前端搭建与插件配置
基于知识图谱的前后端(vue+django)分离的问答系统的设计与实现(三):前端开发
接下来进入正题,问答系统的前端开发篇。
本节搭建环境,安装必要的工具和组件,为前端开发打下基础。
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。可以说,一个框架是一个可复用的设计构件,它规定了应用的体系结构,阐明了整个设计、协作构件之间的依赖关系、责任分配和控制流程,表现为一组抽象类以及其实例之间协作的方法,它为构件复用提供了上下文(Context)关系。
通俗来讲,框架好像是别人打好的地基,接入了水电总闸,屋子里很多地方都预留出了空间。我们可以对这个房子进行装修,建游泳池,建厨房,粉刷墙壁,要不要加盖几层,从而把它变成满足自己居住需求的房子。
框架已经完成了一些基础的设计实现了基础的功能,它能帮助我们快速开发项目,使用框架,可以让我们更多地把精力放到业务上面去。
特别是前端框架,是前后端分离后,前端的任务也变得重要起来,web前端开发慢慢趋于规范。
前端要做的核心工作就是:根据用户的操作将相应的数据展示到视图中。
为保证状态与UI同步,前端工作人员除了将精力放在业务逻辑上,还需要将大量的精力放在操作DOM(Document Object Model,简称 DOM)上。 频繁的操作DOM,这样的结果导致了代码臃肿,不易维护,容易出错。前端框架帮助我们减少DOM的操作,方便了开发和维护。目前主流的前端框架angular,react,vue,这三个框架各有优势,今天我们选取的是vue。
什么是渐进式
Vue 是渐进式的 JavaScript 框架,渐进式是指先使用 Vue 核心库,在 Vue 核心库的基础上,根据自己需要再去逐渐增加功能。由于框架做分层设计,可以选择性的使用该 框架的一个或一些组件,使用起来十分灵活方便。
单页面程序
Vue 的开发理念是类似于面向对象思想,将单个网页装配成可复用的组件,每个网页模块属于自己的标记语言、样式语言、脚本语言,用来渲染网页中相应的部分。程序规模越大,样式代码和业务逻辑代码越多使用框架的优势就越明显。
数据驱动
数据驱动视图是 Vue.js 最大的特点。通俗地讲数据驱动就是用户界面的组件已经和数据绑定,数据发生变化的时候,界面就随之改变,不需要程序员再去操作文档对象模型(DOM)。
在传统的 jQuery 中,对于某个元素修改的流程通常是:对某个 HTML 上的组件绑定事件,然后获取这个元素对应的 DOM,然后通过脚本语言对这个元素的 DOM 进行操作。频繁地操作 DOM 会使得代码出错率增加并且难以维护,Vue 框架帮我们封装了数据和 DOM 操作的映射,在开发时我们就可以只关注数据的业务逻辑。
不一定。
代码是为业务服务的,符合业务需求的,才是好的技术栈。
举个简单的例子,如果框架是打好了100层高楼的地基,如果我们想建一个茅草房或者小木屋是不是就用不到框架了?
使用框架,可能有很多用不到的东西是冗余的;会让程序员不再深究代码的底层原理;会让程序员对框架产生依赖;凡是都是有利有弊的,其中滋味还需要各位在代码和项目中去体会。
代码用记事本就可以写,而开发工具,可以帮助我们检查代码规范,而且方便调试,大大提高开发的效率。
Pycharm分为社区版和专业版本,专业版功能更多,插件也更多一点,比如对后端框架django的支持。开发工具pycharm不再作过多的赘述,参考一下网站的进行下载安装。
pycharm的下载和安装
个人还是建议选取专业的pycharm,用起来还是方便许多。
框架的版本是一个大问题,比如python的2.0和python的3.0版本几乎就是两种语法了。
vue的2.x版本被广泛应用,而现在vue cli已经更新到了5.0版本。
不同版本的vue 安装命令都不一样了。vue是从3.x开始有了很大的变化,一些语法发生了改变,比如获取Vue实例的方法变了;初始化的项目不再自带router;还有一些语法可能也略有变化。
Vue中使用的一些第三方组件,例如element UI,也在更新,从原来的element ui 到 element ui plus,连组件demo的语言都变成了ts,变化是非常大的。
所以版本之间的匹配一定要做好,否则很容易出现错误,对初学者非常不友好。
下面进入前端的开发过程,将逐步陈述。
前面我们提到JavaScript是要依靠node.js的运行环境的,所以我们先安装node.js的运行环境。
node.js的下载地址
安装node.js很简答,一路next,这一步可选可不选。
安装完成后,查看是否安装成功。
出现版本号说明已经安装成功。
安装好node.js以后,已经可以使用npm命令。
npm全称是 Node Package Manager 包管理工具,这一点和maven、gradle十分相似,只不过maven、gradle是用来管理java jar包的,而npm是用来管理js的。NPM 的实现思路和maven、gradle是一样的:
也就是说,npm帮助我们下载各种依赖。众所周知,默认代码仓库一般在国外,所以网络差的同学下载比较慢,但是我们可以手动永久改成taobao的镜像地址。
打开cmd,输入以下命令即可。
npm config set registry https://registry.npm.taobao.org
vue cli是一个脚手架,为什么叫脚手架呢,vue cli可以帮助我们构建一个具有主体框架的vue 的项目。
webpack一种模块打包器。通俗点来说,因为对于浏览器来说,它只认识js代码,或者css代码,而Vue框架是有自定义的语法,所以就需要一个工具把它的代码解析成为浏览器认识的js代码。
接下来,全局安装vue cli,打开cmd命令行,输入以下命令。
npm install -g @vue/cli
注意,这是3.0以上版本的vue安装命令,会默认安装最新的版本。3.0以下的是另外一个命令。
安装好以后,可以检查下是否安装成功。
vue --version
出现版本号,说明安装已经成功了。
安装好以后,我们可以用命令行来创建一个vue项目。除此之外,vue提供了一个UI界面,帮助我们创建和管理项目,和项目依赖。我们可以看一下。
打开cmd,命令行运行以下代码,会跳出浏览器。
vue ui
项目管理的UI界面,点击创建。
选择一个目录,然后点击创建。
起个项目名字,点击下一步。
选择Vue3, 用新不用旧嘛。
点击创建项目以后,切换回cmd命令行看进度,此时开始自动下载所需要的包,等待项目建立完成即可。
上图是正在创建项目
创建成功后,刚才的ui界面会到这里。
接下来,我们用pycharm打开项目,来看一下项目结构。之前我们已经安装好了pycharm,我们找到文件的目录,然后右键,以pycharm as project打开。
安装好pycharm的前提下,我们也可以这样点击左上角的项目名字,然后点击在编辑器中打开,此时会打开pycharm。
用pycharm打开的项目结构
既然是用Pycharm工具,启动项目也用IDE。
打开package.json 文件:
这个文件下有三个命令,分别是serve /build /lint,分别对应开始服务/打包成dist(打包以后可以用应用服务器部署)/运行代码格式检查,现在我们运行npm run serve (点击上图中,serve对应的绿色小按钮)来看一下项目是否可以正常启动啦。然后观察pycharm下方的运行结果。
启动正常,第一个对应的是本地ip,第二个对于的是外网ip,而8080就是计算机对外开放服务的端口,外部访问8080端口,就会得到这个网页。如果你的电脑和另外一台电脑是用同一个路由器上网的,另一台电脑可以通过第二个ip访问你的网页。
点击第一个链接。
说明项目启动成功啦,开始写自己的前端代码之前呢,我们先大体介绍一下项目的结构。
项目结构
是安装node后用来存放用包管理工具下载安装的包的文件夹。比如webpack、gulp、grunt这些工具。不好理解的话,我们可以认为,这是别人写好的工具,我们不用管。
接下来可以看到public 文件夹,这是用来存放静态资源的。
我们再看public下面的这index.html(vue项目的入口),其中第十五行,有一句话,files wil l be auto injected,也就是说,生成的文件会被自动注入。
我们可以注意到,这句话的上方,有一个div,它的id是app,而大家都知道,在html里面,id是唯一的,这个app,指的就是下面App.vue文件的内容。
接下来可以看到,src文件夹(资源和源码文件):
3.1 该目录下的assets文件夹,这里面主要存放一些图片,图标等。
3.2 components 存放vue文件。vue文件的本质,里面网页代码。里写操作和方法,而写网页的样式。
3.3. 我们来看一下App.vue:
App.vue便是vue组件入口了。
vue是单页面的程序,通过组合各种div成为一个复杂的页面,所有的div都是写在index.html这一个页面上,我们在运行的时候页面变化,其实是不同的div在调用的时候切换的结果。也就是说,我们写的vue文件,要被App.vue里引用,才可以被加载。
我们刚才启动项目的时候,打开的欢迎界面,就是App.vue引用了,组件下的HelloWorld.vue。
我们上文提到,在index.html(项目入口)里面有个id为app的div,这个App.vue里的div 就是index.html里面id为app的div。
我们写的vue组件,需要被App.vue(组件入口)引用,然后才能被index.html(项目入口)调用。
相当于vue框架的程序入口文件,主要放置项目中经常会用到的插件和CSS样式之类的。例如: 网络请求插件:axios和加载的一些组件库等。
3.0 版本以后,自动生成的目录里没有了router.js,在vue.js里面,路由是一个很关键的概念。我们必须要花大篇幅来说这个东西。
什么是路由
路由是浏览器 URL 中的哈希值( # hash) 与 展示视图内容 之间的对应规则。
路由就是一套映射规则(一对一的对应规则), 由开发人员制定规则。
当 URL 中的哈希值( # hash) 发生改变后,路由会根据制定好的规则, 展示对应的视图内容。
区分(route,routes,router):
route:首先它是个单数,译为路由,即我们可以理解为单个路由或者某一个路由;
routes:它是个复数,表示多个的集合才能为复数;即我们可以理解为多个路由的集合,JS中表示多种不同状态的集合的形式只有数组和对象两种,事实上官方定义routes是一个数组;所以我们记住了,routes表示多个数组的集合;
router:译为路由器,上面都是路由,这个是路由器,我们可以理解为一个容器包含上述两个或者说它是一个管理者,负责管理上述两个;举个常见的场景的例子:当用户在页面上点击按钮的时候,这个时候router就会去routes中去查找route,就是说路由器会去路由集合中找对应的路由。
为什么要学习路由?
路由是什么东西呢,路由是用来控制页面的跳转的,特别是对用户的权限管理中起着重要的角色。在 web App 中, 经常会出现通过一个页面来展示和管理整个应用的功能。我们之前提到,我们的vue框架是一个单页面程序,可以理解为咱们vue组件的切换逻辑。
Vue中的路由
vue 中的路由 : 是 hash 和 component 的对应关系, 一个哈希值对应一个组件。也就是说,一个路径对应着一个对应的vue文件,而显示是谁来做的呢,是下面两个组件。
vue中router两个重要的路由组件。
router-view 主要是在构建单页应用时,渲染指定路由对应的组件,我们上面提到vue是单页面程序,页面的的切换,是用切换不同的vue组件来实现的,router-view就是用来渲染vue组件的,可以理解为一个容易,里面可以装不同的页面。
router-link 组件支持用户在具有路由功能的应用中 (点击) 导航。 通过 to 属性指定目标地址,默认渲染成带有正确链接的“a”标签,不想深入理解的,可以直接理解为a标签。
既然vue cli初始化的时候没给我们生成这个router,那我们只能自己来安装然后使用。
安装vue router。现在我们打开vue ui的界面,选择左侧的插件,然后点击中间上方位置的 添加vue router 。这个工具可以帮我们安装vue router,并且添加好router的配置文件。
添加完router 以后,我们来看项目结构,项目结构已经发生了变化。接下来我们分析下更新好的目录。
分析新的项目结构,看router是如何起作用的。
我们发现vue组件的入口,App.vue已经发生了改变。多出了router文件夹(一个js)文件,还有views文件夹(多了两个vue文件)。
App.vue 本来是一个图标组件和HelloWorld组件,现在变成了一个nav组件,nav组件是导航组件,里面又有了两个router-link链接,分别指向不同的url。
我们重新运行一下项目。
我们可以看到,默认显示的是Home页面,地址栏里的url是localhost:8081/#/,这和router-link里的to的“/”相对应,旁边的显示的是“/about”链接,点击后会显示about页面。
我们可以知道,当在Home界面的时候,上面的url是localhost:8081/#/,点击About,那么url就会变成localhost:8081/about,对应的界面也会切换。
是那么router是如何通过url来找到相对应的组件来显示的呢,我们来分析下。
js文件里,导入路由对象,创建路由实例,定义路由的url和组件直接的映射。
我们来看一下router文件下的js文件具体做了什么。
我们可看到,第一行引入了createRouter,和createWebHashHistory,这属于router组件里的。
第2行引入了HomeView组件,其中HomeView是项目下的vue文件。
第4行开始,定义了一个routes数组,里面包括多个路由,每个路由写了三个基本的属性,分别是路径,也就是url,name(组件的名称),component(对于的vue组件)。这里就把访问路径和vue组件对应起来了,路由就会根据路径加载对应的组件。
注意到的是,第16行这种写法,其实就是第2行和第8行的结合版,随你选择。
第二十五行是固定的写法,就是导出默认路由。
router的js文件是怎么被加载的呢,因为vue项目不会主动去加载这个文件的。
我们之前提到main.js这个程序入口文件,插件组件的加载是在main.js完成的,所以我们看到main.js。
在2.X版本中创建一个vue 实例是通过 new Vue()来实现的,到了3.X中则是通过使用createApp这个 API返回一个应用实例。
然后在main.js里面导入了router文件。
看到上图的最后一行代码,我们可以看到上面先得到了实例,然后.use(相当于加载)了router组件。
到此我们介绍完了router和它的工作机制。
测试一个自定义的route和页面,看看是否可以正常跳转。
在view文件夹下,创建一个名称为TestView.vue的文件,然后在文件里写入,以下的代码。
<template>
<p>我只是一个卑微的测试页面</p>
</template>
然后,我们把这个组件去router文件夹下的index.js文件里去做下配置。我们在第3行添加
import TestView from "@/views/TestView";
然后再第19行添加。
{
path: '/test',
name: 'test',
component: TestView
}
添加完以后的长这个样子。
然后我们去App.vue里第5行添加,
|<router-link to="/test">Test</router-link>
然后我们启动这项目,然后点击test,发现长这个样子。
好的,说明路由是配置成功了。路由可以正常使用了,我们再看下另一个重要的插件。
Vuex 是一个专为 Vue.js 应用程序开发的“状态管理模式”。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
讲人话就是:有几个数据,几个操作,在多个组件上都需要使用,如果每个组件都去调用都是写,就会很麻烦。你可以简单的将其看成把多个组件、界面共享的变量全部存储在一个对象里面。然后,将这个对象放在顶层的Vue实例中,让其他组件可以使用,多个组件就可以共享这个对象中的所有变量属性。这种设计是不是也让你想到了单例模式。
例如,我们的前端登录功能,我们想把登录的用户信息保存到本地,而用户的信息可能要在多个地方使用,这时候就可以用到Vuex了。
可能有人有疑惑了,不能自己封装一个对象来管理吗?当然是可以的。但是我们自己封装的对象,是没用响应式的,还要自己写,很麻烦。
我们继续使用vue ui 的界面来安装Vuex。点击上方 添加vuex按钮即可安装vuex,并且生成配置文件。
我们发现,多了store文件和下面的index.js文件夹。main.js里,也注册了store。
初学者来说,我来通俗地讲一下几个比较核心的概念:
- State。对我们来说,它就用来存储的数据。
- Getters。 获取state中的数据,可以加以包装。比如说我们把用户选择的商品存在购物车里,我们再getter里面,可以选取商品价格大于某个价格的商品.
- Mutations。用于处理state中数据,比如说更新用户的状态,说白了就是,对数据进行修改。
- Action。Mutation中进行异步操作, 比如网络请求, 必然是异步的。
- Module。是模块的意思。为什么在Vuex中我们要使用模块呢?
当应用变得非常复杂时,store对象就有可能变得相当臃肿。为了解决这个问题,Vuex允许我们将store分割成模块(Module),而每个模块拥有自己的state、mutation、action、getters等等。
所谓组件库,就是别人写好的组件样式,你拿来用就可以,这样可以使用前端框架封装的代码帮助工程师快速开发。
学习过前端的同学肯定知道bootstrap,我们一般的使用方法就是引入css和样式,然后在页面使用就可以了。
我们的组件库选用element UI。
之前我们已经介绍了npm包管理工具,那么我们现在可以下载Element UI组件库了。
请注意,vue3以上的element ui 教程一定要进这个链接。
element ui plus
我们看到开发工具的下方,有一个terminal ,就是终端的意思,和我们的命令行是一样的,不同的是,这里直接切到项目的路径下面了,更加方面。我们在安装的时候,一定要保证路径在当前项目下。
npm install element-plus --save
在terminal里面直接输入,以上命令,就安装了element ui。这些插件,都要在main.js里注册才行。
在main.js的代码调整一下,这样还更好看一些。
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
app.use(store)
app.use(router)
app.mount('#app')
这样就完整引入了element ui的样式。想要按需引入的同学,可以看这个链接。(按需引用的话,可以减少打包后的项目体积,提高页面加载效率)
element UI 官方引入方式
整体引入了element UI以后,我们再写的样式就和element ui 一样了。element ui 官网上会有相对应的代码,我们直接复制过来加以改动即可,例如导航栏。我们在element ui 的网站,找到组件,然后点击导航栏,然后查看代码。
这里有一点要注意一下,element ui plus的最新版本的demo变成了 typescript语言,大家不要粘下面的ts代码。
清空HelloWorld.vue文件里的代码,然后我们直接把导航栏的代码粘贴到我们的HelloWorld.vue文件里。
<template>
<el-menu
:default-active="activeIndex2"
class="el-menu-demo"
mode="horizontal"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
@select="handleSelect"
>
<el-menu-item index="1">Processing Center</el-menu-item>
<el-sub-menu index="2">
<template #title>Workspace</template>
<el-menu-item index="2-1">item one</el-menu-item>
<el-menu-item index="2-2">item two</el-menu-item>
<el-menu-item index="2-3">item three</el-menu-item>
<el-sub-menu index="2-4">
<template #title>item four</template>
<el-menu-item index="2-4-1">item one</el-menu-item>
<el-menu-item index="2-4-2">item two</el-menu-item>
<el-menu-item index="2-4-3">item three</el-menu-item>
</el-sub-menu>
</el-sub-menu>
<el-menu-item index="3" disabled>Info</el-menu-item>
<el-menu-item index="4">Orders</el-menu-item>
</el-menu>
</template>
重新运行项目观察
我们看到了样式和element ui 一样,说明Element UI 样式使用成功了
以上三个主要组件已经引入成功。