抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

vue

VUE介绍与入门

为什么要学习vue:

  1. 开发更快速,更高效。
  2. 企业开发都在使用。
  3. 前段工程师必备技能,高薪。

vue是什么

渐进式javascript框架,一套拥有自己规则语法的框架。

库和框架:

库:封装的属性和方法(例如jQuery)

框架:拥有自己的规则和元素,比库强大的多(例vue)

库是方法的集合,而框架是一套拥有自己规则的语法

vue/cli脚手架

  • @vue/cli是Vue官方提供的一个全局模块包(得到vue命令),此包用于创建脚手架项目
  • 脚手架

如何安装@vue/cli

通过在终端输入yarn global add @vue/cli或则npm install -g @vue/cli进行全局安装

就会全局安装到你的电脑里

通过vue -V查看vue脚手架版本

如何创建一个vue脚手架项目

  1. 在要创建项目的地方打开终端(cmd)输入vue create 项目名称,项目名称尽量用英文(不要用中文!!),等待终端反应完成即可。
  2. 选择模板

如何启动vue脚手架项目

启动webpack内置热更新本地服务器

在项目根目录打开终端(cmd)输入yarn serve或者npm run serve启动本地热更新开发服务器

脚手架里主要文件的作用

  1. node_modules —— 都是下载的第三方包
  2. public/index.html —— 浏览器运行的主网页
  3. src/main.js —— webpack打包的默认入口文件
  4. src/App.js —— vue页面入口
  5. package.json —— 项目相关配置及依赖包配置

目录树:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
vuecil-demo        # 项目目录
├── node_modules # 项目依赖的第三方包
├── public # 静态文件目录
├── favicon.ico# 浏览器小图标
└── index.html # 单页面的html文件(网页浏览的是它)
├── src # 业务文件夹
├── assets # 静态资源
└── logo.png # vue的logo图片
├── components # 组件目录
└── HelloWorld.vue # 欢迎页面vue代码文件
├── App.vue # 整个应用的根组件
└── main.js # 入口js文件
├── .gitignore # git提交忽略配置
├── babel.config.js # babel配置
├── package.json # 依赖包列表
├── README.md # 项目说明
└── yarn.lock # 项目包版本锁定和缓存地址

项目架构了解

基于webpack和nodejs,项目运行会以入口文件开始进行加载,过程如下图

1
2
3
4
5
6
7
8
9
入口main.js
|
v
new Vue(Vue实例化) ————>(插入)index.html
| ∆
v | (标签+样式+数据)
App.vue根组件
| | |
组件1 组件2 组件3

main.js和App.vue,以及index.html作用和关系

  1. main.js – 项目打包入口 – Vue初始化

  2. App.vue – Vue页面主入口

  3. index.html – 浏览器运行的文件

  4. 以main.js为入口,数据流向:App.vue => main.js => index.html

修改webpack server端口号

因为使用的是@vue/cli脚手架,所以服务配置要写在vue.config.js里

在项目根目录下,通过修改vue.config.js文件更改端口号

1
2
3
4
5
6
module.exports = {
devServer:{ // 自定义服务器配置
port: 3000, // 设置端口号为3000
open: true
}
}

eslint代码检查工具

一种代码检查工具,此工具将会在服务启动时检查代码,并报告有误或者需要改进的地方。

假如在main.js中随意定义里变量,不实用,eslint将会报错

1
2
6:5 error 'a' is assigned a value but never used no-unused-vars
// 6行5列 错误 a变量已定义但从未使用过

处理eslint代码检查

方式一:手动解决掉错误

方式二:暂时关闭eslint检查,在项目更目录的vue.config.js中配置后重启服务

1
2
3
4
module.exports = {
// ...其他配置
lintOnSave: false //关闭eslint检查
}

如何关闭:在vue.config.js中设置lintOnSave为false重启服务器即可。

单vue文件讲解

vue项目开发原则:

  • vue推荐采用.vue文件来开发项目
  • template里只能有一个根标签
  • vue文件-独立模块-作用域互不影响
  • style配合scoped属性,保证样式只针对当前template内标签生效
  • vue文件配合webpack,把他们打包起来插入到index.html

vue文件内部

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- template必须,只能有一个根标签,如果不按要求讲影响渲染到页面的标签结构 -->
<template>
<div id='App'>欢迎使用vue</div>
</template>

<!-- js代码 -->
<script>
// 默认导出一个对象,里边的数据是vue框架双向数据绑定所要读取的值
export default {
name: 'App'
}
</script>

<!-- 当前组件的样式,设置scoped,可以保证样式只对当前页面有效 -->
<style scoped>
#app{
background: 'pink'
}
</style>

其实每一个.vue文件都可以当做一个组件,组件的介绍以及使用会在后面说。

vue脚手架创建后的欢迎界面清除

  • assets和components文件夹下的一切都删除掉(不要默认的欢迎界面)
  • src/App.vue默认有很多东西,可以全部删除留下template、script和style标签
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>

</template>

<script>
export default {
data(){
return{

}
}
}
</script>

<style>

</style>
  • 欢迎界面文件有assets下的图片和components下的文件,App.vue初始代码
  • 直接删除即可,但要留下Vue项目入口页面App.vue文件

Day01


Day02

vue基础-指令

1. 插值表达式

用于在dom标签中,直接插入内容

又叫:声明式渲染/文本插值

在dom标签中,直接插入vue数据变量,双 ,可以把vue的内容显示在标签内(相当于ES6的模版字符串,并且带有特殊功能的模版字符串)

  • 又叫:声明式渲染/文本插值
  • 语法:
  • mas和obj是vue数据变量
  • 要在js中data函数里声明

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div>
<h1>{{ msg }}</h1> <!-- Hello Vue !!! -->
<h3>{{ obj.name }}</h3> <!-- 小vue !!! -->
<h3>{{ obj.age }}</h3> <!-- 5 -->
</div>
</template>
<script>
export default{
data() {
return {
msg : 'Hello Vue !!!',
obj : {
name : '小vue'
age : 5
}
}
}
}
</script>
<style>

