文章目录
写在前面
本博文仅作为个人学习过程的记录,可能存在诸多错误,希望各位看官不吝赐教,支持错误所在,帮助小白成长!
Vue
一、什么是 Vue
- 开发者:尤雨溪(中国)
- 一套用于构建用户界面的渐进式框架,发布于 2014 年 2 月,与其他大型框架不同的是,Vue 被设计为可以自顶向下逐层应用。
- Vue 核心库只关注视图层(HTML+CSS)。
- 便于与第三方库(网络通信:axios,页面跳转:vue-router , 状态管理:vuex)或者既有项目整合。
二、相关技术栈
前端
-
HTML(容易)
-
CSS(难点、重点)
企业中开发,多用 CSS 预处理器,用编程的方式来自动生成输出 CSS
-
JS(重点)
JS 框架:
-
jQuery
-
Angular(Java 程序员开发)
将 MVC 搬到了前端,增加了模块化开发的理念,采用 TypeScript(微软)开发
-
React(Facebook 出品)
提出了虚拟 Dom(Visual Dom)的概念
需要学 JSX 语言
-
Vue
渐进式:不要求完全使用全部功能,可以只在项目中只嵌入一部分。
综合了 Angular 和 React
特色:属性计算
强调模块化
-
Axios(前端通信框架)
-
-
UI 框架
- ElementUI(饿了么)
- AmazeUI
- Bootstrap(Twitter)
- Ant-Design(阿里巴巴)
后端
-
NodeJS
由于过于笨重,作者声称已经放弃了 NodeJS,开始开发新的架构Deno
-
NodeJS 及项目管理工具
-
Express: NodeJS 框架
-
NPM:项目综合管理工具,类似于 Java 开发中的 Maven
-
关于前后端分离
模式也好,技术也罢,没有好坏优劣之分,只有合不合适;
前后端分离的开发思想主要是基于SoC(关注度分离原则)
,让前后端职责更清晰,分工合作更高效。
三、入门使用
3.1、Hello,Vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Hello Vue</title>
</head>
<body>
<div id="app">{
{message}}</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app', data: {
message: 'Hello, Vue!' } })
</script>
</body>
</html>
声明式编程范式!显示与数据分离!
响应式:页面显示会随着数据的改变而改变!
3.2、Mustache 语法
Mustache
语法:代码中我们使用{
{message}}
,进行元素插值。双大括号就是 Mustache 语法的标志!
大括号内支持使用运算符对数据进行处理后显示!
3.3、插值操作
v-once
只会进行一次渲染,后面数据的更新不会触发页面的刷新,但是对象的数据还是会变化!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>V Once</title>
</head>
<body>
<div id="app"><span v-once>{
{message}}</span></div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'this is a readonly message' },
})
</script>
</body>
</html>
代码效果:
v-html
将数据按照 html 代码做解析,然后渲染。
与之相反的是:v-pre,显示原生的文本内容,不做任何解析!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>V Html</title>
</head>
<body>
<div id="app">
<h1>v-html:</h1>
<span v-html="message"></span>
<h1>v-pre</h1>
<span v-pre>{
{message}}</span>
<h1>Mustache</h1>
<span>{
{message}}</span>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '<a href="https://www.baidu.com/">百度一下</a>' },
})
</script>
</body>
</html>
代码效果:
v-text
其作用与 mustache 相似,接收一个字符串变量,然后渲染,还是利用上面那个例子,效果如图
v-cloak
当 Mustache 语法未被正确解析时,用户可能看到类似{ {message}}的文本元素。
使用 v-cloak,可以判断元素是否渲染成功:{
当数据渲染成功前:v-cloak 作为标签属性存在,
数据渲染成功后:v-cloak 从标签属性清除
}
因此我们可以借助这个特殊属性,使用 css 来装饰对应标签选择不让用户看到原生内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>V-Cloak</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app">
<h1>Message:</h1>
<span v-cloak>{
{message}}</span>
</div>
<script src="../js/vue.js"></script>
<script>
// 设置延时,2s后创建Vue
setTimeout(function () {
const app = new Vue({
el: '#app',
data: {
message: 'Hello World!',
},
})
}, 2000)
</script>
</body>
</html>
3.4、属性绑定 v-bind
像控制元素内容一样,动态控制属性值,使用v-bind:xxx="??"
将标签内的 xxx 属性绑定到 data 中的??数据上!
<div id="app">
<a v-for="movie in movies" v-bind:href="movie.src">{
{movie.name}}<br /></a>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
movies: [
{
name: '钢铁侠', src: 'xxxx' },
{
name: '美国队长', src: 'xxxx' },
{
name: '雷神', src: 'xxxx' },
],
},
})
</script>
可以看到我们的 a 标签的 href 是与 movie 的 src 值绑定的!
v-bind 使用的频率极高,于是官方为其提供了简写版::xxx=??
。就可以完成 xxx 属性与 data 中??的值的绑定!
同时官方文档提到了在 2.6 版本后,还提供了动态参数(v-bind、v-on 是支持接收参数的!其绑定的内容就是参数)
也就是说以后绑定的属性或者行为也不用“写死”了,可以通过 data 中的参数进行指定:
<div id="app">
<a v-bind:[link.attr]="link.attrValue" v-text="link.linkName"></a>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
link: {
linkName: '百度一下',
attr: 'href',
attrValue: 'https://www.baidu.com',
},
},
})
</script>
可以看到,我们直接通过数据就为 a 标签动态绑定了 href 属性!
再来看看 v-bind 的高阶使用:结合对象动态修改 class:
<style>
.red {
color: red;
}
.yello {
color: yellow;
}</style
><!--version 1.0-->
<body>
<div id="app">
<h1 :class="{
'red': true, 'yello': false}">Hello, World</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app' })
</script>
</body>
通过一个:class = {classname: boolean, classname2: boolean}
,会将 boolean 为 true 的 class 加入 class 列表。这种写法我们称其为对象语法!
<!--version 2.0-->
<div id="app">
<h1 :class="{
'red': isRed, 'yello': isYello}">Hello, World</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', data: {
isRed: true, isYello: false } })
</script>
这里进行简单优化后,class 的列表的增删与否通过具体的数据isRed
、isYello
进行控制
<!--version 3.0-->
<div id="app"><h1 :class="getClasses()">Hello, World</h1></div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isRed: true,
isYello: false,
},
methods: {
getClasses: function () {
this.isRed = false
this.isYello = true
return {
red: this.isRed, yello: this.isYello }
},
},
})
</script>
继续优化后,我们的 class 属性值通过一个方法返回一个 object,然后判断是否加入 class。我们还可以通过 v-on 来通过界面交互改变 isRed、isYello 的数据值,以达到改变界面显示的效果!
这种使用会经常应用在实际开发中,请务必熟悉掌握!
v-bind 动态绑定 style
其使用方式和上面的绑定 class 大同小异,我们通过一个 kv 集合对象来动态为标签添加样式!这种操作在组件化开发中很常见!
<div id="app">
<span :style="{fontSize: '50px', backgroundColor: 'blue'}">{
{message}}</span>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app', data: {
message: 'Hello World!' } })
</script>
这样写就感觉很鸡肋,然而其真正的用法应该是利用数据控制样式表的变化,或者使用 method 获取样式表。
<div id="app">
<span :style="{fontSize: spanFontSize + 'px'}">{
{message}}</span>
<span :style="getBgColor()">{
{message}}</span>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello World!', spanFontSize: 20, spanBgColor: 'blue' },
methods: {
getBgColor: function () {
return {
backgroundColor: this.spanBgColor }
},
},
})
</script>
有几个注意点:
- 传统样式表中带
-
的样式属性(例如font-size
等)在进行属性绑定时,属性名作为 key,要使用小驼峰命名法(lower-Camel-Case)。例如fontSize、backgroundColor
- k-v 在表示时一定要分清是变量还是字符串!key 作为属性名可以不使用字符串表示,但是 value 如果不加以区分,会导致 vue 解析失败。(例如:
:style={fontSize: 50px}
,很明显我们希望 50px 作为属性值被解析,但是 vue 会认为 50px 就是一个变量名,所以需要改写成::style={fontSize: '50px'}
)
3.5、条件插值
3.5.1、v-if、v-else、v-else-if
<body>
<!--根据绑定ViewModel中的数据判断显示哪个标签-->
<div id="p1">
<h1 v-if="message==='A'">A</h1>
<h1 v-else-if="message==='B'">B</h1>
<h1 v-else>C</h1>
</div>
<script src="../vue-js/vue.js"></script>
<script>
// vm 绑定 id=p1的Dom元素
var vm = new Vue({
el: "#p1",
data: {
message: "A"
}
});
</script>
</body>
3.5.2、v-show
v-show 使用效果与 v-if 相同,但是 v-show 是使用 css 的 display 属性来控制元素的显示:(v-show 在 template 中不能使用!)
<div id="app">
<!-- v-if则是直接通过增删标签来达到显示、隐藏 -->
<h1 v-if="display">{
{message}}</h1>
<!-- v-show会保证标签始终在DOM中,使用css的display属性来控制它的显示与否。不可用于template-->
<h1 v-show="display">{
{message}}</h1>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'hello world', display: false },
})
</script>
3.5.3、使用 key 来管理复用元素
Vue 在进行页面渲染时,为了保证效率会最大程度上复用页面元素。
我们修改了数据值导致页面重新渲染时,首先会在内存中创建虚拟 DOM,虚拟 DOM 使用
diff
算法会将旧页面和新页面都有的元素进行复用,然后将渲染完成的虚拟 DOM 渲染回浏览器上。
我们用一个案例来演示一下:
<div id="app">
<form v-if='loginType === "username"'>
<label>Username</label>
<input type="text" placeholder="Please input your username" />
</form>
<form v-else>
<label>Email</label>
<input type="text" placeholder="Please input your email" />
</form>
<button @click="toggleLoginType">Toggle Login Type</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
loginType: 'username' },
methods: {
toggleLoginType() {
if (this.loginType === 'username') {
this.loginType = 'email'
} else {
this.loginType = 'username'
}
},
},
})
</script>
即使我们使用按钮进行登录类型的切换,我们输入框中的内容依旧没有消失。这就很好地说明了我们的输入框(即 input 元素)被复用了,那么 label 元素也就必然被复用了。
可是如果我们想要切换了登录类型后,就清除原来输入的内容,简单说就是不复用这个 input 元素。我们就需要为这个元素加上特定的标识,在 Vue 中 元素的 key 属性是用于区分元素的关键。所以我们只需要给 input 元素绑定一个独一无二的 key 属性,告诉 Vue“它们是两个独立的东西,请不要复用!”
<form v-if='loginType === "username"'>
<label>Username</label>
<input
type="text"
placeholder="Please input your username"
:key="'usernameInput'"
/>
</form>
<form v-else>
<label>Email</label>
<input
type="text"
placeholder="Please input your email"
:key="'email-input'"
/>
</form>
<button @click="toggleLoginType">Toggle Login Type</button>
修改后,去试试效果!
3.6、列表渲染 v-for
3.6.1、遍历数组
遍历时,第二个可选参数 index 表示元素在数组中的下标!
<body>
<div id="p1">
<ul v-for="(letter, index) in letters" :key="index">
<li>{
{letter.element}}-->{
{index}}</li>
</ul>
</div>
<script src="../vue-js/vue.js"></script>
<script>
// vm 绑定 id=p1的Dom元素
var vm = new Vue({
el: '#p1',
data: {
letters: [{ element: 'A' }, { element: 'B' }, { element: 'C' }],
},
})
</script>
</body>
v-for 也会监听列表的变化,如果列表发生了变化会触发页面的更新!
v-for 还支持for-of
,更接近原生 JavaScript 的遍历。
3.6.2、遍历对象
除了遍历数组,还支持使用 v-for 遍历数组,遍历时有三个参数:{value, name, index}
,依次为属性值、属性名、属性下标!后两个参数为可选参数!
遍历的顺序与对象属性声明的顺序相同!
<div v-for="(value, name, index) in object">
{
{ index }}. {
{ name }}: {
{ value }}
</div>
<script src="../js/vue.js"></script>
<script>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10',
},
},
})
</script>
3.6.3、v-for 添加 key
这是 Vue 推荐我们在使用 v-for 的时候所做的操作。
当我们不为遍历元素绑定 key 的时候(默认),当列表插入值后,导致列表的数据顺序变化后,不会移动 DOM 元素来匹配列表的数据项。即列表的数据与 DOM 中的元素是没有绑定的!它会从发生了变化的位置挨个更新元素的值。
但是当我们使用:key
为元素绑定一个 key 以后,并且确保 key 与数据是可以做到一一对应的(index 无效),列表数据就可以与元素进行绑定。可以便于 Vue 追踪这个元素。当列表变化后,Vue 就可以通过元素进行复用和元素重排序来完成更高效的渲染工作。
注意一下,key 尽量不要使用 index,因为 index 无法保证数据变化时与数据保持对应关系!
3.6.4、数组更新检测
并不是所有的数组更新都会触发页面重渲染(例如直接通过下标修改数组)。(响应式更新)
支持更新检测的数组方法有:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
以上的方法属于数组变更方法,即是在原数组的数据上进行变动。当然也有非变更方法:
例如:filter()
、concat()
和 slice()
。这些方法调用后会返回一个新的数组,当我们将新数组赋值给原数据时,**页面会在保证元素重用最大化下进行重新渲染!**即相同的 DOM 元素会被保留重用!而不是丢弃原有所有 DOM 元素,将新的数组进行渲染到整个列表。
3.7、绑定事件 v-on
<body>
<div id="p1">
<!--绑定按钮点击事件-->
<button v-on:click="showMsg">Click Me</button>
</div>
<script src="../vue-js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#p1',
data: {
message: 'hello Vue' },
methods: {
showMsg: function () {
alert(this.message)
},
},
})
</script>
</body>
v-on: click=“xxx” 可缩写为 @click="xxx"
我们的事件监听回调函数是可以接收参数的!
如果我们的回调函数是有参数要求的,当你的绑定事件时,省略了函数调用的小括号,那么将默认将触发的事件作为第一个参数传入:
<div id="app">
<!--这里省略了小括号,当鼠标点击时,会将事件作为首个参数传入-->
<button @click="showMessage">点我</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
methods: {
showMessage(message) {
console.log(message)
},
},
})
</script>
于是控制台的输出效果就是:
3.7.1、修饰符
一个事件我们也可以分为很多状态,修饰符就用于指出一个指令以特殊的方式进行绑定。通过在事件后加上.xxx
来为事件加上修饰符。
@click.stop
:停止事件冒泡
<div id="app" @click="clickDiv">
text-content <button @click="clickBtn">点我</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
methods: