0. 目标读者
本教程适合读者是有一定成熟的后端开发经验,对后端了解较为清晰。但是不熟悉前端开发的初等,中等水平后端开发者。由于目标用户是Linux后端开发者,所以使用的多为shell指令,但实际上windows下只是换成cmd输入相同的指令即可,大体上逻辑一致。
本文会以能够简单的开始写为目的介绍,背后逻辑和机理只会解释到能动手开发为主,底层技术不会涉及我才不会告诉你我也没研究。
本文会涉及HTML,CSS,JavaScript。但都不会讲的特别深,都按照能入手开发为目的进行讲解。
0.1 预备知识:Html 结构
Html 本质和 markdown 等语法类似,目的是为了用一套格式化的语法来达到呈现图形的效果。与 XML,JSON 等主要是为了展示数据结构或者为了持久化的目的不同,HTML 本质是为了呈现数据的,这是一个用以显示为目的的语言。HTML 的实现中使用了 XML 的思想,但对其进行了扩充和特例化。
如同 MarkDown 中 #
##
表示的一级二级标题一样, html 中只是用<h1></h1>
<h2></h2>
等来表示标题而已,
这里引用一句别的博客的话:
HTML 是网页的结构,就比如工人盖房子一样,首先要用砖把房子的结构搭建起来,有了房子结构才能在其基础上再进行其他作业,HTML 就类似于房子的大框架结构。HTML 有很多标签组成,不同的标签语义不同,所有的标签内容组合在一起就构成了网页的结构内容。HTML 中写了什么内容被浏览器渲染后网页中就有什么内容,这些内容是原生态的无任何修饰。只有当网页中有了这些原生态的内容后才可以在其基础上添加样式进行修饰,让网页变得更美观,用户体验更好。所以 HTML 就如同整个网页的灵魂,不可或缺。
Html 使用 xml 的方式来表示数据结构,常见的 html 中的元素如下图所示:
0.2 Vue做了什么
先放一段官网的话:
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
实际上更简单的理解是,框架通过实时变化HTML文件中的每一个组件,达到渐进式的效果。也就是实际上从始至终一般都是一个HTML文件,框架不停的修改这个文件里面的HTML文件节点和文件的属性和值。这种应用在前端属于里叫单页Web应用SPA, single page web application
。目前主流的风格是做这样的网页。
1. 环境搭建
nodejs简介
1、node 是一个基于 V8 引擎的 Javascript 运行环境,它使得 Javascript 可以运行在服务端,直接与操作系统进行交互,与文件控制、
网络交互、进程控制等。简单的说node.js就是运行在服务端的 JavaScript。
2、node.js是一个基于Chrome JavaScript运行时建立的一个平台。
3、node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
1.1 下载node
公司内部有加速镜像:
这个文件直接就是一个配置好PATH就能用的安装包:node-v14.19.0-linux-x64.tar.xz
解压到自己喜欢的路径,然后把压缩包里面的bin文件设置成PATH环境变量,就可以开始愉快的前端之旅了。Node这个引擎不光仅仅只有环境,和Python类似,除了环境以外,另一个很大的特色就是这里面有自己的“市场”。类似于Python的pip。
1.2 设置好环境变量
一样的,npm要使用很多开源组件,这些组件都在一个公用的市场里。类似于python的pip。这里也需要配置一下源。主要的目的是为了让公司内部可以访问node的市场,有别于Python,node的市场对于整个程序编译来说更加重要。可以理解为如果没有市场,那么一切就运行不起来。
vim ~/.npmrc
输入如下变量:
registry=https://registry.npmmirror.com/
以下,开始可以真真真真的开始建立项目了。
2. 新建一个项目
2.1 各种插件装起来
node只是提供了一种编译环境,而实际上各种前端代码需要对应的插件才能运行起来,那么开始装了。这里就来vue吧。这里提示一下,-g表示全局安装
,这里提示一下,如果想偷懒可以把install
写成i
。
npm install vue -g #这个是vue本身
npm install @vue/cli -g #这个是vue的脚手架,方便快速开发的
npm install -g @vue/cli-init #这个是vue用来快速创建项目的脚手架
到这里为止,实际上已经可以基于vue开始进行前端代码开发了。
2.2 可以简单的创建一个项目了
vue建立新工程也有自己的专属命令,vue create
+ 项目名称
,注意,这里随便去一个目录都行。下面这行命令执行后,会自动新建一个以项目名称为名字的目录,并且在里面直接添加很多辅助定式文件,那些文件的作用我们现阶段可以不用理解,只需要记住,我们需要改动的东西都是在src文件夹下就行。
vue create my-first-project
这里注意一下,为了简便快速入门,我们选择vue2.x,因为2.x目前例子很多,成熟的案例也很多,方便我们借用。3.x需要调试的地方不少,先学会了2.x转过去还是容易的。
这里需要额外注意一下,默认直接回车选的是Vue 3,我们作为一个抄作业快速搭积木的人,Vue2目前可抄的作业更多。所以这里要按一下 ↓ 。
我们进入my-first-project
这个目录,直接在shell中敲击如下指令,一个默认的前端网页已经可以访问了。
npm run serve
输入完上面指令后,整个my-first-project
工程便开始编译了,类似于我们后端编译cpp文件,最终生成可执行程序类似。但前端的这个run serve
模式更加等效于我们的debug模式。
更加方便的是,任何一行源代码改动,node可以自动重新构建,自动展示在浏览器上是最新的内容。包括如果把工程改挂了,浏览器上也能直接展示成报错。
现在编译完成了,已经有一个提示了,按照提示的去访问对应网页就可以看到了一个vue提供的默认网页了。
DONE Compiled successfully in 4556ms 下午1:53:02
App running at:
- Local: http://localhost:8081/
- Network: http://192.168.1.73:8081/
Note that the development build is not optimized.
To create a production build, run npm run build.
额外提示一点,如果整个项目写完了,最后运行
npm run build
之后,工程里会多一个dist目录,框架会将所有相关的代码打包成发布时候需要的版本,最后将dist目录下的所有内容放到对应的WEB服务器里,和后端程序放在一起即可。
2.2.1 为什么这样就能展示了?
这个时候细心的你可能发现了一点奇怪的地方。我们明明只写了前端代码,为什么访问8080端口还是能正常展示,浏览器也能正常显示。Amazing!
这是因为node引擎帮你处理了最简单的资源获取过程。也就是这个调试模式下,做的事情仅仅是所有的资源文件(主要包括html,图片,js脚本)。这些文件会按照http协议传输给浏览器。没有任何和后端服务器交互的逻辑协议,仅仅只是http传输,但这种模式下调试前端展示已经没有什么问题了。
2.3 开始试着自己写写前端代码了
前端代码一大抄,看你会抄不会抄。成熟的前端框架已经给我们总结了很多很多可以复用的前端组件了。组件更像是我们需要用的一个皮肤,那么现在我们选一个皮肤吧。
2.3.1 先大体了解一下Vue这个框架是按照什么逻辑展示的
这里引用一段官网的原话:
组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树:
这个图里实际上也很考究,很简明的说明了Vue的整体思想。从上到下,整个页面是一个总树根,这一层下面分了3个大块(分别为横着的一条,和下面的两个大块),然后每个里面又细分了。不光只是一个随意数量的示意。实际上,HTML语言的布局也是这种思路。
2.3.2 先选一个自己喜欢的皮肤
进入my-first-project
这个目录,我们选择一个最为常用的UI框架。来自我们天天点外卖的手机APP,饿了么
。这里给一个链接,后面我们会经常在里面去 抄东西 找灵感。以下命令也是源自于这个网页的快速上手提示。
npm i element-ui -S
按照网页要求,我们要开始写改第一个js代码了。在src/main.js 中写入以下内容
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App)
});
按照这个要求改好后,我们后面就可以安心的开始抄写代码了。
2.3.3 vue文件里面有哪些东西
最初的工程里,src/componets
下有一个HelloWorld.vue
。我们后续绝大多数也是通过新增一些.vue
文件来增加界面要展示的内容。和2.3.1里树状图那样,每一个.vue
文件实际上就是一个小方块。
那么.vue
文件主要写点什么,里面都有些什么东西呢?其实每个.vue
文件里主要都有三个部分。
- 第一个部分是模板部分,也就是最后放到树上的小方块到底是个什么,是按钮,是表,或者是很多东西的组合。这段
<template>
和</template>
之间的代码将被插入到html中。这个部分主要需要用html语言写。
<template>
<div class="hello">
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<!-- <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>. -->
</p>
<h3>Installed CLI Plugins</h3>
...........
</div>
</template>
- 第二个部分是脚本部分,主要是一些模板对应的响应动作对应的函数。例如某个按钮按下之后,要执行个什么事情、某个输入框输入了东西后要干什么等等。这部分的语言是JavaScript。
<script>
// import HelloWorld from '@/components/HelloWorld.vue'
// import TableExc from '@/components/TableExc.vue'
export default {
name: 'App',
data() {
return {
Hw_seen : true
}
},
components: {
// HelloWorld
// TableExc
},
methods : {
to_deal() {
this.$router.push('/home')
},
to_about () {
this.$router.push('/about')
}
}
}
</script>
- 第三部分是样式部分,主要是负责格式相关的东西,类似于word中的段落对齐方式,字体大小,加粗,等等各种和格式排版相关的东西。这个部分主要是用css语言写。
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 2px;
}
</style>
读到这里,其实我们可以简单介绍一下vue整个工程的渲染过程,大概是这样的。
背后逻辑稍微要逻辑一下,方便后面理解vue-router
针对新建的项目,默认逻辑是有一个空的index.html
文件,这个文件里有一个空的块<div id="app"></div>
。这块后续会被App.vue
替换。然后App.vue
中又引用了一段<HelloWorld msg="Welcome to Your Vue.js App"/>
的语句,引入了一个HelloWorld.vue
。
2.3.4 原有界面不好看,我想换一个
首页太简单太枯燥了,我想换一个。这里直接替换HelloWorld.vue
。
这里的一个实例,好多王小虎的那个看起来很不错。下面点开还直接有代码。直接都贴过来就完事。
但是好像现在还不能跑,注意2.3.3里提到的那样,原有代码里少一个<template>
部分,但没事,最上面那些el开头的就是,直接把那些的外层套一个<template> </template>
。然后shell里运行
npm run serve
首页不一样了,想要的东西就来了。但我还想改一些东西。那应该怎么办呢?
3. 开始正儿八经的改改代码
从简单的组件开始加起来,那么我们先在王小虎(HelloWorld.vue)这个界面加一个按钮吧,以下案例一直到3.6均在王小虎(HelloWorld.vue)这个界面进行修改,3.7介绍vue-router的时候需要涉及改动App.vue。
3.1 从加一个按钮开始,了解vue的主要功能
还是从饿了么找灵感 这里有很多按钮,选个漂亮的贴过来就行。这里选择一个贴过来。
<el-button type="primary" round>主要按钮</el-button>
把上面这一行直接贴到<template> </template>
的一个元素间隔(即不要在某个这段落内,而跨越这个段落。)中即可。这里选择在head和main之间插入,具体如下:
<el-header style="text-align: right; font-size: 12px">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>查看</el-dropdown-item>
<el-dropdown-item>新增</el-dropdown-item>
<el-dropdown-item>删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span>王小虎</span>
</el-header>
<!--我们插入在这里 <el-button type="primary" round>主要按钮</el-button> -->
<el-main>
<el-table :data="tableData">
<el-table-column prop="date" label="日期" width="140">
</el-table-column>
<el-table-column prop="name" label="姓名" width="120">
</el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
</el-table>
</el-main>
然后可以开始测测效果了,如果之前一直都没退出去就更加容易,直接看浏览器就能实时更新。这里由于我退出过,所以重新shell启动一遍。
npm run serve
按钮终于出现了,虽然出现的位置有点尴尬,但是的的确确多了一个按钮。但是按下去之后什么反应都没有。这可怎么办。
3.2 如何给一个元素增加一个动作,v-on: 或者 @
给按钮增加事件实际上是一个最最最基础的需求,改动的点实际上也很少。只需要修改两个地方。
- 模板中增加 @click= 某个函数名
<el-button type="primary" round @click="button_click">主要按钮</el-button>
- 脚本中的methods里增加一个绑定的那个函数。
<script>
export default {
data() {
const item = {
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
};
return {
tableData: Array(20).fill(item)
}
},
//下面是我们要加的内容
methods: {
button_click () {
alert("你别乱点呀!")
}
}
};
</script>
这样改完后,再点一下那个按钮,就会出来一个提示。你别乱点呀!这行就出来了。逻辑上相当于把button_click这个函数和按钮点击这个事情关联了起来。实际上就这么简单。这个@这个符号相当于是v-on的简写。也可以写成下面的形式:
<el-button type="primary" round v-on:click="button_click">主要按钮</el-button>
3.3 我还想实时修改页面内容,那该怎么办呢? v-model和 {{}} 语法
实际上用源生的JavaScript语言和html语法写这种实时修改页面的语言会很复杂,涉及到ajax,xpath或者其他的元素定位语言等复杂的方式才能进行修改。但现在绝大多数的主流前端框架都实现了双向绑定功能。简单的说就是JavaScript中脚本的变量与Html中的变量实时互通,脚本中变量修改了,Html中的也会实时变化。
那我们来试试,还是刚刚那个按钮的例子。
模板加入的代码换成这样:
<el-button type="primary" round @click="button_click"> {{msg}} </el-button>
我们在html代码断中如果要引用JavaScript变量,直接使用 {{}} 里面加上变量名即可。在脚本代码中,加入对msg这个变量的操作。
<script>
export default {
data() {
return {
seen : false,
num : 1,
msg : "可劲按"
}
},
methods: {
button_click () {
// alert("你别乱点呀!")
this.num += 1
this.msg = "可劲按" + this.num;
}
}
};
</script>
这下一直按,这个按钮的名字就会一直递增了。我们想要的结果已经出来了。但还没介绍v-model
,这个主要体现在一些输入的控件上。例如我们现在多了一个输入框,想能够修改按钮的名字。这种情况下,v-model
就能体现出效果了。这个时候,我们接着上面的那个代码,再加个输入框,输入框里写点东西最后能呈现在按钮上。
还是去找饿了么点个外卖,下单一个输入框。
<el-input v-model="input" placeholder="请输入内容"></el-input>
饿了么的模板上已经使用了v-model,绑定到了一个input变量上,并且在脚本里的data里也声明了input为空。这里我们就不叫input了,直接用之前输出的msg值。所以我们插入<template>
里的内容改成这样。插入位置和之前一样,先随处找一个空白位置。
<el-input v-model="msg" placeholder="请输入内容"></el-input>
脚本再审视一遍,不改也没事。因为msg实际上已经绑定到input控件,最后还是能显示到输出位置的。
<script>
export default {
data() {
return {
seen : false,
num : 1,
msg : "可劲按"
}
},
methods: {
button_click () {
// alert("你别乱点呀!")
this.num += 1
this.msg = "可劲按" + this.num;
}
}
};
</script>
抬头看一眼浏览器,点点按钮。果然输出框换了,按钮的名字也不一样了。交互感又好了一些呢。
3.4 元素属性绑定到变量上, v-bind: 或者 :
其实理解了上面的v-model
之后,v-bind
的作用极为相似,同样也是一种双向绑定,只不过绑定的是元素属性里的东西,而不是元素内容。仅此而已。这回我们并不需要再从饿了么上找素材了,当然并不是我们要去找美团。直接用上面的已有的代码就可以体现v-bind
的作用。同理v-on:
和@
的关系一样,v-bind:
的简写就是:
。
我们还是用输入框做文章,这里属性字段有个placeholder
是个固定量,总是输出请输入内容,感觉有点没意思。我们想把我们的msg变量放到这个默认占位符的位置,虽然内容是可劲按
,但是并不妨碍。
<el-input v-model="msg" :placeholder="msg"></el-input>
在抬头看一眼,完事儿了呀,输入框不再单调了。让你可劲按了。
所以更简单的理解,v-bind
就是一个作用于元素属性的v-model
。
3.5 选择性加载控件 v-if
有些场景下,有些非特权用户就不想让他们看到那么多,那么事情应该怎么办呢?实际上v-if
就是一个显示开关。v-if
值为true
了,那么这个控件就看的到,成false
了,就看不到。还是刚刚那个输入框的例子,我想点击一下按钮才能看到。再点一下,就看不到了。这个需求又应该怎么做呢?我们先看看按钮应该添加一个事件了。这里介绍一个新的功能,对于很简单的函数,一行表达式,可以不用在methods里写,直接写在@后面即可。
- 我们首先给我们的输入栏加一个
v-if
,然后用一个变量kandejianbu
来控制这个控件是否能看得见
<el-input v-model="msg" :placeholder="msg" v-if="kandejianbu"></el-input>
- 我们把变量
kandejianbu
的变化绑定到一个按钮上,按钮的点击行为直接用表达式写出,不再绑定一个函数。我才不告诉你我偷懒不想写那么多代码
<el-button type="primary" round @click="kandejianbu = !kandejianbu"> {{msg}} </el-button>
- 这个时候我们一定别忘了,还是要在脚本区域的data段把我们的
kandejianbu
怼进去。
<script>
export default {
data() {
return {
seen : false,
num : 1,
msg : "可劲按",
kandejianbu : true
}
},
methods: {
button_click () {
// alert("你别乱点呀!")
this.num += 1
this.msg = "可劲按" + this.num;
}
}
};
</script>
再点点,一下看得见,一下看不见,交互感果然又好了点呢。
3.6 v-for 批量的吐出后端数据
这个语法只是为了简单的吐出一个数组里面的所有元素。这里并不深究这个命令,只是给出一个<template>
的模板例子,接着上面王小虎刚好有一个数组,我们呈现一下即可。
还是在<template>
段找一个空白的地方,输入以下代码:
<p v-for="item in tableData" :key="item.date">
{{ item.name }}
</p>
这个语法有点像是C++11里的for(auto a : list)
语法,这里的item
相当于代指容器里的每一个元素,然后因为王小虎那个例子里tableData
这数组里面每个元素是一个结构体。所以用item.data
排序,然后展示item.name
。
最后抬头看一眼,一溜王小虎出来了。刚好是虎年,祝大家虎虎虎虎虎!
3.7 单页应用的推荐插件vue-router
单页应用的特点是,基本上无论怎么操作,都不会有第二个页面跳出来。无非是在当前页面通过类似导航栏的东西,不断的切换当前页面的内容。作为最流行的框架,自然对这种SPA的方式支持的比较完美了。那么现在为我们的例子做一个简单的导航吧。
你没想错,我们不可能空手写代码,这个时候想写个导航栏怎么办?拿出手机打开饿了么APP! 我们还是要去饿了么找作业抄。现成的导航栏呀,看起来还是不错的,我比起第一条白色,我还是喜欢深色的,那就抄个深色的过来吧。
再次提示一下,这里需要改动App.vue
了。这里还是推荐大家再重温一下整个vue框架的渲染过程。
我们可以先研究一下直接create
出来的App.vue
里都有些什么。
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
这个<template>
实际上主要就两个东西,一个img图片,这就是为什么我们首页总是悬着那么大一个V,然后下一行引用了我们一直修改的HelloWorld.vue
。先把那么个大图标干掉。
<template>
<div id="app">
<!-- <img alt="Vue logo" src="./assets/logo.png"> -->
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
抬头看一眼,OK了,终于不见了。舒服了。
在注释掉的代码这块,我们改成我们想要的导航栏。
<template>
<div id="app">
<el-menu
:default-active="activeIndex2"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="1">仪表盘</el-menu-item>
<el-submenu index="2" disabled>
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项1</el-menu-item>
<el-menu-item index="2-4-2">选项2</el-menu-item>
<el-menu-item index="2-4-3">选项3</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>消息中心</el-menu-item>
<el-menu-item index="4">Vue original</el-menu-item>
</el-menu>
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
OK,导航栏也出现了。
但既然是导航栏,那么肯定点不同的按钮,下面展现的东西是不一样的。那么也就是下面这块区域是按照不同按钮,呈现不同的东西的。逻辑上是这样没毛病的,vue是怎么做的呢?这里vue用了一个vue-router
这个插件。
- 首先需要引入这个插件了,在shell里输入:
npm install vue-router
- 然后一般的习惯是在src文件夹里建立一个router的文件夹,里面放一个js脚本,名字也无所谓,这里就干脆叫
router.js
。这个文件的写法基本也是固定的,只用改routers里面的东西就好了。我们暂时只写两个路由。相当于我们想要的导航栏能最好后指向两个地方。一个是/home下的HelloWorld2,另一个是/about下的HelloWorld。这里我们先直接把HelloWorld.vue改个名字复制成HelloWorld2.vue。
import HelloWorld from '@/components/HelloWorld'
import HelloWorld2 from '@/components/HelloWorld2'
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter);
const routers = [
{
path: '/home',
name: 'home',
component: HelloWorld2
},
{
path: '/about',
component: HelloWorld
},
]
export default routers
- 我们在
main.js
中加上我们export出去的这个routers这个路由表。这样我们的Vue框架就知道,我们还引用了路由表这个插件。
import Vue from 'vue'
import App from '@/App.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import routers from '@/router/router'
import VueRouter from 'vue-router'
Vue.config.productionTip = false
Vue.use(ElementUI);
const router = new VueRouter({
mode: 'history',
routes: routers
})
new Vue({
el: '#app',
router,
render: h => h(App)
})
- 最后但是也是最关键的步骤,把router-view放在App.vue中,并为导航按钮添加对应的动作,对,你没记错,就是添加@click的函数。
<template>
<div id="app">
<el-menu
:default-active="activeIndex2"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="1" @click="to_deal">仪表盘</el-menu-item>
<el-submenu index="2" disabled>
<template slot="title">我的工作台</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
<el-menu-item index="2-3">选项3</el-menu-item>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项1</el-menu-item>
<el-menu-item index="2-4-2">选项2</el-menu-item>
<el-menu-item index="2-4-3">选项3</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>消息中心</el-menu-item>
<el-menu-item index="4" @click="to_about">Vue original</el-menu-item>
</el-menu>
<!-- 这里需要注意,之前是HelloWorld的组件,现在用router-view代替。 -->
<router-view></router-view>
</div>
</template>
我们再看看对应的函数怎么写:
<script>
// import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
data() {
return {
Hw_seen : true
}
},
components: {
// HelloWorld
},
methods : {
to_deal() {
this.$router.push('/home')
},
to_about () {
this.$router.push('/about')
}
}
}
</script>
这样,点了导航上的按钮,就相当于push了一个路径,我们就通过之前的routers设置的组件里去了。
虽然当前HelloWorld和HelloWorld2两个东西一模一样,切了导航看不出来,但是有兴趣的小聪明可以改改HelloWorld2,例如把
<script>
段data中返回的王小虎换成王大虎,那么就不一样了。
解释一下 <router-view>
这个元素
这里多解释一下<router-view>
这个元素,实际上就是一个占位符的作用,为后续导航的组件占个位置,后续push到了什么位置,就把配置的vue中的 template加载到这个<router-view>
元素上。
4. 后端的数据应该怎么传过来呢?
还记得之前说的,node市场里什么都有么,那么后端数据怎么拿过来,直觉反应是什么?对的嘛,有库可以用的,调接口就完事儿。vue为我们准备了另一个组件,vue-resoucre。
npm i vue-resource
然后在main.js
中加入我们需要用这个插件即可。
//在main.js中插入如下两行代码段
import VueResource from 'vue-resource'
Vue.use(VueResource);
Vue.http.options.emulateJSON = true;
4.1 HTTP GET POST
在引入了vue-resource
后,HTTP请求无非就是GET和POST调接口了。特别需要注意,一般情况下get里面的内容直接写uri就好,也就是直接下面的例子里,直接写protocol就好,样例这么写是为了演示跨域请求。一般来说跨域请求是很危险而且不常用的手法。
来个GET的样例
this.$http.get('http://10.10.112.220:8081/protocol').then((response) => {
console.info(response.body)
}, (response) => {
console.info(response.body)
alert("got failed")
});
这里和C++11的std::promise和std::future类似。get返回的可以理解是一个std::future,然后对future塞两个处理回调函数就好。这里的箭头函数类似于C++11的lambda,写法略有不同。第一个回调是成功处理回调,第二个回调是失败处理回调。
POST也极为类似,无非就是POST要给服务器一些数据,多传输一些东西进去就好。
this.$http.post('http://10.10.112.220:8081/protocol', {title: '',blog_body: ''}).then(
(response) => {
console.info(response.body)
}, (response) => {
console.info(response.body)
alert("got failed")
});
4.2 Websocket 双工通信
由于不是每个浏览器都支持Websocket,虽然现在主流浏览器都支持了,但是还是有大部分浏览器不支持。所以一般准备用websocket之前,都会有个判断,大概会这么写:
if (!window.WebSocket) {
alert("浏览器不支持WebSocket");
return;
}
然后如果Websocket被浏览器支持,后面的事情就很简单了。
// 定义一个全局对象
var ws = null;
// 为websocket对象创建一个通信url
ws = new WebSocket('ws://' + location.hostname + ':80/test');
// 然后注册几个回调就好,这里很像是我们后端用的异步框架
//对象打开时候的回调
ws.onopen = function(){
ws.send(package);
log("打开连接ws");
};
//对象关闭时候的回调
ws.onclose = function(event) {
//log("websocket closed");
};
// 来消息时候的回调,这里一般注册一个总共的消息处理入口函数
ws.onmessage = dealMessage;
// 出错时候的回调
ws.onerror = function(event) {
log("websocket occur error:" + event.data);
};
4.3 后端来的时候怎么呈现到页面?
记得由于上述代码其实都是写在<script>
段的,所以数据来了,提取出要呈现的信息,赋值给data()里面的那些变量,通过双向绑定自然就呈现好了。
参考资料
- Vue.js快速入门 申思维