MVVM & MVC
MVC
Model View Controller; 要理解MVVM,还是要先了解一下MVC,因为MVVM是在MVC的基础上演进而来,早期的JSP,PHP等前端只是负责其中的view,然后再交给后端去渲染成动态的网页。
MVVM
Model View ViewModel
- 数据绑定在ViewModel层,并自动将数据渲染到页面中
- 视图变化的时候,通知ViewModel层更新数据
区别
- MVC:更专注于元素本身
- MVVM:更专注于数据本身,数据驱动视图更新
数据响应式
- 其实是一种机制
- 给数据做了特殊定义(defineReactive), 数据访问或变化是可以侦测感知,针对变化做出响应
- vue中结合发布订阅,在render中订阅需要做更新的组件,在需要更新时通知这些组件
生命周期
- 概念:组件创建、更新、销毁的过程
- 用途:在合适的时候做合适的事
- 分类:
- 初始化阶段: beforeCreate、created、beforeMounted、mounted
- 更新阶段:beforeUpdate、updated
- 销毁阶段:beforeDestroy、destroyed
- 过程
- beforeCreate: new Vue(), 实例初始化挂载功能
- created:props、data、methods、computed、watch;数据已准备就绪,可以做赋值,拉取等数据操作
- beforeMounted:vDom已更新,还不能操作dom
- mounted:$el已生成,可以获取dom;子组件已挂载,可以访问
- beforeUpdate:vDom已更新,dom未更新
- updated:数值变化已作用于dom,可以获取dom最新状态;但要谨慎操作数据,造成死循环
- beforeDestroy:实例vm尚未被销毁,做一些清空,重置造作
- destroyed:实例vm已被销毁
computed & watch
相同点
- computed本质是一个具备缓存的watcher
- 都基于vue的依赖收集机制
- 被依赖的值发生变化,进而改变进行处理计算 不同点
- 入和出
- computed: 多对一,多个值的变化,组成一个最终变化产物
- watch:一对多,单个值的变化,影响一系列的状态变更
- 性能开销
- computed:自动diff依赖,依赖没有发生变化,会从缓存中读取当前的计算值
- watch:监听值变化与否,都会执行回调
- 写法
- computed:必须有return
- watch:数据变化出发回调
- 触发时机
- computed:进入即出发
- watch:不会立即出发;可以添加immediate: true
v-for & v-if 优先级
- vue2: v-for优先级大于v-if
- vue3: v-if优先级大于v-for
key的作用
key
的作用主要是为了更高效的更新虚拟DOM
,其原理是Vue在patch
过程中,通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作,提高性能- 不设置key可能在列表更新时,引发一些隐藏bug
- vue在使用相同标签名元素的过渡切换时,也会使用key,其目的也是为了让vue可以区分它们,否则vue只会替换内部属性而不会触发过渡效果
插槽(slot)
默认插槽
<!-- SlotTest.vue -->
<template>
<slot></slot>
</template>
<!-- index.vue -->
<slot-test>
this is default slots
</slot-test>
具名插槽
<!-- SlotTest.vue -->
<template>
<slot name="main"></slot>
</template>
<!-- index.vue -->
<slot-test v-slot:main>
this is main slots
</slot-test>
作用域插槽
<!-- SlotTest.vue -->
<template>
<slot name="scope" :slotData="obj"></slot>
</template>
<script setup>
const obj = {
name: "tianzhen",
};
</script>
<!-- index.vue -->
<slot-test v-slot:scope="test">
{{ test.slotData.name }}
</slot-test>
<!-- 解构 -->
<slot-test v-slot:scope="{ slotData }">
{{ slotData.name }}
</slot-test>
混入(mixin)
将组件中共同的逻辑抽离出来,减少冗余
局部使用
// 新建mixin.js
export const mixins = {
created() {
console.log("created is trigger on mixin");
},
data() {
return {
name: "wangwu",
};
},
methods: {
clickMe() {
console.log("click is trigger on mixin");
},
},
};
- mixin 是一个对象,与组件中的选项一致
<template>
<div>
<p>{{ name }}</p>
<button @click="clickMe">click me</button>
</div>
</template>
<script>
import { mixins } from "./mixins";
export default {
mixins: [mixins],
};
</script>
全局使用
// main.js
import { mixins } from "./mixins";
Vue.mixin(mixins);
选项合并
当mixin中的data,methods,生命周期等与组件出现重复时
- data会使用组件本身中的值
- methods会使用组件本身的方法
- 生命周期会优先执行mixin
new Vue都做了什么
- 执行_init
- 组件实例初始化属性,$root,$children…
- 处理自定义事件
- 处理插槽信息,$createElements
- 组件状态初始化,响应式等
- beforeCreate,created