vue基础
传统组件,只是静态渲染,更新还要依赖于操作dom
vue mvvm用数据驱动视图
view > dom
viewModel > vue(通过dom监听,指令等更新渲染)
Model> data
1.computed和watch
-
computed有缓存,data不变则不会重新计算
-
watch监听引用类型拿不到oldVal,如何进行深度监听
watch: {
handler(oldVal, val){
// 其中oldVal和val是同一个引用地址
},
deep:true
}
2.v-if和v-show的区别和使用场景
-
v-if是元素直接删除和生成(交互不频繁用)
-
v-show是元素显示和隐藏(经常交互使用)
3.列表循环
-
v-for和v-if不建议一起使用
-
key的重要性
key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
key值的作用是:
更精准–>在虚拟dom节点中赋予key值,会更加快速的拿到需要的目标节点,不会造成就地复用的情况,对于节点的把控更加精准。
1 .key的作用是用来对比组件自身新旧DOM进行更新的,跟踪节点身份(减少渲染次数)
2 .key的作用是辅助判断新旧vdom节点在逻辑上是不是同一对象(判断是不是同一节点)。
4.组件通讯方式props和$emit
props:父组件传值给子组件.
$emit:子组件通过触发事件去处理事情.
5.生命周期
挂载阶段
-
beforeCreated,vue实例还没初始化
-
created页面还没有开始渲染,但是vue实例已经初始化完毕
-
beforeMount虚拟dom替换真实dom前
-
mouted页面渲染完毕
父子组件中
- 父组件先created,再子组件
- 之后子组件先mouted页面,再父组件组件
更新阶段
- beforeUpdated虚拟dom替换真实dom前
- updated页面渲染完毕
父子组件中
- 父组件先beforeUpdated,再子组件beforeUpdated
- 之后子组件先updated,再父组件组件updated
销毁阶段
- beforeDestroy销毁前
- destroyed销毁完毕
高级特性
1. 自定义v-model
//子组件
<template>
<input type="text" :value="val" @input="$emit('change',$event.target.value)" />
</template>
<script>
export default {
model: {
prop: 'val',
event: 'change'
},
props: {
val: String,
default(){
return ''
}
}
}
</script>
//父组件
<Child v-model="name"></Child>
2.$nextTick
vue是异步渲染,data改变后,Dom不会立刻渲染,$nextTick会在dom渲染后触发,以获得最新Dom节点
eg: 比如给一个ul里新增li,push完成后,虽然页面也显示,但是直接取新增的li值是拿不到的.
//等dom全部渲染完再回调
this.$nextTick(()=>{
//操作dom
})
3.solt
2.6后用v-slot和vm.$slots获取插槽里面的值
//父页面
<todo-list>
<template v-slot:todo="slotProps" >
{{slotProps.user.firstName}}
</template>
</todo-list>
//slotProps 可以随意命名
//slotProps 接取的是子组件标签slot上属性数据的集合所有v-bind:user="user"
//子页面
<slot name="todo" :user="user" :test="test">
{{ user.lastName }}
</slot>
data() {
return {
user:{
lastName:"last",
firstName:"first"
},
test:[1,2,3,4]
}
},
//显示
// first
// {{ user.lastName }}是默认数据 v-slot:todo 当父页面没有(="slotProps")
// 时显示 last
4.动态组件
根据值动态选择渲染组件时候使用。
<component :is="currentView"></component>
5. 异步加载组件
使用的时候才会加载需要的组件,大型组件时候使用可以优化性能
<mycomponent v-if="isShow"></mycomponent>
components:{
mycomponent:()=>import('../mycomponent')
}
6. keep-alive
tap切换使用,单页面系统
原理: 缓存虚拟dom
作用:
- 缓存组件
- 平凡切换时候不会重复渲染
- 有两个单独的生命周期,activated 和 deactivated
7. mixin
即把一个公共的逻辑部分(data,methods,mounted等)与主页面进行混合
多个组件共同逻辑抽离。
使用
mixins:[myMinxin]
带来问题
- 数据来源不明
- 命名冲突
vue原理部分
1. vue响应式原理
核心: Object.defineProperty(2.0)
Proxy(3.0)
(对象)
通过observer定义响应式,里面通过defineReactive去重新定义属性进行属性监听,其中通过Object.defineProperty中set触发更新视图
(数组)
重新定义原型上的几个数组方法(push,pop,shift,splice…),调用这些方法则会触发视图更新
Object.defineProperty缺点
- 深度监听,需要递归到底,一次性计算量大
- 新增属性/删除属性监听不到(得用vue.set/vue.delete)
- 无法原生监听数组,需要单独处理
2.虚拟dom和diff算法
虚拟dom:
用js模拟dom结构,计算出最小变更,操作dom。
虚拟dom就是js对象,就是个轻量级的dom描述。因为一个dom包含231个属性,而很多属性并不用的上。
虚拟dom解决的问题
虚拟 DOM 和 Diff 算法的出现是为了解决由命令式编程转变为声明式编程、数据驱动后所带来的性能问题的。
换句话说,直接操作 DOM 的性能并不会低于虚拟 DOM 和 Diff 算法,甚至还会优于。
虚拟 DOM 的作用
- 在牺牲(牺牲很关键)部分性能的前提下,增加了可维护性。
- 实现了对 DOM 的集中化操作,在数据改变时先对虚拟 DOM 进行修改,再反映到真实的 DOM 中,用最小的代价来更新 DOM,提高效率
- 可以适配 DOM 以外的渲染目标(微信小程序等),实现了跨平台的能力
虚拟 DOM 的缺点
- 首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,会比 innerHTML 插入慢。
- 只是少次量操作虚拟dom的话,可能会速度不如直接操作dom
存在价值:
数据驱动视图,控制dom操作
vdom结构
<div class="header" id="div1">
<p>内容<p/>
</div>
(tag标签,props属性,children子元素)
{
tag:'div',
props:{
className:'header',
id:'div1'
},
children:[
{
tag:"p",
children:'内容'
}
]
}
原因:dom操作非常耗费性能,js计算则很快
diff算法:
- 只比较同一层级,不跨级比较
- tag不同则直接删除重建,不进行深度比较
- tag和key,两者都相同,则认为是相同节点,不再深度比较
3. 模板编译
- vue template complier将模板编译为render函数
- 执行render函数生成vnode
render函数
Vue.component('heading',{
render: function(createElement){
return createElement(
'div',
[createElement('a',{
attrs:{
name:'qw',
href:'www.baidu.com',
},'链接'
})]
)
}
})
4. vue组件渲染过程
初次渲染
- 解析模板为render函数(或在开发环境已完成,vue-loader)
- 触发响应式,监听data属性getter(模板用到了其中属性就会触发get)
- 执行render函数,生成vnode,patch(elem,vnode)
更新过程
- 修改data,触发setter(此前在getter中已经被监听)
- 重新执行render函数, 生成newVnode
- patch(vnode,newVnode)
异步渲染
- $nextTick
- 汇总data的修改,一次性更新
- 减少dom操作次数,提高性能
前端路由原理
http: 协议 protocol
hostname ip/域名 127.0.0.1
host 127.0.0.1:8881
port 8881
pathname /index.html
search ?a=1&b=2
hash 哈希 ‘#/aaa/bbb’
hash特点
-
hash变化会触发网页跳转,即浏览器前进或者后退
-
hash变化不会刷新页面,spa必须的特点
-
hash变化不会提交到server端
-
通过
window.onhashchange
监听
h5 history
需要后端配合,只返回index主页
-
用url规范的路由,但是跳转不刷新页面
-
history.pushState({name:'page1'},' ','page1')
-
window.onpopstate = (event)=> {console.log('onpopstate',event.state,location.pathname)}
选择哪种
-
toB系统,后台管理系统,推荐用hash,简单易用,对url规范不敏感
-
toC 的系统,可以考虑H5 history,但是需要服务器支持