Vue
刀刀
3/20/2025
0 字
0 分钟
Vue
的基本概念
什么是 vue
Vue
是一个 渐进式 的 javascript
框架,拥有一套属于自己规则的语法。
官网地址:vue官网 。
补充知识点:
什么是渐进式
渐进式:逐步进步,想用什么就用什么,不必全部使用。
什么是库和框架
- 库:封装的属性或方法 (例jquery.js)
- 框架:拥有自己的规则和元素, 比库强大的多 (例vue.js)拥有自己的规则和元素, 比库强大的多 (例vue.js)
开发方式
- 传统开发方式:基于
html
/css
/js
文件开发vue
- 工程化开发方式:在
webpack
环境中开发vue
(推荐这种方式)
脚手架 @vue/cli
脚手架介绍
自己配置 webpack
的环境十分麻烦, Vue
官方提供了一个全局模块包,这个包用于创建脚手架项目。
脚手架的好处是无需我们配置 webpack
环境,下载即可使用,支持 css
、 less
、 babel
、开发服务器等。
脚手架安装
需要把脚手架
@vue-cli
模块包安装到全局,让电脑拥有vue
命令,才能创建脚手架工程。
全局安装命令
sqlyarn global add @vue/cli # or npm i -g @vue/cli 复制代码
注意:
如果下载失败查看一下
npm
的镜像源,命令nrm ls
。 切换成淘宝镜像源可减少连接超时的错误。查看版本
vue -V 复制代码
创建项目启动服务
通过
vue
命令创建一个脚手架的项目。注意:项目名不能带大写字母、中文和特殊符号。
创建项目
luavue create 文件夹名称 复制代码
选择模板
可以选择默认模板,也可选择自己手动配置一个新的模板。
开启成功后会出现两条代码指示,第一条让我们进入目标文件内,第二条是开启命令。
进入文件内并成功开启命令后就有相关路径。
目录和代码分析
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 # 项目包版本锁定和缓存地址
复制代码
主要文件及含义
node_modules下都是下载的第三方包
public/index.html – 浏览器运行的网页
src/main.js – webpack打包的入口文件
src/App.vue – vue项目入口页面,根主键
package.json – 依赖包列表文件
复制代码
项目架构了解
首先去 main.js
入口文件,去到 App.vue
根组件模块,获取到样式、标签、逻辑,返回 main.js
文件。 new
实例化一个 Vue
对象,把属性插入到 index.html
页面中。
自定义配置
在
webpack
中我们通过webpack.config.js
文件进行自定义配置,如端口号、出入口文件等,vue
中则是vue.config.js
文件进行自定义配置。
在 src
文件夹的同级目录下新建一个 vue.config.js
文件。自定义端口号命令和 webpack
的一样。
module.exports = {
devServer: {
port : 3000
}
}
修改完毕后重新启动即可。
eslint
的作用
eslint
是一个代码检查工具,检测代码的严谨程度
模拟情景:声明一个变量,但不使用,保存运行,结果报错。
解决方法:
手动解决掉错误, 以后会讲如何自动解决
暂时关闭
eslint
检查(因为现在主要精力在学习
Vue
语法上), 在
vue.config.js
中配置后重启服务。
jsmodule.exports = { // 暂时关闭eslint配置 lintOnSave: false } 复制代码
单文件 vue
讲解
单文件最大的好处,就是独立作用域,互不影响。
Vue
中更推荐采用.vue
组件来开发项目。
template里只能有一个根标签
html<template> <div id="app"> </div> <div id="box"></div> </template> 复制代码
结果会报错。
vue
文件-独立模块-作用域互不影响。style
配合scoped
属性, 保证样式只针对当前template
内标签生效。html<style scoped> </style> 复制代码
vue
文件配合webpack
, 把他们打包起来插入到index.html
。
Vue
指令
插值表达式
可以直接在
dom
元素中插入内容。
语法:
{{ 表达式 }}
在插值表达式中,可以添加文本内容,可以用三元表达式进行判断处理,可以进行简单的运算,还可以字符串内置api进行处理。但是不能写语句,如if判断和for循环。
<template>
<div>
<h1>{{ msg }}</h1>
<h2>{{ obj.name }}</h2>
<h3>{{ obj.age > 18 ? '成年' : '未成年' }}</h3>
</div>
</template>
<script>
export default {
data() { // 格式固定, 定义vue数据之处
return { // key相当于变量名
msg: "hello, vue",
obj: {
name: "小vue",
age: 5
}
}
}
}
</script>
总结:
dom
中插值表达式赋值,vue
的变量必须在data
里声明。
MVVM
设计模式
转变思维, 用数据驱动视图改变, 操作dom的事, vue源码内干了。
设计模式: 是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。
M
:model
数据模型 (data
里定义)V
:view
视图 (html
页面)VM
:ViewModel
视图模型 (vue.js
源码)- MVVM通过
数据双向绑定
让数据自动地双向同步 不再需要操作DOM- V(修改视图) -> M(数据自动同步)
- M(修改数据) -> V(视图自动同步)
指令 v-bind
作用:给标签属性设置
vue
变量的值。
前面的插值表达式只能用在元素内容上,不能用在元素属性上。如: src=""
、value=""
等。这个时候就用到了 v-bind
指令。
- 语法:
v-bind:属性名="vue变量"
- 简写:
:属性名="vue变量"
在使用 v-bind
属性绑定期间,如果绑定内容需要进行动态拼接,字符串的外面需要包裹一层单引号。如果不包裹单引号,则默认为是一个变量,会去 data
内寻找获取。
<a v-bind:href="url">百度</a>
<a :href="url">百度</a>
<script>
export default {
data() {
return {
url: "http://www.baidu.com",
};
},
};
</script>
总结:
vue指令, 实质上就是特殊的
html
标签属性, 特点: v- 开头。v-bind
把vue
变量的值, 赋予给dom
属性上, 影响标签显示效果。
指令 v-bind
动态参数
<!--
注意,参数表达式的写法存在一些约束,如之后的“对动态参数表达式的约束”章节所述。
-->
<a v-bind:[attributeName]="url"> ... </a>
这里的 attributeName
会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data
property attributeName
,其值为 "href"
,那么这个绑定将等价于 v-bind:href
。
对动态参数表达式的约束
动态参数表达式有一些语法约束,因为某些字符,如空格和引号,放在 HTML attribute
名里是无效的。例如:
<!-- 这会触发一个编译警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>
变通的办法是使用没有空格或引号的表达式,或用计算属性替代这种复杂表达式。
在 DOM
中使用模板时 (直接在一个 HTML
文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute
名全部强制转为小写:
<!--
在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
除非在实例中有一个名为“someattr”的 property,否则代码不会工作。
-->
<a v-bind:[someAttr]="value"> ... </a>
指令 v-on
作用:给标签绑定事件。
语法
v-on:事件名="要执行的少量代码"
html<template> <div id="app"> <h1>{{ count }}</h1> <button v-on:click="count = count + 1">增加1</button> </div> </template> <script> export default { data() { return { count: 1, }; }, }; </script> 复制代码
v-on:事件名="methods中的函数"
v-on
等号内是函数的名字,函数写在methods
对象内。事件函数想要用到
data
内的数据,就要通过this.
的形式获取。因为数据都是放在Vue
对象内,对象调用了这些方法,this
指向这个vue
实例对象。html<template> <div id="app"> <h1>{{ count }}</h1> <button @click="add">增加1</button> </div> </template> <script> export default { data() { return { count: 1, }; }, methods: { add() { this.count += 1; }, }, }; </script> 复制代码
v-on:事件名="methods中的函数(实参)"
这里加括号不是立即执行函数,而是为函数传递一个参数。必须要有括号才能传参!
html<template> <div id="app"> <h1>{{ count }}</h1> <button @click="addFn(5)">增加多个</button> </div> </template> <script> export default { data() { return { count: 1, }; }, methods: { addFn(num) { this.count += num; }, }, }; </script> 复制代码
指令 v-on
动态参数
使用动态参数为一个动态的事件名绑定处理函数:
<a v-on:[eventName]="doSomething"> ... </a>
在这个示例中,当 eventName
的值为 "focus"
时,v-on:[eventName]
将等价于 v-on:focus
。
对动态参数的值的约束
动态参数预期会求出一个字符串,异常情况下值为 null
。这个特殊的 null
值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。
指令 v-on
简写
普通简写
html<a @click="doSomething">...</a>
动态简写
html<a @[event]="doSomething"> ... </a>
指令 v-on
修饰符
作用:在事件后面加上
.修饰符名
给事件带来更大的功能。
@事件名.修饰符="methods里函数"
.stop
- 阻止事件冒泡.prevent
- 阻止默认行为.once
- 程序运行期间, 只触发一次事件处理函数
<template>
<div id="app" @click="father">
<button @click.stop="son">阻止冒泡</button>
<a :href="url" @click.prevent>阻止默认行为</a>
<button @click.once="one">只出发一次</button>
</div>
</template>
<script>
export default {
data() {
return {
url: "http://www.baidu.com",
};
},
methods: {
father() {
console.log("父元素触发了");
},
son() {
console.log("我不冒泡!");
},
one() {
console.log("我只出发一次!");
},
},
};
</script>
<style scoped>
</style>
指令 v-on
按键修饰符
作用:给键盘事件, 添加修饰符, 增强能力。
- 语法:
@keyup.enter
- 监测回车按键@keyup.esc
- 监测返回按键
<template>
<div>
<input type="text" @keydown.enter="enterFn">
<hr>
<input type="text" @keydown.esc="escFn">
</div>
</template>
<script>
export default {
methods: {
enterFn(){
console.log("enter回车按键了");
},
escFn(){
console.log("esc按键了");
}
}
}
</script>
指令 v-model
作用:把
value
属性和vue
数据变量, 双向绑定到一起。 双向数据绑定的含义:
- 数据变化 -> 视图自动同步
- 视图变化 -> 数据自动同步
语法: v-model="vue数据变量"
指令 v-model
不能用于 div
这个无法获取内容的标签,一般用于 input
、select
、textarea
等。
select
: 下拉菜单的v-model
指令写在第一行的select
中,获取到的是每条option
的value
值。checkbox
: 复选框表单中的Vue
变量是一个字符串时,关联的是checked
属性;是一个数组时,关联的是value
的值。即绑定单个复选框,获取到的是该复选框的选中状态(
true
或false
);绑定多个复选框,获取到的是一个数组,包含所有已选中的值radio
:获取到的是被选中的单选框的值
<template>
<div>
<!--
v-model:是实现vuejs变量和表单标签value属性, 双向绑定的指令
-->
<div>
<span>用户名:</span>
<input type="text" v-model="username" />
</div>
<div>
<span>密码:</span>
<input type="password" v-model="pass" />
</div>
<div>
<span>来自于: </span>
<!-- 下拉菜单要绑定在select上 -->
<select v-model="from">
<option value="北京市">北京</option>
<option value="南京市">南京</option>
<option value="天津市">天津</option>
</select>
</div>
<div>
<!-- (重要)
遇到复选框, v-model的变量值
非数组 - 关联的是复选框的checked属性
数组 - 关联的是复选框的value属性
-->
<span>爱好: </span>
<input type="checkbox" v-model="hobby" value="抽烟">抽烟
<input type="checkbox" v-model="hobby" value="喝酒">喝酒
<input type="checkbox" v-model="hobby" value="写代码">写代码
</div>
<div>
<span>性别: </span>
<input type="radio" value="男" name="sex" v-model="gender">男
<input type="radio" value="女" name="sex" v-model="gender">女
</div>
<div>
<span>自我介绍</span>
<textarea v-model="intro"></textarea>
</div>
</div>
</template>
<script>
export default {
data() {
return {
username: "",
pass: "",
from: "",
hobby: [],
sex: "",
intro: "",
};
// 总结:
// 特别注意: v-model, 在input[checkbox]的多选框状态
// 变量为非数组, 则绑定的是checked的属性(true/false) - 常用于: 单个绑定使用
// 变量为数组, 则绑定的是他们的value属性里的值 - 常用于: 收集勾选了哪些值
}
};
</script>
指令 v-model
修饰符
作用:让
v-model
拥有更强大的功能。
语法:
v-model.修饰符="vue数据变量"
.number
以parseFloat
转成数字类型。.trim
去除首尾空白字符。.lazy
在change
时触发而非inupt
时,有利于减少请求优化性能。
<template>
<div>
<div>
<span>年龄:</span>
<input type="text" v-model.number="age">
</div>
<div>
<span>人生格言:</span>
<input type="text" v-model.trim="motto">
</div>
<div>
<span>自我介绍:</span>
<textarea v-model.lazy="intro"></textarea>
</div>
</div>
</template>
<script>
export default {
data() {
return {
age: "",
motto: "",
intro: ""
}
}
}
</script>
指令 v-text
和 v-html
作用:更新
DOM
对象的innerText
/innerHTML
。
- 语法:
v-text="vue数据变量"
v-html="vue数据变量"
- 注意: 会覆盖插值表达式
<template>
<div>
<p v-text="str"></p>
<p v-html="str"></p>
</div>
</template>
<script>
export default {
data() {
return {
str: "<span>我是一个span标签</span>"
}
}
}
</script>
v-model
也可以为子组件绑定,只要子组件遵循以下规则:
- 子组件只有一个
input
标签且该标签为根标签 - 子组件的
value
值动态绑定prop
变量value
- 其
input
事件触发后$emit
抛出新值
父组件:
<custom-input v-model="searchText"></custom-input>
子组件:
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
指令 v-show
和 v-if
作用:控制标签的隐藏或出现
语法:
v-show="vue变量"
v-if="vue变量"
原理
v-show
动态为元素添加或移除display:none
样式 (频繁切换使用v-show
性能更好)。v-if
动态从DOM
树上创建或移除元素(对于刚初始化就不需要被展示的时候使用v-if
性能更好,不需要额外创建这个元素)。
html<template> <div id="app"> <div v-show="isok">我是v-show</div> <div v-if="isok">我是v-if</div> <button @click="change">点我改变</button> </div> </template> <script> export default { data() { return { isok: false, }; }, }; </script> 复制代码
高级
v-else
使用,需要结合v-if
才能生效。xml<script> export default { data() { return { age: 1, able: false, }; }, methods: { change() { this.isok = !this.isok; // this.age = 20; this.able = true; }, }, }; </script>
补充拓展:
在
html
页面中,代码是从上往下执行的,因此会出现先创建v-for
控制的元素节点,再判断是否删除。但是在
.vue
组件中,会把整体当作js
代码编译,因此会去判断是否要加载再去加载。
指令 v-for
作用:列表渲染, 所在标签结构, 按照数据数量, 循环生成。
遍历数组
语法
v-for="值 in 目标数组"
v-for="(值, 索引) in 目标数组"
索引必须要写在第二位上,可以自己命名,不一定是要
index
。
遍历对象
语法
v-for="值 of 目标对象"
v-for="(值, 键) of 目标对象"
v-for="(值, 键, 索引) of 目标对象"
注意:
v-for
的临时变量名不能用到v-for
范围外
指令 v-for
的更新监测
作用:当
v-for
遍历的目标结构改变,Vue
触发v-for
的更新。
情景一:数组翻转 数组翻转用到了数组的内置
API
方法:reserve()
。这个方法会修改原数组。html<template> <div> <ul> <li v-for="(val, index) in arr" :key="index"> {{ val }} </li> </ul> <button @click="revBtn">数组翻转</button> </div> </template> <script> export default { data(){ return { arr: [5, 3, 9, 2, 1] } }, methods: { revBtn(){ // 1. 数组翻转可以让v-for更新 this.arr.reverse() }, } } </script> 复制代码
情景二:数组截取 数组截取用到了数组内置方法
slice
,需要传递两个参数,第一个参数为起始值(从哪里开始),第二个参数为终止值(在哪里结束)。但是这个方法不会改变原数组,会产生返回值给新的数组接收,如下图所示。
所以我们要用原数组来接收这个返回值。
html<template> <div> <ul> <li v-for="(val, index) in arr" :key="index"> {{ val }} </li> </ul> <button @click="sliceBtn">截取前3个</button> </div> </template> <script> export default { data(){ return { arr: [5, 3, 9, 2, 1] } }, methods: { sliceBtn(){ // 2. 数组slice方法不会造成v-for更新 // slice不会改变原始数组 // this.arr.slice(0, 3) // 解决v-for更新 - 覆盖原始数组 this.arr = this.arr.slice(0, 3) }, } } </script> 复制代码
情景三:更新值 更新值可以用到
vue
的内置属性方法:$set()
,需要传递三个参数:- 第一个参数:需要被更新值的数组或对象
- 第二个参数:更新的位置(必须是字符串的形式)
- 第三个参数:更新后的值
html<template> <div> <ul> <li v-for="(val, index) in arr" :key="index"> {{ val }} </li> </ul> <button @click="updateBtn">更新第一个元素值</button> </div> </template> <script> export default { data(){ return { arr: [5, 3, 9, 2, 1] } }, methods: { updateBtn(){ // 3. 更新某个值的时候, v-for是监测不到的 // this.arr[0] = 1000; // 解决-this.$set() // 参数1: 更新目标结构 // 参数2: 更新位置 // 参数3: 更新值 this.$set(this.arr, 0, 1000) } } } </script> 复制代码
这些方法会触发数组改变, v-for会监测到并更新页面
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
这些方法不会触发v-for更新
slice()
filter()
concat()
注意:
vue
不能监测到数组里赋值的动作而更新, 如果需要请使用Vue.set()
或者this.$set()
, 或者覆盖整个数组。即直接采用数组[索引]的方式修改值是不会被v-for
监测到的。关于这点下图为vue
创始人和发现这个问题并在issue
上提问的程序员的对话截图。知道即可。
指令 v-for
的就地更新与虚拟 dom
.vue文件中的template里写的标签, 都是模板, 都要被vue处理成虚拟DOM对象, 才会渲染显示到真实DOM页面上
内存中生成一样的虚拟DOM结构(本质是个JS对象)
因为真实的DOM属性好几百个, 没办法快速的知道哪个属性改变了,如下图所示,真实
dom
的属性。比如template里标签结构
xml<template> <div id="box"> <p class="my_p">123</p> </div> </template> 复制代码
对应的虚拟DOM结构
cssconst dom = { type: 'div', attributes: [{id: 'box'}], children: { type: 'p', attributes: [{class: 'my_p'}], text: '123' } } 复制代码
以后vue数据更新
- 生成新的虚拟DOM结构
- 和旧的虚拟DOM结构对比
- 找不不同, 只更新变化的部分(重绘/回流)到页面 - 也叫打补丁
好处1: 提高了更新DOM的性能(不用把页面全删除重新渲染)
好处2: 虚拟DOM只包含必要的属性(没有真实DOM上百个属性)
在内存中比较差异, 然后给真实DOM打补丁更新上,v-for
的默认行为会尝试原地修改元素而不是移动它们。
总结: 虚拟DOM保存在内存中, 只记录dom关键信息, 提高DOM更新的性能
指令 v-for
的 key
的作用
官方建议:只要使用到了 v-for
,那么一定要绑定一个 :key
属性,而且,尽量把 id
具有唯一性的数值作为 key
的值。
而且,官方对 key
的值类型是有要求的,只能是字符串或者数值。
key
的值不允许重复,否则终端会报错。
无key - 就地更新
v-for
不会移动 DOM
, 而是尝试复用, 就地更新,如果需要 v-for
移动 DOM
, 你需要用特殊 attribute key
来提供一个排序提示。
<ul id="myUL">
<li v-for="str in arr">
{{ str }}
<input type="text">
</li>
</ul>
<button @click="addFn">下标为1的位置新增一个</button>
export default {
data(){
return {
arr: ["老大", "新来的", "老二", "老三"]
}
},
methods: {
addFn(){
this.arr.splice(1, 0, '新来的')
}
}
};
性能不高, 从第二个 li
往后都更新了,打开控制台,可以发现第二个 li
的文本和第三个 li
的文本被修改了;创建了新的第四个 li
。
有key - 值为索引
还是就地更新
因为新旧虚拟DOM对比, key存在就复用此标签更新内容, 如果不存在就直接建立一个新的
<ul id="myUL">
<li v-for="(str, index) in arr" :key="index">
{{ str }}
<input type="text">
</li>
</ul>
<button @click="addFn">下标为1的位置新增一个</button>
export default {
data(){
return {
arr: ["老大", "新来的", "老二", "老三"]
}
},
methods: {
addFn(){
this.arr.splice(1, 0, '新来的')
}
}
};
v-for
先循环产生新的DOM
结构,key
是连续的, 和数据对应- 然后比较新旧
DOM
结构, 找到区别, 打补丁到页面上
最后补一个 li
, 然后从第二个往后, 都要更新内容,效果实现和无 key
是一样的。
有key - 值为id
v-for
不会移动 DOM
, 而是尝试复用, 就地更新,如果需要 v-for
移动 DOM
, 你需要用特殊 attribute key
来提供一个排序提示
新DOM里数据的key存在, 去旧的虚拟DOM结构里找到key标记的标签, 复用标签。 新DOM里数据的key存在, 去旧的虚拟DOM结构里没有找到key标签的标签, 创建。
旧DOM结构的key, 在新的DOM结构里没有了, 则移除key所在的标签
<template>
<div>
<ul>
<li v-for="obj in arr" :key="obj.id">
{{ obj.name }}
<input type="text">
</li>
</ul>
<button @click="btn">下标1位置插入新来的</button>
</div>
</template>
<script>
export default {
data() {
return {
arr: [
{
name: '老大',
id: 50
},
{
name: '老二',
id: 31
},
{
name: '老三',
id: 10
}
],
};
},
methods: {
btn(){
this.arr.splice(1, 0, {
id: 19,
name: '新来的'
})
}
}
};
</script>
<style>
</style>
图解效果:
总结: 不用key也不影响功能(就地更新), 添加key可以提高更新的性能
总结
Vue
是什么是一个渐进式的
javascript
框架。Vue-cli
作用以及简单使用- 作用:无需我们配置自动帮我们搭建好
webpack
环境,开箱即用。 - 使用:
vue create 项目名
创建项目目录,进入目录后npm run serve
运行。
- 作用:无需我们配置自动帮我们搭建好
插值表达式 语法:
。vue变量在
script
标签内的data
函数内return
返回。MVVM
设计模式双向数据绑定与数据驱动视图。通过数据驱动视图,不要在想着怎么操作DOM,而是想着如何操作数据!!
v-bind
作用把
vue
变量的值, 赋予给dom
属性上, 影响标签显示效果v-on
作用和事件对象以及修饰符使用- 作用:给dom标签绑定事件, 等号右侧为事件处理函数,简写形式为
@
- 事件对象
- 无传参, 通过形参直接接收
- 传参, 通过$event指代事件对象传给事件处理函数
- 修饰符
.stop
- 阻止事件冒泡.prevent
- 阻止默认行为.once
- 程序运行期间, 只触发一次事件处理函数
- 作用:给dom标签绑定事件, 等号右侧为事件处理函数,简写形式为
v-model
的作用把
value
属性和vue
数据变量, 双向绑定到一起v-if
和v-show
的区别和本质v-if
:直接把节点从dom
树上删除v-show
:原理是通过样式display:none
隐藏节点。
v-for
的作用和使用- 作用:列表渲染, 所在标签结构, 按照数据数量, 循环生成
- 使用语法:
v-for="(值, 索引) in 目标结构"
v-for="值 in 目标结构"
vue
的特点- 渐进式
- 声明式渲染
- 数据驱动视图 (响应式)
- 极少的去写DOM操作相关代码
- 双向绑定
- 组件系统
- 不兼容IE8及以下浏览器
v-for
什么时候会更新页面呢?- 数组采用更新方法, 才导致
v-for
更新页面
- 数组采用更新方法, 才导致
vue
是如何提高更新性能的?- 采用虚拟
DOM+key
提高更新性能
- 采用虚拟
虚拟
DOM
是什么?- 本质是保存
dom
关键信息的JS对象
- 本质是保存
如何比较新旧虚拟
DOM
?- 根元素改变 – 删除当前DOM树重新建
- 根元素未变, 属性改变 – 更新属性
- 根元素未变, 子元素/内容改变
- 无key – 就地更新 / 有key – 按key比较
思维导图
拓展
为什么在 script
逻辑模块中, data
是函数返回的形式,而 methods
方法是对象的形式?
这就要从基本数据类型和复杂数据类型讲起。我们都知道,基本数据类型存储的是值,当赋值给一个新的变量时,内存会开辟一个新的空间存储值,彼此互不干扰,各自独立。
let a = 10
let b = a
b = 20
console.log(a ,b) // 10 20
复制代码
复杂数据类型存储的是地址,赋给新的变量时你修改我也会受到影响。
let obj = {s:2}
let obj1 = obj
obj1.s = 666
sonsole.log(obj) // {s:666}
返回 vue
,我们希望各个组件操作的值相互独立,互不干扰,因此如果使用对象的形式来存储,会造成修改前一个组件后一个组件的值也被改变。用函数返回的形式每个组件都有自己的返回值,互不干扰。
而函数我们希望能够复用,因此对象是最好的选择。