Vue 是一个目前最流行的前端响应式框架,关于它的简单介绍可以观看这里。
Vue 的官网提供一个快速上手指南,有多种方式可以安装和使用 Vue,这里展示一个最简单的方式——直接导入官方提供的在线的核心 JS 文件进行使用。
这里展示的内容相当于官方快速上手指南中的使用 ES 模块构建版本。
需要先像在之前文章中介绍的那样,在 JS 模块中导入 Vue 的createApp
函数:
<script type="module">
import { createApp } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";
</script>
要想让 Html 页面元素被 Vue 控制和渲染,需要使用createApp
函数对其装载(mount):
<body>
<div id="app"></div>
<script type="module">
import { createApp } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";
createApp().mount("#app");
</script>
</body>
在上边这个示例中,id 为app
的div
元素(包括其子元素)被 Vue 控制和渲染,具体是通过createApp().mount("#app")
实现的。
要想向被 Vue 控制的 Html 标签中写入(渲染)内容,需要先准备数据,具体是通过createApp
的参数提供:
<script type="module">
import { createApp } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";
createApp({
data: function(){
return {
msg: "Hello World!"
};
}
}).mount("#app");
</script>
这里createApp
函数接收一个 JS 对象作为参数,该对象的data
属性同样是一个函数,其返回值是一个 JS 对象,该对象的属性可以在 Vue 渲染的 Html 元素中使用。
当然,当 JS 对象的属性是函数时,也可以使用简写方式进行定义:
createApp({
data(){
return {
msg: "Hello World!"
};
}
}).mount("#app");
准备好 Vue 数据后,在 Html 元素中使用插值表达式({{...}}
)插入数据:
<div id="app">
<h1>{{msg}}</h1>
</div>
这样页面加载后就可以被 Vue 正常渲染和显示内容。
类似于一些模版语言,vue 提供一些程序控制指令,用于更灵活地对页面元素进行控制和渲染。
通常使用v-for
指令将 JS 数组中的内容渲染到 Html 表格或列表中。
这里提供一个简单的示例代码:
<body>
<div id="app">
<table>
<tr>
<td>序号</td>
<td>姓名</td>
<td>年龄</td>
</tr>
<tr>
<td>序号</td>
<td>姓名</td>
<td>年龄</td>
</tr>
</table>
</div>
<script type="module">
import {createApp} from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";
createApp({
data(){
return {
students: [
{
name: "JackChen",
age: 19
},
{
name: "BrusLee",
age: 28
}
]
}
}
}).mount("#app");
</script>
</body>
在上面的示例中,提供了一个表格,表格所在的 div
由 Vue 渲染,并且通过createApp
函数的参数提供了一个可以用于填充表格的 JS 数组students
。
现在使用v-for
指令填充表格:
<table>
<tr>
<td>序号</td>
<td>姓名</td>
<td>年龄</td>
</tr>
<tr v-for="(student,index) in students">
<td>{{index}}</td>
<td>{{student.name}}</td>
<td>{{student.age}}</td>
</tr>
</table>
像上面展示的,只需要在需要循环填充的元素(这里是tr
标签)中添加属性v-for
,并在其值中使用(...) in ...
的方式遍历 JS 数组读取元素和索引下标即可。
(...) in ...
循环读取的写法与 Python 颇为类似。
如果不需要使用索引下标,可以简写:
v-for="student in students"
我们已经知道,要在 Html 标签体中使用 Vue 提供的数据,需要使用插值表达式,但如果要在标签的属性值中使用 Vue 提供的数据,就要使用 v-bind
命令:
<body>
<div id="app">
<a v-bind:href="url">百度</a>
</div>
<script type="module">
import {createApp} from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";
createApp({
data(){
return {
url: "https://www.baidu.com/"
}
}
}).mount("#app");
</script>
</body>
在上面的示例中,通过v-bind
命令,将 Vue 中提供的url
变量的值设置为a
标签的href
属性值。
特别的,使用v-bind:xxx
设置属性值时,可以简写为:xxx
,比如上面示例中可以简写为:
<a :href="url">百度</a>
可以使用v-if
命令控制是否显示某个 Html 标签:
<body>
<div id="app">
商品价格:
<span v-if="customer.level>=1 && customer.level<=2">9.9</span>
<span v-else-if="customer.level>2 && customer.level<=3">19.9</span>
<span v-else>29.9</span>
</div>
<script type="module">
import { createApp } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
createApp({
data() {
return {
customer: {
level: 2,
name: "JackChen"
}
}
}
}).mount("#app");
</script>
</body>
如同其他的模版语言一样,v-if
可以结合v-else-if
和v-else
命令一起使用,起到通过条件表达式来控制是否显示 Html 元素的作用。
使用v-show
同样可以控制 Html 元素是否在页面显示:
<div id="app">
商品价格:
<span v-show="customer.level>=1 && customer.level<=2">9.9</span>
<span v-show="customer.level>2 && customer.level<=3">19.9</span>
<span v-show="customer.level>3">29.9</span>
</div>
注意,
v-show
后的条件表达式不能为空。
页面展示效果是相同的,它们的区别在于作用机制不同:
v-if
是通过将 Html 元素对应的 DOM 节点从页面文档的 DOM 树中删除/添加的方式控制是否显示。v-show
是通过设置元素的 CSS 样式(style="display:none"
)来控制是否显示。作用机制的不同决定了它们在生效时的性能差异,前者会触发 DOM 树的修改以及页面的重新渲染,而后者仅涉及页面重新渲染。
因此,如果有 Html 元素需要频繁的显示或隐藏,应当使用v-show
,v-if
应当用于仅在页面加载时需要判断是否显示的元素。
可以用v-on
命令监听 HTML DOM 事件,并在相应的事件发生时执行指定的 JS 函数:
<body>
<div id="app">
<button v-on:click="redirect">跳转到百度</button>
</div>
<script type="module">
import {createApp} from "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
createApp({
methods:{
redirect(){
window.location.href="https://baidu.com"
}
}
}).mount("#app");
</script>
</body>
注意,这里绑定的是 DOM 元素的事件,而非 Html 事件,所以是
click
而不是onclick
,两者的写法略有不同。
要绑定的 JS 方法需要定义在 Vue 函数createApp
入参的methods
属性中。
特别的,使用v-on
绑定事件时可以简写为@event_name
:
<button @click="redirect">跳转到百度</button>
v-model
可以作用于 Html 表单元素,将其的视图与 Vue 中的数据模型进行双向绑定。这样就可以很容易地获取用户在表单元素中填写的值,或者通过 Vue 的数据模型修改表单元素的值。
下面是一个简单示例:
<body>
<div id="app">
<input v-model="num" />
<button @click="increase">自增</button>
</div>
<script type="module">
import { createApp } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
createApp({
data() {
return {
num: 0
}
},
methods: {
increase() {
this.num++;
}
}
}).mount("#app");
</script>
</body>
在上面这个示例中,使用v-model
将文本输入框与数据模型num
进行了双向绑定,输入框的初始值是数据模型的初始值0
,按钮的点击事件会触发increase
函数,在该函数中对num
自增,自增后同样会改变输入框中显示的值,这就是双向绑定。
increase
方法中的this
关键字在这里代表的并不是methods
属性,而是 Vue 实例。因此可以通过this.num
获取到需要的数据模型。
类似于其它框架,Vue 实例有生命周期,包括从创建到销毁的一系列过程。这些过程有对应的生命周期钩子(方法)可以供我们调用,以在 Vue 实例的特定阶段执行某些代码。
比较常用的有mounted
,这个方法对应 Vue 实例已经加载成功,类似于以前前端开发经常会使用的 document.ready
事件,可以将一些页面加载完毕后执行的内容放在该函数中。
下面是一个简单示例:
<body>
<div id="app"></div>
<script type="module">
import { createApp } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
createApp({
mounted() {
console.log("vue 实例加载完毕")
}
}).mount("#app");
</script>
</body>
Axios 是一个前端框架,用它可以更方便地发送 Ajax 请求。
用于调试的后端示例代码可以从这里 获取。
首先需要引用 Axios 的 JS 文件:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
具体的 JS 文件地址可以在官方指南中安装部分的 使用 unpkg CDN 找到。
看一个简单示例,使用 Axios 从服务端读取所有文章列表:
<body onload="getAllArticles()">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
function getAllArticles() {
axios({
url: '/article/getAll',
method: 'get',
baseURL: 'http://localhost:8080'
}).then(function (result) {
console.log(result.data)
}).catch(function (error) {
console.log(error)
});
}
</script>
</body>
这里使用的是axios
的标准调用,可以在参数中设定各种调用所需的配置内容,包括 URL、调用方法等,具体可以参考官方文档中的请求配置。
接收到的响应信息可以使用级联调用的then
方法的参数(这里是result
)获取,该参数包含响应报文头、HTTP 状态码等信息,最常用的是响应报文体(result.data
)。完整的响应内容结构可以参考官方文档的响应结构。
实际上then
方法接收的是一个匿名函数,该匿名函数负责处理成功时的响应。所以也可以使用匿名函数的特殊写法作为 then
方法的参数:
axios({
url: '/article/getAll',
method: 'get',
baseURL: 'http://localhost:8080'
}).then(result => {
console.log(result.data)
}).catch(error => {
console.log(error)
});
JS 中匿名函数的简写方式类似于 Java。
与then
类似,用于处理调用失败时的响应函数在catch
方法中设置。
除了上边这种最基本的调用方式,Axios 还提供一些更简单的调用方式,比如:
axios.get('http://localhost:8080/article/getAll').then(result => {
console.log(result.data)
}).catch(error => {
console.log(error)
});
类似的,对于 POST 请求,也有响应的简写方式:
axios.post('http://localhost:8080/article/add',{
title: '哈利波特',
category: '小说',
time: '2001-10-01',
state: '已发布'
})
更多的 POST 调用示例可以查看官方文档。
可以用上面介绍的内容完成一个简单案例——一个带搜索功能的文章列表页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
文章分类:<input type="text" v-model="category" />
发布状态:<input type="text" v-model="state" />
<button @click="search">搜索</button>
<table>
<tr>
<td>文章标题</td>
<td>分类</td>
<td>发表时间</td>
<td>状态</td>
<td>操作</td>
</tr>
<tr v-for="article in articles">
<td>{{article.title}}</td>
<td>{{article.category}}</td>
<td>{{article.time}}</td>
<td>{{article.state}}</td>
<td>
<a>编辑</a>
<a>删除</a>
</td>
</tr>
</table>
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
data() {
return {
articles: [],
category: '',
state: ''
}
},
methods: {
loadArticles() {
axios.get("http://localhost:8080/article/getAll").then(result => {
this.articles = result.data
}).catch(error => {
console.log(error)
})
},
search() {
axios.get("http://localhost:8080/article/search", {
params: {
category: this.category,
state: this.state
}
}).then(result => {
this.articles = result.data
}).then(error => {
console.log(error)
})
}
},
mounted() {
this.loadArticles();
}
}).mount("#app");
</script>
</body>
</html>
后台的搜索接口实际上有bug,如果某个搜索条件为空,就不会返回任何内容。
谢谢阅读,本文的完整示例代码可以从这里获取。