</style>

2.MVVM设计模式

vue内部代码运行机制图:

MVVM设计模式

设计模式:是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

view 为DOM层,vue里有数据和虚拟dom,通过model(js对象/数据)来进行渲染和操作。

  • MVVM,一种软件架构模式,决定了写代码的思想和层次
    • M: model数据模型 (data里定义)
    • V: view视图 (html页面)
    • VM: ViewModel试图模型 (vue.js源码)
  • MVVM通过 数据双向绑定 让数据自由地双向同步 不需要操作DOM
    • V(修改试图) -> (数据自动同步)
    • M(修改数据) -> (试图自动同步)

转变思维,用数据驱动试图改变,操作dom的事,vue源码内干了。

3.vue指令-v-bind

用于给标签属性设置vue变量的值

vue指令,实际上就是特殊的html标签属性,特点:以v-开头

每个指令都有独立的作用

  • 语法:v-bind:属性名="vue变量"
  • 简写::属性名="vue变量"推荐写法
1
2
3
<!-- vue指令-v-bind属性动态赋值 -->
<a v-bind:href="url(http://www.baidu.com)">百度一下</a>
<img :src="imgSrc">
v-bind指令 作用
:href a标签跳转
:src 标签路径
:变量名 一般用于给组件传变量

4.vue指令v-on

用于给标签绑事件

  • 语法
    • v-on:事件名=”要执行的 少量代码
    • v-on:事件名=”methods中的函数”
    • v-on:事件名=”methods中的函数(实参)”
  • 简写:@事件名=”methods中的函数”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<template>
<div>
<!-- vue指令: v-on事件绑定-->
<p>你要买商品的数量: {{count}}</p>
<button v-on:click="count = count + 1">增加1</button>
<button v-on:click="addFn">增加1个</button>
<button v-on:click="addCountFn(5)">一次加5件</button>
<button v-on:click="subFn()">一次减5次</button>
</div>
</template>
<script>
export default{
data(){
return{
count:1
}
},
methods:{
addFn(){
this.count++
},
addCountFn(num){
this.count += num
},
subFn(){
this.count--
}
}
}

</script>

绑定事件的简写示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div>
<button @click='fn'>
点击弹窗
</button>
</div>
</template>
<script>
export default{
methods:{
fn(){
alert('今天笔记真不错')
}
}
}
</script>

总结:常用@事件名,给dom标签绑定事件,以及 @事件名=右侧事件处理函数

5.vue指令v-on修饰符(事件修饰符)

用于给事件进行修饰,比如阻止默认跳转、阻止冒泡等

语法:

  • @事件名.修饰符=”methods里的函数”
    • .stop - 阻止事件冒泡(事件继续传播)
    • .prevent - 阻止默认行为
    • .once - 程序运行期间,只触发一次事件处理函数
    • .self - 点击的元素(即event.target)是当前元素自身时触发处理函数
    • .submit - 只有修饰符(后面可以跟.prevent),用于阻止元素(无论什么元素)默认事件
    • .passice - 滚动事件后执行(一般用与滚动事件,提升移动端端性能)

且事件修饰符可以叠加使用,比如@click.prevent.stop译为点击阻止默认事件和事件冒泡

6.v-on:key系列修饰符(按键修饰符)

当监听键盘事件是可以使用的修饰符

语法:

  • @keydown/keyup/keypress.修饰符=”methods里的函数”
    • .enter - 按下Enter回车键时
    • .tab - 按下tab键时
    • .delete - 按下del删除键时(捕获”删除”和”退格”键)
    • .esc - 按下esc退出键时
    • .space - 按下空格键时
    • .up - 按下键盘上方向键时
    • .down - 按下键盘下方向键时
    • .left - 按下键盘左方向键时
    • .right - 按下键盘右方向键时

系统修饰符(用于监听键盘事件当中的系统按键);

可以使用如下修饰符来实现仅按下相应按键时才出发鼠标或键盘事件的监听:

  • .ctrl - 当按下ctrl键时
  • .alt - 当按下alt键时
  • .shift - 当按下shift键时
  • .mate - 当按下win键时(当按下command键时-Mac系统)

.exact修饰符

.exact修饰符允许你控制由精确的系统修饰符组合触发的事件

1
2
3
4
5
6
7
8
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>

鼠标按键修饰符:

一样是v-on:key按键修饰符,在后面直接.就可以自定什么情况下调用函数。

  • .left鼠标左键按下时
  • .right鼠标右键按下时
  • .middle鼠标中键按下时

简写形式:

1
<button @key.left='fn'></button>

7.vue指令v-model()

作用:将DOM元素的value属性和vue数据变量双向绑定到一起

语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="app">
<!-- 在标签里写上v-model属性,字符串里写上data里返回的变量值 -->
<input v-model='text'/>
</div>

<script>
let demo = new Vue({
el:'#app',
data(){
return{
text:'vue很好用' // 当vue实例里的text值被修改时input的value值也将被修改
}
}
})
</script>

双向数据绑定

  • 数据变化 -> 视图自动同步
  • 视图变化 -> 数据自动同步

v-model修饰符

作用:可以将数据进行修饰,使v-model拥有更强大的功能

语法:

v-model.修饰符=”vue数据变量”

  • .number - 以parseFloat转成数字类型
  • .trim - 去除首位空白字符
  • .lazy - 在change(状态改变时)时触发而非input时

小结:v-model修饰符,可以对值进行预处理,非常高效好用

8.vue指令 v-text 和v-html

作用:更新Dom对象的innerText/innerHtml

语法:

  • v-text=”vue数据变量”
  • v-html=”vue数据变量”

注意:设置了v-text或v-html会覆盖标签里的插值表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div>
<p v-text="str"></p>
<p v-html="str"></p>
</div>
</template>

