前端学习笔记 2:Vue
Vue 是一个目前最流行的前端响应式框架,关于它的简单介绍可以观看这里。
1.快速入门
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 正常渲染和显示内容。
2.vue 指令
类似于一些模版语言,vue 提供一些程序控制指令,用于更灵活地对页面元素进行控制和渲染。
2.1.v-for
通常使用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"
2.2.v-bind
我们已经知道,要在 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>
2.3.v-if && v-show
可以使用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
应当用于仅在页面加载时需要判断是否显示的元素。
2.4.v-on
可以用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>
2.5.v-model
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
获取到需要的数据模型。
3.生命周期
类似于其它框架,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>
4.Axios
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 调用示例可以查看官方文档。
5.案例
可以用上面介绍的内容完成一个简单案例——一个带搜索功能的文章列表页面:
<!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,如果某个搜索条件为空,就不会返回任何内容。
谢谢阅读,本文的完整示例代码可以从这里获取。
6.参考资料
- w3school 在线教程
- Axios中文文档 | Axios中文网 (axios-http.cn)
- Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)
- 黑马程序员SpringBoot3+Vue3全套视频教程