# 一、Vue介绍
官网:https://cn.vuejs.org
Vue.js是一套构建用户界面的**渐进式**框架。**声明式渲染和组件系统是Vue的核心库所包含内容。**
- 渐进式:循序渐进,不需要掌握全部的点,学多少用多少
- 框架:半成品的应用(之前学习的jQuery也是一个框架)
![Vue特点](https://storage.lynnn.cn/assets/markdown/91147/pictures/2020/09/4f9e45db623e2c0f0dd1a45e985c36b83825ce6c.png?sign=cead88c04c73c6d314f093b1ef504d42&t=5f50707e)
![Vue与react在github上](https://storage.lynnn.cn/assets/markdown/91147/pictures/2020/09/229fe902962263af21443024e14a78b54ea5c3d1.png?sign=976600758fc879cea5db0a54774e1bda&t=5f5070ea)
- **声明**式渲染:(如同js基础一样,要使用变量则必须先声明变量,这种称之为声明式)
Vue.js的核心是一个允许采用简洁的模板语法来声明式的将数据渲染进DOM的系统。
- **组件化**应用构建
组件系统是Vue的另一个重要概念,因为它是一种抽象的允许我们使用**小型、独立**和通常**可复用**的“小积木”构建大型应用。几乎任意类型的应用界面都可以抽象为一个组件树。
![组件](https://storage.lynnn.cn/assets/markdown/91147/pictures/2020/09/279e26e948d53d33a2a05e10e7c29aa736fe80a1.png?sign=9f63925b42a763bb945ad25cda41928f&t=5f5073bf)
- 基于**MVVM**
![MVVM](https://storage.lynnn.cn/assets/markdown/91147/pictures/2020/09/daf286bb718f7afb09ddea7205c58a18d56797f5.png?sign=9597d9d44c7ac8ace46d8ab7c0500407&t=5f560d40)
# 二、Vue入门
## 1、初识Vue
> vuejs文件分为“.min.js”与“.js”文件,区别在于其中带“.min”这个是生产版本(压缩版),不带“.min”的是测试版本(测试时用的,不压缩的):
>
> - 生产版本(vue.min.js)
> - 代码压缩(代码不具备可读性)
> - 不支持vue调试工具
> - 开发版本(vue.js)
> - 代码不压缩(代码具备可读性)
> - **支持vue的调试工具**
以输出“Hello World”为例,使用Vue.js实现输出“Hello World”案例:
> **步骤**(仅限在vue的非工程化的环境下)
>
> - 在视图部分定义渲染的容器,正常情况下内容相对固定,一般是:
>
> - ~~~html
> <div id="app"></div>
> ~~~
>
> - 通过`script`标签引入下载好的`vue.js`文件
>
> - 产生vue实例(js部分,需要去new)
>
> - 需要给实例传递配置选项(格式是一个对象)
> - 如果可能,会用到一些数据,数据需要在对象中声明(声明式渲染)
>
> - 如果需要展示数据的话,则需要使用特定的表达式(插值表达式,形式`{{表达式}}`,在视图部分写,哪里需要值就在哪里写)
代码片段如下:
~~~html
<body>
<!-- 1. 定义渲染的容器 -->
<div id="app">
{{msg}}
<div>
<!-- 只要不出id=app这个容器的界限,不管多少深度,都没问题 -->
{{msg}}
</div>
</div>
<!-- 2. 引入vue.js文件 -->
<script src="./js/vue.js"></script>
<script>
// 3. 产生vue实例(V是大写的),传递配置选项
new Vue({
// el => element,指定vue负责渲染的容器的选择器
el: "#app",
// data指定vue实例需要的数据(数据的初始化)
data: {
msg: "hello world",
},
});
</script>
</body>
~~~
Vue实例细节分析:
- Vue参数对象属性
- el:元素挂载的位置,值可以是CSS选择器或DOM元素
- data:模型数据,值是一个对象(仅限于当前)
- 插值表达式`{{msg}}`
- 将数据填充到HTML标签中
上述提及的都是前端vue框架的模板语法,当然vue的模板不仅仅是上述这个2个,还有更多的,比如后面要学习的:
- 指令
- 事件
- 流程控制
- ....
## 2、vue devtools工具安装
通过chrome中的谷歌插件商店安装Vue Devtools工具,此工具帮助我们进行vue数据调试所用,一定要安装。Vue工具在谷歌商店的地址是:https://chrome.google.com/webstore?utm_source=chrome-ntp-icon
> 请注意:打开chrome应用商店,**需要科学上网**才能访问到,至于怎么科学上网请各位自行解决。
![Vue工具谷歌商店](https://storage.lynnn.cn/assets/markdown/91147/pictures/2020/09/dc840deb63c247fb5b7fac6f162f3fece10832ae.png?sign=180564fbbac92d11b6e89e4e9d8df208&t=5f561a39)
安装好后打开Chrome的`开发者工具(F12或Ctrl+Shift+I)`即可使用:
![谷歌浏览器使用Vue工具](https://storage.lynnn.cn/assets/markdown/91147/pictures/2020/09/7ea8955be2b91f4c8530fdf7696fa2f5508b3a35.png?sign=2773c0e615128ca86b96c79bca31eaf4&t=5f561a6a)
**补充:如果自己解决不了科学上网问题,但是又需要用Vue开发工具那该怎么办?**
> 如果实在解决不了科学上网难题,Vue官方也提供了插件源码允许我们自己编译/构建Google Chrom插件,步骤如下(构建插件流程稍微麻烦一些<**不要求掌握如何构建**>,此处已为同学们构建好,可以直接使用)。
>
> ![Vue调试工具](https://storage.lynnn.cn/assets/markdown/91147/pictures/2020/08/6f094719844e04c1aa853b36c18b1e18c1ee6c2d.png?sign=55a5622a22b937b7b1b419ca67dafd6b&t=5f38fa24)
## 3、Vue模板语法
### 3.1、插值表达式
**插值表达式:**是vue框架提供的一种在HTML模板中绑定数据的方式,使用`{{变量名}}`方式绑定Vue实例中data中的数据变量,会将绑定的数据实时的在视图中显示出来。
插值表达式的写法支持使用:
- 变量名
- **部分**JavaScript表达式
- 注:`{{ }}`括起来的区域,就是一个就是js语法区域,在里面可以写部份的js语法。不能写 var a = 10;分支语句;循环语句
- 三元运算符
- 方法调用(方法必须需要先声明)
- ...
~~~html
<body>
<div id="app">
<!-- 直接使用变量名 -->
<h5>{{name}}</h5>
<!-- 运算 -->
<h5>{{name + '--好的'}}</h5>
<h5>{{ 1 + 1 }}</h5>
<!-- 使用函数 -->
<h5>{{title.substr(0,6)}}</h5>
<!-- 三目运算 -->
<h5>{{ age > 18 ? '成年' : '未成年'}}</h5>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
var vm = new Vue({
el: "#app",
data: {
title: "我是一个标题,你们看到没有",
name: "张三",
age: 20,
},
});
</script>
~~~
### 3.2、指令
**问1:什么是指令?**
- [x] 指令的本质就是标签中的vue**自定义属性**
- [x] 指令格式以“v-”开始,例如:v-cloak,v-text、v-html等
**指令的含义:在vue的html中,以`v-`开头的自定义属性就是指令。**
详见官网对指令的说明:https://cn.vuejs.org/v2/api/#%E6%8C%87%E4%BB%A4
**问2:指令有什么作用?**
正如插值表达式的效果,插值表达式只能用于标签之间的数据输出;在标签属性上,插值表达式无用武之地,但是有需要在属性中使用可变数据的情况,此时指令就能帮助我们解决这个问题。
语法糖:复杂操作的简化形式
当表达式的值改变时,将其产生的连带影响,响应式地作用于页面(DOM)。(简化操作)
**小试牛刀**:v-text指令与v-html指令【相当于innertHTML和innerText】
> **官网**
>
> v-text:https://cn.vuejs.org/v2/api/#v-text
>
> v-html:https://cn.vuejs.org/v2/api/#v-html
友情提醒:v-html尽量少用甚至不用,因为可能引发XSS(跨站脚本攻击,XSS)攻击。
~~~html
<body>
<div id="app">
<!-- 插值表达式形式 -->
<div>{{str1}}</div>
<!-- 插值表达式此时与v-text是等效的 -->
<div v-text='str2'></div>
<div v-html='str1'></div>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
str1: '迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。',
str2: '<a href="http://www.baidu.com">百度</a>'
}
})
</script>
~~~
# 三、常用指令
## 1、v-cloak
**作用:**解决浏览器在加载页面时因存在时间差而产生的`闪动`问题
**原理:**先隐藏元素挂载位置,处理好渲染后再显示最终的结果
**注意:**需要与CSS规则一起使用
**文档地址:**https://cn.vuejs.org/v2/api/#v-cloak
**示例:**
~~~html
<style>
[v-cloak] {
display: none;
}
</style>
<div v-cloak>
{{ message }}
</div
~~~
> 如果后期有多个元素需要解决闪动问题,可以将`v-cloak`写在根元素上(id="app"顶级的div上)。
## 2、数据绑定指令
- v-text 填充纯文本
- 相比插值表达式更加简洁
- 不存在插值表达式的闪动问题
~~~html
<div id='app'>
<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{msg}}</span>
</div>
<script src="./js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
msg:'<a href="http://www.baidu.com/">百度一下</a>'
}
})
</script>
~~~
- v-html 填充HTML片段
- 存在安全问题
- 本网站内部数据可以使用,来自第三方的数据不可使用
- 只有一个场景会使用:后台会用,比如有一个企业站,会发不企业的动态的新闻,这个时候会使用富文本编辑器,由于内容是自己人加的,所以可以放心使用。 自己攻击自己(自攻)
~~~html
<div id='app'>
<div v-html="html"></div>
</div>
<script src="./js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
html:'<a href="http://www.baidu.com/">百度一下</a>'
}
})
</script>
~~~
- v-pre 填充原始信息(对应的是以前html中的标签“<pre>”)【凑数】
- 跳过表达式的编译过程(先编译,后渲染),显示原始信息
~~~html
<span v-pre>{{ this will not be compiled }}</span>
~~~
> **有些时候我们不想指令中的表达式进行运行,只需要给表达式加个引号**。例如:
~~~html
<div v-html='"msg"'></div>
<div v-html="'msg'"></div>
~~~
针对后续想让指令属性值不解析的操作都可以这么去做。
## 3、v-once
**作用:**只渲染**元素或组件**一次**,之后元素或组件将失去**响应式(数据层面)功能(对于数据的一锤子买卖)
> **Q & A:**如何理解响应式?
>
> - 布局响应式:布局会随着设备尺寸的大小变化而变化的布局方式
> - **数据响应式:双向数据绑定**
**示例:**
~~~html
<div id="app">
<h3>{{message}}</h3>
<!-- 动态修改message值,此绑定将不会发生改变 -->
<div v-once>{{message}}</div>
</div>
<script src="./js/vue.js"></script>
<script type='javascript'>
const vm = new Vue({
el: '#app',
data: {
message: '你好世界'
}
})
</script>
~~~
## 4、v-bind(重点)
**作用:**动态地绑定一个或多个`attribute`【实现可以允许我们在html内置的属性值中使用变量,主要是给非指令的属性去使用绑定动态可变的数据的】
场景:复用某个数据的时候会使用。例如:飞猪官网
~~~html
<!-- v-bind:给非指令的属性使用变量 -->
<a v-bind:href="url" v-bind:target="target">{{alt}}</a>
<!-- v-bind的简写形式,实际使用这样的写法 -->
<a :href="url" :target="target">{{alt}}</a>
~~~
**示例代码**
~~~html
<body>
<div id="app">
<a :href="url" :target="type" :alt="alt">{{alt}}</a>
<a :href="url">{{alt}}</a>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
url: 'https://www.fliggy.com/',
type: '_blank',
alt: '飞猪官网'
}
})
</script>
~~~
## 5、v-on(重点)
### 5.1、基本使用(重点)
**作用:**绑定事件监听器(事件绑定)
**示例:**
~~~html
<!-- 直接执行操作 -->
<!-- 常规写法 -->
<button v-on:click="num++"></button>
<!-- 缩写 -->
<button @click="num++"></button>
<!-- 事件处理函数调用:直接写函数名 -->
<button @click="say"></button>
<!-- 事件处理函数调用:常规调用 -->
<button @click="say('sth')"></button>
~~~
如果事件处理函数为自定义函数,则需要先进行定义,定义的方式如下:
~~~javascript
...
data: {
...
},
methods: {
functionName: function(arg1,arg2,arg3,...){
// something to do
},
....
}
~~~
> 注意:事件绑定`v-on`属性表达式中切记不能直接写业务逻辑,例如`@click="alert('123')"`。换言之,就咋行内上是不允许使用内置函数的,必须要调用自己定义的函数,然后你可以在自定义的函数内使用内置函数。
**事件处理函数传参**
~~~html
<!-- 事件处理函数调用:直接写函数名 -->
<button @click="say"></button>
<!-- 事件处理函数调用:常规调用 -->
<button @click="say('hi',$event)"></button>
~~~
在不传递自定义参数的时候,上述两种用法均可以使用;但是如果需要传递自定义参数的话,则需要使用第2种方式。
> 事件对象的传递与接收注意点
>
> - 如果事件直接使用函数名并且不写小括号,那么**默认**会将事件对象作为唯一参数进行传递,可以在定义函数的位置直接定义一个形参,并且在函数内可以使用该形参
> - 如果使用常规的自定义函数调用(只要写了小括号),那么如果需要使用**事件对象则必须作为最后一个参数进行传递**,且事件对象的名称必须是“$event”
**示例代码**
~~~html
<style>
#big {
width: 300px;
height: 300px;
background-color: red;
}
#mid {
width: 200px;
height: 200px;
background-color: green;
}
#sma {
width: 100px;
height: 100px;
background-color: pink;
}
</style>
<body>
<div id="app">
<div id="big" @click="say('大娃',$event)">
<div id="mid" @click="say('二娃',$event)">
<div id="sma" @click="say('三娃',$event)"></div>
</div>
</div>
</div>
</body>
<script src="./js/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
},
methods:{
say: function(name,event){
console.log('你点了' + name);
}
}
})
</script>
~~~
### 5.2、事件修饰符
含义:用来处理事件的特定行为(也是vue提供一些语法糖)
使用示例:
~~~html
<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>
<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>
<!-- 串联修饰符(连贯操作) -->
<button @click.stop.prevent="doThis"></button>
~~~
更多事件修饰符请参考官方文档:https://cn.vuejs.org/v2/api/#v-on
**实例代码**
~~~vue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.dawa {
background: red;
width: 400px;
height: 400px;
}
.erwa {
background: orange;
height: 300px;
width: 300px;
}
.sanwa {
background: yellow;
height: 200px;
width: 200px;
}
</style>
</head>
<body>
<div id="app">
<!-- 套娃行为 -->
<div class="dawa" @click="call_dawa">
<div class="erwa" @click.stop="call_erwa">
<div class="sanwa" @click.stop="call_sanwa">
</div>
</div>
</div>
</div>
<script src="./js/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
},
methods:{
call_dawa(){
console.log('大娃:收到');
},
call_erwa(){
console.log('二娃:收到');
},
call_sanwa(){
console.log('三娃:你说啥');
}
}
})
</script>
</body>
</html>