<script>
export default {
data() {
return {
str: "<span>我是一个span标签</span>"
}
}
}
</script>

注意2:v-text会把值转换成普通字符串显示,v-html会把值当作html解析。

9.vue指令v-show和v-if

作用:通过vue变量控制标签的显示/隐藏或保留/删除

语法:

  • v-show=”vue变量”
  • v-if=”vue变量”

原理:

  • v-show 使用display:none隐藏(一般频繁切换时使用)
  • v-if 直接从DOM树上移除组件元素

高级:v-if 和 v-else 的配合使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>
<h1 v-show="isOk">v-show的盒子</h1>
<h1 v-if="isOk">v-if的盒子</h1>

<div>
<p v-if="age > 18">我成年了</p>
<p v-else>还得多吃饭</p>
</div>
</div>
</template>

<script>
export default {
data() {
return {
isOk: true,
age: 15
}
}
}
</script>

10.vue指令v-for(循环)

作用:for循环遍历数据,生成数据对等的DOM元素

语法:

  • ```html
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71

    - `<li v-for="item in arr"> </li>`

    目标数据可以是数组、对象、数字、字符串(可遍历对象)

    *注意:v-for的临时变量名不能到v-for范围外*

    ```html
    <template>
    <div id="app">
    <div id="app">
    <!-- v-for 把一组数据, 渲染成一组DOM -->
    <!-- 口诀: 让谁循环生成, v-for就写谁身上 -->
    <p>学生姓名</p>
    <ul>
    <li v-for="(item, index) in arr" :key="item">
    {{ index }} - {{ item }}
    </li>
    </ul>

    <p>学生详细信息</p>
    <ul>
    <li v-for="obj in stuArr" :key="obj.id">
    <span>{{ obj.name }}</span>
    <span>{{ obj.sex }}</span>
    <span>{{ obj.hobby }}</span>
    </li>
    </ul>

    <!-- v-for遍历对象(了解) -->
    <p>老师信息</p>
    <div v-for="(value, key) in tObj" :key="value">
    {{ key }} -- {{ value }}
    </div>

    <!-- v-for遍历整数(了解) - 从1开始 -->
    <p>序号</p>
    <div v-for="i in count" :key="i">{{ i }}</div>
    </div>
    </div>
    </template>

    <script>
    export default {
    data() {
    return {
    arr: ["小明", "小欢欢", "大黄"],
    stuArr: [
    {
    id: 1001,
    name: "孙悟空",
    sex: "男",
    hobby: "吃桃子",
    },
    {
    id: 1002,
    name: "猪八戒",
    sex: "男",
    hobby: "背媳妇",
    },
    ],
    tObj: {
    name: "小黑",
    age: 18,
    class: "1期",
    },
    count: 10,
    };
    },
    };
    </script>

Day02


Day03

vue核心部件

认知引导、概念引入:

虚拟DOM

本质就是一个JS对象,保存DOM关键信息。

好处:提高DOM更新的性能,不频繁操作真实DOM,在内存中找到变化部分,再更新真实DOM(打补丁)

虚拟DOM比较

在新旧dom中比较出不一样的部分,将不一样的部分插入dom树,不用重新渲染,减少性能消耗。

在v-for遍历生成的DOM中,可以通过设置的:key值,比对新旧DOM结构的不同从而将更新的地方进行渲染,达到减少性能消耗的目的。

以后vue数据更新:

  • 生成新的虚拟DOM结构
  • 和旧的虚拟DOM结构对比
  • 利用diff算法, 找不不同, 只更新变化的部分(重绘/回流)到页面 - 也叫打补丁

==好处1: 提高了更新DOM的性能(不用把页面全删除重新渲染)==

==好处2: 虚拟DOM只包含必要的属性(没有真实DOM上百个属性)==

diff算法

vue用diff算法,新虚拟dom,和旧的虚拟dom比较

情况1:跟元素变了,删除重建

旧虚拟DOM

1
2
3
<div id="box">
<p class="my_p">123</p>
</div>

新虚拟DOM

1
2
3
<ul id="box">
<li class="my_p">123</li>
</ul>
情况2: 根元素没变, 属性改变, ==元素复用==, 更新属性

旧虚拟DOM

1
2
3
<div id="box">
<p class="my_p">123</p>
</div>

新虚拟DOM

1
2
3
<div id="myBox" title="标题">
<p class="my_p">123</p>
</div>

动态class

利用v-bind设置元素标签的动态class

语法:

1
2
3
4
5
6
7
8
9
10
<!-- 1.在标签里使用v-bind通过变量设置class值 -->
<div v-bind:class="uuu"> 测试 </div>
<!-- 2.简写 -->
<div :class="uuu"> 测试 </div>
<!-- 3.通过变量判断是否给予类名(true使用,false不用) -->
<div :class="{类型:布尔值}"> 测试 </div>
<!-- 4.三元表达式自定义取值 -->
<div :class=" isCheck ? 'active' : '' ">
判断变量isCheck是true还是false,如果true设置actice类名,反之取空字符串
</div>

动态style

用于给标签设置动态的style值

语法::style="{css属性名:值}"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div id="app">
<p :style="{color:colorStr}">
这是一段小小的段落
</p>
</div>
---
<script>
new Vue({
el:"#app",
data(){
return{
colorStr:'blue'
}
}
})
</script>

给style赋值和动态class有什么区别

动态class: :class="{类名:布尔值}",true使用,false不使用

动态style: :style="{css属性名:值(字符串)}"直接写成style样式

vue过滤器

过滤器只能在:插值表达式v-bind表达式 里使用

使用场景:

  • 字母转大小写
  • 字符串翻转

定义过滤器的语法:

  • 全局作用域

    1
    Vue.filter("过滤器名",()=>{return "返回处理后的值"})
  • 局部作用域 - 在vue实例对象里挂载filter属性,里边写过滤器名称

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    new Vue({
    ...
    filter:{
    // 参数1为要过滤的数据
    过滤器名称(a){
    return a.toUpperCase()
    }
    }
    ...
    })

