-
JavaScript 表达式(Expression):
- 表达式是可以计算并返回一个值的任何合法的 JavaScript 结构。
- 它们可以是一个简单的字面量(例如数字、字符串或布尔值),也可以是复杂的组合,包括算术运算符连接的操作数、函数调用、属性访问、对象和数组字面量等。
- 表达式总是会生成一个值,这个值可以被赋给变量、作为参数传递给函数,或者直接参与进一步的计算。
-
JavaScript 代码(Code):
- JavaScript 代码通常指的是一个或多个 JavaScript 语句的集合,它们共同构成了一段可执行逻辑的单元。
- 语句不一定要返回值,而是用来描述一系列操作,这些操作可以改变程序的状态,控制流程(如条件语句、循环语句等)。
简单来说,一个表达式会产生一个值,而一个代码块则会执行一系列操作。
MVVM
- M: 模型(Model) : 对应 data 中的数据
- V: 视图(View) : 模板
- VM: 视图模型(ViewModel) : Vue 实例对象
Object.defineProperty()
- 数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
- 数据代理的好处:更加方便的操作数据
let per = {
name: "张三",
sex: "男",
};
Object.defineProperty(per, "age", {
value: 500,
enumerable: true, // 控制属性是否可以枚举,默认值是 false
writable: true, // 控制属性是否可以被修改,默认值是 false,
configurable: true, // 控制属性是否可以被删除,默认值是 false
get() {
}, // 用来获取属性值的函数(当有人读取属性时,get 函数(getter)就会被调用,且返回值
set() {
}, // 用来设置属性值的函数(当有人修改属性时,set 函数(setter)就会被调用,
});
Vue 中的数据代理
-
基本原理:通过 Object.defineProperty()把 data 对象中的所有属性添加到 vm 上
-
为每一个添加到 vm 上的属性,都指定一个 getter/setter
-
在 getter/setter 中去操作(读/写) data 中对应的属性
-
Vue 中的事件处理
-
@click="show" === v-on:click="show($event)"
-
事件修饰符:
- .stop:阻止事件冒泡
- .prevent:阻止默认事件
- .once:事件只触发一次
- .capture:使用事件捕获模式
- .self:只有 event.target 是当前操作的元素时才触发事件
- .passive:事件的默认行为立即执行,无需等待事件回调执行完毕
-
按键别名:(@keyup.XXX)
- 回车 enter
- 删除 delete(捕获“删除”和“退格”键)
- 退出 esc
- 空格 space
- 换行 tab(需配合@keydown 使用)
- 上 up
- 下 down
- 左 left
- 右 right
计算属性 computed
- 定义:通过已有的属性进行计算得到的新的属性
- 优势:与 methods 实现相比,内部有缓存机制(复用),效率更高,调试方便
- data 里面放的是属性
- computed 里面放的是计算属性
computed: {
fullName {
// 当fullName属性被读取时,get() 方法会被调用,且返回值就作为 fullName 的值
// 初次获取fullName和所依赖项发生变化时,都会调用get(依赖项指的是计算属性中所有用到的属性)
get(){
return this.firstName + this.lastName;
},
// 当fullName被修改时调用
set(value) {
const arr = value.split(' ')
this.firstName = arr[0]
this.lastName = arr[1]
}
},
// 大多数情况下计算属性是不需要修改的,可以简写为
fullName() {
return this.firstName + this.lastName;
}
}
监视属性 watch
-
当被监视的属性变化时,回调函数自动调用,进行相关操作
- 注意
- 监视的属性必须存在(必须在 data 里存在),才能进行监视
- 注意
-
深度监视
watch: {
isHot: {
deep: true, // 配置deep: true可以检测对象内部值的改变
immediate: true, // 初始化时让handler调用一下
handler(newValue, oldValue) {
onsole.log('isHot被修改了', newValue, oldValue)
}
},
// 如果不需要其他配置项的,可以简写成
isHot(newValue, oldValue) {
console.log('isHot被修改了', newValue, oldValue)
}
}
watch 和 computed 的区别
- computed 存在缓存机制,当他依赖项没有变化时,不会重新执行。而 watch 每次都会执行。
- computed 只能是执行同步代码。而 watch 支持异步(也就是可以用 setTimeout)。
- computed 有返回值。而 watch 没有返回值,需要手动处理数据。
key 的作用
- key 是给每一个虚拟 DOM 增加的唯一标识,可以根据 key 更准确、更快的找到对应的节点
VUE 检测数据变化的原理
-
VUE 是如何监测对象里面数据改变的?
- 遍历对象的属性
- 给属性添加 getter 和 setter
- 遇到对象嵌套问题,进行递归
-
Vue.set & this.$set
- 用于为对象添加响应式属性
- 语法:Vue.set( target, propertyName/index, value )
- target:要更改的数据源(可以是对象或者数组)
- propertyName/index:要更改的具体数据
- value:重新赋的值
- 注意:Vue.set 只能给 data 里的对象追加属性而不能给 data 追加
-
VUE 是如何监测数组里面数据改变的?
- 通过调用数组的一些方法(push, pop, shift, unshift, splice, sort, reverse)来监听数组变化,VUE 将这些方法进行了包裹
注意:不能使用数组索引直接修改
- 通过调用数组的一些方法(push, pop, shift, unshift, splice, sort, reverse)来监听数组变化,VUE 将这些方法进行了包裹
v-cloak
- 用于解决网速慢时 vue.js 未能加载出来,页面出现{ {xxx}}的问题,配合 css 来提升用户体验
[v-cloak]{
display: none;
}
<div v-cloak>{
{
name}}</div>
VUE 自定义指令
- 需求:定义一个 v-big 指令,和 v-text 功能类似,但会把绑定的数值放大 10 倍
<span v-big="count"></span>
data: {
count: 1
}
directives: {
// big函数会在一开始和所绑定的数据发生改变时调用
big(element, binding) {
element.innerText = binding.value * 10
}
}
生命周期
-
挂载流程
-
beforeCreate:无法拿到 data 中的数据和 methods 中的方法
-
created:可以拿到 data 中的数据和 methods 中的方法
这个时候 Vue 开始解析模版生成虚拟 DOM,但是页面还不能显示解析好的内容
-
beforeMount:页面呈现的是未经编译的 DOM,此时对 DOM 的操作
最终
不生效这个时候内存中的虚拟 DOM 会转为真实 DOM 插入页面,所以在 beforeMount 操作的 DOM 就不奏效了
-
mounted:页面呈现的是经过编译的 DOM,此时可以对 DOM 进行操作(一般在此时进行开启定时器、发送网络请求、订阅消息、绑定事件等操作)
-
-
更新流程
- beforeUpdate:操作事件改变数据后,数据已更新但页面尚未与数据同步
- updated:页面和数据同步,保持最新
-
销毁流程
-
beforeDestroy:此时可以拿到 data 中的数据和 methods 中的方法,但是对数据的修改不再触发更新(一般在此时解绑事件监听器,清理定时器等)
注意:销毁后自定义事件会失效,但是原生 DOM 事件依然有效
-
destroyed:所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
-
VUE 组件命名规范
-
一个单词组成
- 首字母小写:header
- 首字母大写:Header
-
多个单词组成
- kebab-case 命名:goods-list
- CamelCase 命名:GoodsList
VueComponent
- 组件本质是一个名为 VueComponent 的构造函数,且不是程序员定义的,是 Vue.extend 生成的
- 当在代码中写入
<component-name/>
的时候,Vue 会创建 component-name 组件的实例对象,即执行 new VueComponent(options)
注意:每次使用 Vue.extend 返回的都是全新的 VueComponent - 组件配置中
this
指的是 VueComponent 实例对象,new Vue(options)中this
指的是 Vue 实例对象
脚手架
- 安装脚手架
npm install -g @vue/cli
- 创建项目
vue create my-project
- 项目目录
├── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── main.js: 入口文件
│ │── App.vue: 汇总所有组件
│ │── components: 存放组件
│ │ └── HelloWorld.vue
│ └── views: 存放页面
│ └── Home.vue
├── .gitignore: git 版本管制忽略的配置
├── babel.config.js: babel 的配置文件
├── package.json: 应用包配置文件
├── package-lock.json: 包版本控制文件
├── README.md: 应用描述文件
└── vue.config.js: vue 脚手架的配置文件
ref 属性
- 应用在 HTML 标签上获取的是真实 DOM 元素,应用在组件标签上是组件实例对象(vc VueComponent)
props
- 功能:让组件接收外部传过来的数据
export default {
name: "GoodsList",
data() {
return {
};
},
// 完整方式
props: {
name: {
type: String,
required: true,
},
price: {
type: Number,
default: 1000,
},
},
};
mixin
- 功能:可以把多个组件共用的配置提取成一个混入对象
// 定义
export const mixin = {
mounted() {
console.log("mixin 的 mounted 被调用了");
},
};
// 使用
import {
mixin } from "../mixin";
export default {
name: "GoodsList",
data() {
return {
};
},
mixins: [mixin],
};
插件
- 功能:用于增强 Vue
- 本质:包含 install 方法的一个对象,install 的第一个参数是 Vue,第二个以后的参数是插件使用者传递的数据
// 定义
export default {
install(Vue, options) {
// 1. 添加全局过滤器
Vue.filter(....)
// 2. 添加全局指令
Vue.directive(....)
// 3. 配置全局混入(合)
Vue.mixin(....)
// 4. 添加实例方法
Vue.prototype.$myMethod = function() {
...}
Vue.prototype.$myProperty = xxxx