过滤器的使用:

1
2
3
4
5
<template>
<div>
<h1>{{'Hello wolrd | 过滤器名称'}}</h1>
</div>
</template>

注意⚠️:

  • 过滤器需要 先定义后使用
  • 局部过滤器只可在局部使用,全局过滤器可在全局使用

多过滤器的使用

  • 过滤器传参:vue变量|过滤器(实参)
  • 多过滤器:vue变量|过滤器1|过滤器2

多过滤器将将vue变量依次从 左往右 进行过滤,过滤器1 返回的值将会接着由 过滤器2 进行过滤

计算属性computed

一个数据依赖另一些数据计算而来的结果

【 底层根据 Object.defineProperty——ES5新增对象方法 设计 】

语法:

1
2
3
4
5
computed:{
'计算属性名'(){
return '值'
}
}

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>
<!-- 30 -->
<p>{{num}}</p>
</div>
</template>

<script>
export default{
data(){
return{
a:10,
b:20
}
},
computed:{
num(){
return this.a + this.b // 10 + 20
}
}
}
</script>

注意⚠️:

  1. 计算属性只会根据vue实例里的data里设置的变量的变化而进行计算,用法和data形同
  2. 计算属性的名称和data属性都是变量不能重名
  3. 函数那变量变化,会自定重新计算结果返回

计算属性 - 缓存

因为计算属性是基于他们的依赖项的值结果进行缓存的,只要依赖的变量不变,都直接从缓存取结果

一句话概括:当计算属性里的值变化了之后,才会触发计算属性重新计算值,并且计算得得内容会保存在缓存里,使用时不会触发计算属性。

计算属性 - 完整写法

计算属性也是变量,当需要直接赋值时要使用完整写法

语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
computed:{
"属性名":{
// set和get为固定写法,分别代表计算属性在获取和设置的时候进行的计算过程
// 参数1为给计算属性设置的值,内部可以写计算属性的值被更改后执行的代码
set(){
console.log()
},
get(){

}
}
}

// 官方解释
var vm = new Vue({
data: { a: 1 },
computed: {
// 仅读取
aDouble: function () {
return this.a * 2
},
// 读取和设置
aPlus: {
get: function () {
return this.a + 1
},
set: function (v) {
this.a = v - 1
}
}
}
})
// 访问计算属性时将按get函数里的方法执行并返回新的访问值(不会叠加)
vm.aPlus // => 2
// 给计算属性赋值的时候根据set函数里的方法执行并返回新的值(不会叠加)
vm.aPlus = 3
vm.a // => 2
// 仅读取时
vm.aDouble // => 4
小节:
  1. 必须return值

  2. 会缓存计算值

  3. 同步计算

  4. 计算属性名 不能和data中的对象的键一致

  5. 中有两个方法 getter 和 setter,即可以复制也可以被赋值

VUE侦听器 - watch

可以侦听data/computed属性值的变化

大白话:监听vue里data里还有计算属性的变化而进行动作的工具

语法:

1
2
3
4
5
6
7
watch:{
// 参数1为新值,参数2为旧值
"被侦听的属性名"(newVal,oldVal){
console.log('原来的值为:',oldVal)
console.log('更新后的值为:',newVal)
}
}

深度侦听和立即执行

深度侦听一般用于对象或者数组这些复杂数据类型的数据

语法:

1
2
3
4
5
6
7
8
9
10
11
watch:{
"要侦听的属性名":{
// immediate 在vue实例创建时立即执行监听函数
immediate:true, // 立即执行
deep:true, // 是否深度监听,用于多层嵌套的对象和数组
handler(newVal,oldVal){
console.log("新值",newVal)
console.log("旧值",oldVal)
}
}
}

想要侦听一个属性变化,可使用侦听属性watch

注意⚠️:

  • 不要在侦听器里改data或计算属性的值,因为当更改了值后又会触发侦听器,会让程序进入 死循环
  • 侦听器正常情况下只能侦听vue实例里变化的值,而不能侦听其他区域的值(当然会设置的可以)。

Day03


Day04

vue组件

概念:

每一个vue文件都是一个vue组件,每一个组件都是一个独立的个体,里边的变量、html结构和css都是独立的,互补干扰的。

组件化概念

1.创建使用组件

步骤:

  1. 先要在vue文件里使用import导入另一个vue文件(组件),路径为相对路径
  2. 在compnents对象里以组件名称:组件形式组册
  3. 在template模版标签里使用 - <组件名称></组件名称>

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<div>
<!-- 3.在这里使用组件 -->
<myHeader></myHeader>
</div>
</template>
<script>
// 1.先导入组件文件
import myHeader from '@/components/myHeader.vue' // 如果是vue结尾的文件可以省略后缀不写
export default{
...
// 2.在components属性上组册组件
components:{
myHeader // 键值相同可以省略值不写
}
}
</script>

组件进阶

动态组件Component

作用:可以通过变量名控制显示哪个组件

语法:

1
<component :is="组件名称(可以使用变量-值的类型为字符串)"></component>

通过v-bind:is属性控制组件区使用哪个组件,组件名称可以通过挂载在vue实例上的data数据里的 变量控制

组件缓存(keep-alive)

作用:组件切换会导致组件被频繁销毁和重新创建,性能不高,利用组件缓存可以提高性能。

使用vue内置的Keep-alive标签包裹组件,可以让组件保存在内存中不被销毁

使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 主vue文件 -->
<template>
<div id="app">
<!-- 使用keep-alive标签将组件标签包裹起来 -->
<keep-alive>
<!-- 通过is属性设置动态的组件名 -->
<component :is="comName"></component>
</keep-alive>
</div>
</template>
<script>
new Vue({
el:"#app",
...
})
</script>

注意⚠️:使用组件缓存在第一次加载的时候会触发组件创建阶段的钩子函数,之后就不会再触发创建阶段的钩子函数( beforeCreate/created )了。

组件的激活和非激活

:被缓存的组件不再创建和销毁,而是激活和非激活。

补充2个钩子函数(使用在组件里头):

  • activated - 激活时触发
  • deactivated - 失去激活时触发

组件插槽slot

用于实现组件的内容分发,通过slot标签,可以接收到写在组件标签内的内容

vue提供组件插槽的能力,允许开发者在封装组件时,把不确定的部分定义为插槽

语法口诀:

  1. 组件内使用占位
  2. 使用组件时<组件名></组件名>组件内容区,传入template标签代替slot,template标签内写slot:区块名对应传入组件的DOM结构或内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!-- 主vue文件,例如组件名为Pannel -->
<template>
<div>
<Pannel>
<!-- 组件标签内容区 = 插槽内容区 (start) -->
<ul>
<li>张三</li>
<li>李四</li>
<li>王五</li>
<li>赵六</li>
</ul>
<!-- 组件标签内容区 = 插槽内容区 (end) -->
</Pannel>
</div>
</template>

--------------------------------------------------

<!-- 组件内 -->
<template>
<div>
...
<p>
<!-- slot标签为插槽 -->
<slot>
默认内容
默认内容
默认内容
</slot>
</p>

...
</div>
</template>

slot插槽默认内容

如果外面没传内容,想显示默认内容

夹着内容默认显示内容,如果不给插槽slot传东西,则使用夹着的内容在原地显示。

1
2
3
4
5
6
7
8
<!-- 组件内 -->
<template>
<div>
<slot>
<p>默认内容</p>
</slot>
</div>
</template>

具名插槽

当组件内部有2处以上需要外部传入内容的地方时,就要用到具名插槽

简单理解就是给插槽分区域、取名字

传入的标签可以分别派发给不同的slot标签位置

要求:v-slot一般用根template标签使用(template是html5新出的标签内容模块元素,不会渲染到页面上,一般被vue解析为内部标签)

语法:

  • tamplate标签内写v-solt:插槽区块名或直接#插槽区块名 (使用时)
  • slot标签内写name="插槽区块名" (定义时)
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 主vue文件,组件名称假定Pannel -->
<Pannel>
<!-- 写法一 -->
<template v-solt:title>

<template>
<!-- 写法二 -->
<template #content>

</template>
</Pannel>

-----

注意方法一定要一一对应

使用方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!-- 主vue文件 -->
<template>
<div>
<Pannel>
<!-- 使用template标签分开写插槽内容,通过 v-slot:插槽具名 来区分不同区域 -->
<template v-slot:title>
<h4>标题</h4>
</template>
<!-- 也可使用#号代替v-slot: -->
<template #content>
内容
</template>
</Pannel>
</div>
</template>

------------

<!-- 组件内 -->
<template>
<div>
...
<!-- name属性为插槽的具名(区块名) -->
<slot name='title'>
<h3>标题</h3>
</slot>
<p>
<!-- name属性为插槽的具名(区块名) -->
<slot name='content'>
默认内容
默认内容
默认内容
</slot>
</p>
...
</div>
</template>

作用域插槽

作用:可以在父组件使用字组件里的属性值或变量

实现步骤:

  1. 子组件,在slot上绑定属性和子组件内的值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <slot :row="obj"></slot>
    ...
    <script>
    export default{
    return{
    obj:{name:'张三',age:18}
    }
    }
    </script>
  2. 使用组件,传入自定义标签,用template和v-slot=”自定义变量名”

    1
    2
    3
    4
    5
    6
    <Pannel>
    <!-- space为自定义变量名(数据类型为对象),存的是子组件插槽标签slot中的所有属性值,通过.来访问 -->
    <template v-slot="space">
    姓名:{{space.row.name}},年龄:{{space.row.age}}
    </template>
    </Pannel>
  3. 自定义变量名会自动绑定slot上所有属性和值

组件常见情况

常见:即要用到slot插槽名称又要使用子组件内的数据时!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- 主vue文件,假设组件标签为Pannel -->
<template>
<div>
<Pannel>
<!-- 通过 v-slot:插槽名称="自定义变量名" 自定义变量名里 -->
<template v-slot:title="space">
{{space.row}}
</template>

<!-- 也可以通过 #插槽名称="自定义变量名" 自定义变量名里 -->
<template #title="space">
{{space.row}}
</template>
</Pannel>
</div>
</template>

<!-- 子组件内容 -->
<template>
<div>

</div>
</template>

vue内置方法

this.中的方法

this.$nextTick()

nextTick(),是将回调函数延迟在下一次dom更新数据后调用

简单理解:

当数据更新了,在dom中渲染后,自动执行该函数

方法的参数为一个函数,函数里写的是数据更新dom渲染后要执行的内容

自定义指令directive

背景:在vue现有指令不能满足你需求的时候,可以自定义指令完成一些自定义功能。(在设置自定义指令时可自定义设置功能,在仅有的架构里写逻辑就行)

两个地方定义自定义指令(固定写法)

  1. 全局 - 在入口文件(main.js)中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // main.js入口文件内部
    Vue.directive('指令名称',{
    // 页面dom已生成
    inserted(el,bind){ //形参el代表使用此自定义指令的元素,bind为指令上绑定的各种属性,里边包括value值
    console.log(el) //打印真实dom
    console.log(bind.value)
    el.style.color = bind.value //给元素设置颜色
    },
    // update类为数据变化时触发
    update(el,binding){ //el代表使用此自定义指令的元素,binding为数据变化后的指令上绑定的各种属性

    }
    })
  2. 局部 - 在vue文件中设置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    <template>
    <div>
    <!-- 在标签里使用自定义属性v-自定义属性名 -->
    <h3 v-Color="color" @click="color='skyblue'">Vue一定拿下</h3>
    </div>
    </template>

    <script>
    export default {
    data() {
    return{
    color:'green'
    }
    },
    //在vue实例内部定义directives
    directives: {
    // 指令名称:{
    Color: {
    // // 形参el代表使用此自定义指令的元素,bind为指令上绑定的各种属性,里边包括value值
    inserted(el,bind) {
    el.style.color = bind.value;
    },
    // el为绑定指令的元素,binding为更新后的数据
    update(el,binding){
    console.log(el)
    console.log(binding)
    el.style.color = binding.value;
    }
    }
    }
    };
    </script>

5.组件数据流

父组件向子组件传输数据:(父向子)

操作步骤:

  1. 先在父组件里导入子组件import

    1
    2
    // 父组件
    import 子组件名字A from '子组件路径A'
  2. 在父组件里组册子组件(components)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 父组件
    data(){
    return {
    msg:'hello world!'
    }
    }, // components 与data同级,在最外一层
    components:{
    子组件名称A:子组件,
    子组件名称B:
    }
  3. 在子组件里定义 props 接收数据

    1
    2
    // 与data同级,值为一个数组
    props:['变量a','变量b'...]
  4. 在父组件里传递要用的变量(数据),通过使用组件,在组件里设置v-bind传递变量(数据)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <!-- 父组件 -->
    <template>
    <div>
    <!-- 使用组件 -->
    <A v-bind:msg='msg'></A>
    </div>
    </template>
    <script>
    export default {
    data(){
    return {
    // 要用的变量msg
    msg:'hello world!'
    }
    }
    }
    </script>
  5. 在子组件里的template标签里使用msg

    1
    2
    3
    4
    5
    6
    7
    <!-- 子组件 -->
    <template>
    <div>
    <!-- 在子组件里使用传递过来的msg -->
    <h1>{{msg}}</h1>
    </div>
    </template>

子组件向父组件通讯:(子向父)

因为vue的数据是单向数据流,从下至上的数据传递是不行的,只能通过子组件和父组件绑定自定义事件,让通过子组件控制父组件修改父组件的数据。

操作步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
父组件内

<template>
<div>
<!-- 3.使用子组件 4.在子组件里绑定自定义事件-->
<子组件A v-on:自定义事件名称="Fn()" ></子组件A>
</div>
</template>

<script>
// 1.导入子组件
import 子组件A from '子组件A路径'
export default {
data(){
retrun{
num:30
}
},
compunents:{
// 2.组册子组件
子组件A名称:子组件A
},
methods:{
// 5.定义事件要触发的函数
Fn(add){
this.num += add
console.log(num)
}
}
}
</script>

------------------- 子组件内
<template>
<div>
<!-- 1.在子组件的元素上绑定上触发函数的事件 -->
<button @click="fn(10)">加10</button>
</div>
</template>

<script>
export default {
methods:{
// 2.定要触发的函数
fn(a){
// this指vue实例,$emit为vue实例里挂载的一个方法,用于触发当前组件的父组件的自定义事件
// 参数一为自定义事件名(在父组件里定义的),参数二往后都是传递参数,可在父组件使用
// 3.触发父组件的自定义事件(完毕)
this.$emit('自定义事件名',a)
}
}
}
</script>

大概步骤:

  • (父组件)导入子组件并组册使用

  • (父组件)给子组件绑定自定义事件(在子组件标签里@自定义事件)

  • (父组件)定义自定义事件触发的函数

  • (子组件)子组件里通过$emit()触发自定义事件

    $emit()

    • 参数1:自定义事件名
    • 参数2、3、4….:传递的参数

跨组件通信eventBus(事件总线)

无论两个组件是什么样的关系,通过eventbus事件总线,都可以相互通信,甚至可以一个事件串通全部组件,相当于一个公众号,只要订阅了的人都可以收到消息并与之对话。

使用步骤:

1
2
3
4
5
<template>
<div>
vue
</div>
</template>

大概步骤:

  1. 新建vue文件

Day04


Day05

vue生命周期

一句话:vue实例从创建到销毁的过程就是vue的生命周期

生命周期阶段表

阶段 方法名(钩子函数) 方法名(钩子函数)
初始化 beforeCreate created
挂载 beforeMount mounted
更新 beforeUpdata updated
销毁 beforeDestroy destroyed

8大钩子函数

1.初始化前(beforeCreate):

第一个生命周期函数,此时组件的data和methods以及页面DOM结构,都还没有初始化,所以这里什么都做不了,

2.初始化(create):

第二个生命周期函数,此时,组件中的data和methods可用,但页面还没渲染出来(DOM不能获取),在函数中我们经常会 发起ajax请求

3.挂载前(beforeMount)

当模版在内存中编译完成,立即执行该函数,此时内存中的模版结构还没真正渲染到页面上,页面上看不到真实的数据,此时用户看到的只时一个模版而已

4.挂载(mount)

组件创建最后阶段,此时页面已经真正的渲染好了,用户已经可以看到真实的页面数据了,改生命周期函数执行完毕,组件就离开了创建阶段,进入运行阶段;如果大家用到一些第三方UI插件,而且该插件需要被初始化,那么必须在mounted中来初始化插件。

5.更新前(beforeUpdata)

此时数据肯定是最新的,但页面上呈现数据还是旧的

6.更新完毕(updated)

页面已经完成了更新,此时data数据是最新的,同时,页面上呈现的数据,也是最新的

7.即将销毁前(beforeDestroy)

执行该函数的时候,组件将被销毁,但还没有真正开始销毁,此时组件还是正常可用的,data、methods等数据或方法,依然可以被正常访问。

8.组件销毁完毕(destroyed)

组件销毁完毕了,组件废了,当前为vue实例最后一个钩子函数,执行完此勾子函数,vue实例就被销毁了。(经常在此函数里,结束一些异步进程,比如定时器等,以防内存泄漏)

Vue生命周期图:

vue生命周期图

vue的路由(vue-router)

生活中的路由:设备与路由器的映射关系

编程中的路由:地址与网页的映射关系(路径和组件的映射关系)

vue中的路由:组件和路径的映射关系

单页面应用:所有网站内容由一个html页面完成显示(替换body位置的内容)

Vue-router相当于a标签跳转,但它并不会跳转,可以将链接获取的html渲染到指定位置

为什么要使用路由:

  • 优点:
    1. 整体不刷新页面,用户体验更好
    2. 数据传递容易,开发效率高
  • 缺点:
    1. 开发成本高(需要学习专门知识)
    2. 首次加载会比较慢一点,不利于seo(搜索引擎优化)

vue-router一句话概括:

可以通过地址变更,控制组件显示隐藏的东西

官方说明

Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:

  • 嵌套的路由/视图表

  • 模块化的、基于组件的路由配置

  • 路由参数、查询、通配符

  • 基于Vue.js过度系统的视图过度效果

  • 细粒度的导航控制(细粒度模型,通俗的讲就是将业务模型中的对象加以细分,从而得到更科学合理的对象模型,直观的说就是划分出很多对象.)

  • 带有自动激活的CSS class的链接

  • HTML5历史模式或hash模式,IE9中自动降级

  • 自定义的滚动条行为

    ……

使用步骤:(脚手架中)

  1. 下载安装vue-router

    在项目文件夹里安装打开终端(cmd)输入:

    yarn add vue-router -D 或者 npm install vue-router

  2. 引入vue-router

    在入口文件(main.js)引入vue-router

    1
    import VueRouter from 'vue-router'
  3. 使用路由组件

    在入口文件(main.js)中

    1
    2
    // 在vue中,使用vue的插件,都需要调用Vue.use()
    Vue.use(VueRouter)
  4. 书写规则(路由地址表) —— routes

    定义一个变量保存 规则(路由地址表) ,数据结构为 数组

    一个路由地址一个对象,一个地址对应一个组件,组件通过import导入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const routes = [
    {
    path:"/find", // 路由url地址
    component:Find // 对应加载的组件
    },
    {
    path:"/my",
    component:My
    }
    ...
    ]
  5. 创建路由对象 - 传入规则 —— router

    1
    2
    3
    4
    5
    6
    7
    const router = new VueRouter({
    routes:routes // 储存规则
    })
    // 属性名和变量名一致的时候可简写
    const router = new VueRouter({
    routes // 储存规则
    })
  6. 注入路由对象

    1
    2
    3
    4
    5
    6
    7
    new Vue({
    router:router123
    })
    // 属性名和变量名一致的时候可简写
    new Vue({
    router
    })
  7. 组件component换成router-view

    将需要动态根据路由地址渲染的标签写到相应位置,标签会渲染成对应组件内容

    1
    <router-view></router-view>
  8. 使用路由

    在主vue文件里通过a标签href值来进行路由跳转,hash模式下需要以”/#/“开始传路由地址,history(之后会有router-link代替)

    1
    <a href="#/find">发现</a>

总结:

  1. 下载路由模块,便携对应规则注入到vue实例上,使用router-view挂载店显示切换到路由
  2. 一切都围绕着路由地址的变化而变化

声明式导航 -以及- 跳转传参

声明式渲染

可利用组件中的router-link来替代a标签,to属性代替href属性

1
<router-link to="/find">发现页</router-link>

跳转传参

在router-link上的to属性传值,语法格式:

1
2
3
4
<!-- 配合query的传参数 -->
<router-lick to="值?属性=属性值"></router-lick>
<!-- 配合params的传参数 -->
<router-lick to="值/属性=属性值"></router-lick>
  • /path?参数名=值 ()
  • /path/值 —— 需要路由对象提前配置path:”/path/参数名”

对应页面组件接收传递过来的值,通过插值进行使用

1
2
<p>{{ $route.query.name }}<p>
<p>{{ $route.params.username }}</p>
  • $route.query.参数名 —— 通过path跳转时
  • $route.params.参数名 —— 通过name跳转时

总结:

  1. 使用path切换路由时,只能通过query传参
  2. 使用name切换路由时,可以通过query也可以通过params传参接收
  3. 推荐使用name + parmas 传参

声明导航 - 类名区别

router-link自带的2个类名的区别是什么

  • router-link-exact-active (精准匹配) url中hash值路径,与href属性值完全相同,设置此类名
  • router-link-active (模糊匹配) url中hash值,包含href属性值中的路径(不包含#)

路由重定向

设置访问默认网页时,默认的路由地址

在路由配置表里设置

1
2
3
4
5
6
7
8
const routes = [
{
path:"/",
// redirect定义重定向(默认的路由地址)地址
redirect:"/find" // 默认path地址
}
]

路由404(找不到路径的提示页面)

1
2
3
4
5
6
const routes = [
{ // 当找不到路径时
path:'*', // *表示找不到对应路径时的路径
component:NotFound // 对应的组建
}
]

路由模式

一共有两种路由模式:

  1. 默认的是hash路由
  2. 项目发布运营时为history路由

如何设置:在main.js或路由配置文件router/index.js(放哪可以自定)里

1
2
3
4
5
// 创建路由对象
const router = new VueRouter({
routes,
mode:"history" //设置路由模式
})

路由跳转

编程式导航

用js代码来进行跳转

前置:需要在路由规则表里定义好路由名称或路由地址

语法: path 或者 name 任选一个

1
2
3
4
5
// 可以通过点击事件触发以下代码进行跳转
this.$router.push({
path:"路由路径", // 都在路由规则表里定义
name:"路由名"
})

编程式导航 - 跳转传参

query或者params任选一个,对应使用

  • hash模式配合query方式传参
  • histary模式配合params方式传参

当前位置:

1
2
3
4
5
6
7
8
9
10
11
12
this.$router.push({
path:"路由路径",
name:"路由名", // path和name选其一
query:{
"参数名": 值,
username: 值
},
params:{
"参数名": 值,
age: 值
}
})

跳转到的位置里接收值:

1
2
3
4
5
6
7
<template>
<div>
<!-- 通过$route.query.参数名接收值 -->
{{ $route.query.username }}
{{ $route.params.age }}
</div>
</template>

注意⚠️

  • 在存放路由配置的文件里是 **$router.**push 进行跳转,在跳转到的组件里是 **$route.**query 或 .params 接收

路由嵌套 —— 二级路由

路由里在嵌套路由/find/KingTop

通过在路由规则表里设置,在一级路由里设置 children属性 ,children的值为一个数组,存放二级路由的对象,二级路由对象里的path地址不需要在前面加/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const routes = [
{
path:'/layout'
component:Layout,
children:[
{
path: 'home',
component: Home
},
{
path: 'find',
component: Find
},
{
path: 'play',
component: Play
},
]
}
]

全局路由前置守卫beforeEach

用于一些需要登录验证的网站,比如(网易云音乐),功能如字面意思,一个保安大爷的职责,在没有没有”门禁卡”的情况下,不允许访问一些页面

使用方法:在路由对象上使用固定方法beforeEach

语法:

1
2
3
4
5
6
7
8
9
10
let isLogin = false // 默认未登录
router.beforeEach(function(to,from,next){
// 判断条件
if(to.path === '/my' && isLogin === false){
alert('请登录')
next(false) // 阻止路由跳转
}else{
next() // 正常放行
}
})

beforeEach方法里的参数为 函数 , 函数里的参数:

  • 参数1 - 去向:要跳转到的路由(路由对象信息) - 目标
  • 参数2 - 来自:从哪里跳转的路由(路由对象信息) - 来源
  • 参数3 - 函数体:执行next()才会让路由正常的跳转切换(里面是布尔值),true为跳转,false为留在原地。

在main.js(入口文件里)使用router里的beforeEach方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 目标: 路由守卫
// 场景: 当你要对路由权限判断时
// 语法: router.beforeEach((to, from, next)=>{//路由跳转"之前"先执行这里, 决定是否跳转})
// 参数1: 要跳转到的路由 (路由对象信息) 目标
// 参数2: 从哪里跳转的路由 (路由对象信息) 来源
// 参数3: 函数体 - next()才会让路由正常的跳转切换, next(false)在原地停留, next("强制修改到另一个路由路径上")
// 注意: 如果不调用next, 页面留在原地

// 例子: 判断用户是否登录, 是否决定去"我的音乐"/my
const isLogin = true; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
if (to.path === "/my" && isLogin === false) {
alert("请登录")
next(false) // 阻止路由跳转
} else {
next() // 正常放行
}
})

总结:next()放行,next(false)留在原地不跳转路由,next(path路径)强制换成对应path路径跳转。

vue-vant组件库

组件库:由很多组件组成的库

vant组件库 —— 轻量、可靠的移动端Vue组件库、开箱即用

vant组件库使用文档

特点:

  • 提供 60 多个高质量组件,覆盖移动端各类场景
  • 性能极佳,组件平均体积不到 1kb
  • 完善的中英文文档和示例
  • 支持 Vue 2 & Vue 3
  • 支持按需引入和主题定制

vue基础面试题

1. Vue的最大优势是什么?

​ 简单易学, 轻量级整个源码js文件不大, 双向数据绑定, 数据驱动视图, 组件化, 数据和视图分离,

​ vue负责关联视图和数据, 作者中国人(尤雨溪), 文档都是中文的, 入门教程非常多, 上手简单.

​ 相比传统网页, vue是单页面可以只刷新某一部分

2. Vue和jQuery区别是什么?

​ jQuery应该算是一个插件, 里面封装了各种易用的方法, 方便你使用更少的代码来操作dom标签

​ Vue是一套框架, 有自己的规则和体系与语法, 特别是设计思想MVVM, 让数据和视频关联绑定, 省略了很多DOM操作. 然后指令还给标签注入了更多的功能

3. mvvm和mvc区别是什么?

​ MVC: 也是一种设计模式, 组织代码的结构, 是model数据模型, view视图, Controller控制器, 在控制器这层里编写js代码, 来控制数据和视图关联

​ MVVM: 即Model-View-ViewModel的简写。即模型-视图-视图模型, VM是这个设计模式的核心, 连接v和m的桥梁, 内部会监听DOM事件, 监听数据对象变化来影响对方. 我们称之为数据绑定

4. Vue常用修饰符有哪些?

​ .prevent: 提交事件不再重载页面;

​ .stop: 阻止单击事件冒泡;

​ .once: 只执行一次这个事件

5. Vue2.x兼容IE哪个版本以上

​ 不支持ie8及以下,部分兼容ie9 ,完全兼容10以上, 因为vue的响应式原理是基于es5的Object.defineProperty(),而这个方法不支持ie8及以下。

6. 对Vue渐进式的理解

​ 渐进式代表的含义是:主张最少, 自底向上, 增量开发, 组件集合, 便于复用

7. v-show和v-if的区别

​ v-show和v-if的区别? 分别说明其使用场景?

​ v-show 和v-if都是true的时候显示,false的时候隐藏

​ 但是:false的情况下,

​ v-show是采用的display:none

​ v-if采用惰性加载

​ 如果需要频繁切换显示隐藏需要使用v-show

8. 说出至少4个Vue指令及作用

​ v-for 根据数组的个数, 循环数组元素的同时还生成所在的标签

​ v-show 显示内容

​ v-if 显示与隐藏

​ v-else 必须和v-if连用 不能单独使用 否则报错

​ v-bind 动态绑定 作用: 及时对页面的数据进行更改, 可以简写成:分号

​ v-on 给标签绑定函数,可以缩写为@,例如绑定一个点击函数 函数必须写在methods里面

​ v-text 解析文本

​ v-html 解析html标签

9. 为什么避免v-for和v-if在一起使用

​ Vue 处理指令时,v-for 比 v-if 具有更高的优先级, 虽然用起来也没报错好使, 但是性能不高, 如果你有5个元素被v-for循环, v-if也会分别执行5次.

评论