前言
文章只做知识点总结!
vue底层实现原理
vue是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter和getter,在数据变动时发布消息给订阅者,触发相应的监听回调
- observer(数据监听器):observer的核心是通过object.defineProperty()来监听数据的变动,内部定义setter和getter,当数据发生变化时,就会触发setter,去通知订阅者watcher
- watcher(订阅者):watcher订阅者作为observer和compile之间通信的桥梁,主要做的事情是: 在自身实例化时往属性订阅器dep里面添加自己 自身必须有一个update方法 属性变动时,调用自身的update方法,并触发compile中绑定的回调
- compile:主要是解析模板指令,将模板中变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加鉴定数据的订阅者,一旦数据有变动,收到通知,更新视图。
父子组件生命周期顺序
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
computed与watch区别
计算属性computed
- 支持缓存,只有依赖更新发生改变,才会重新计算,否则从缓存中读取数据返回。
- 函数必须用return返回
- 默认第一次加载时候就监听
- 一个属性受多个属性影响 侦听属性watch
- 不支持缓存,数据改变,直接触发相应的操作。
- watch不需要return返回
- 默认第一次加载不监听,需要的话可以添加immedidate属性为true
- 一条数据影响多条数据
vue常用指令
- v-text:用于更新标签包含的文本
- v-html:绑定html代码的数据在视图上
- v-show:显示/隐藏
- v-if:控制元素是否需要被渲染
- v-else
- v-for
- v-bind
- v-on
- v-model
- v-once:只渲染一次,后面元素中的数据再更新变化,都不会重新渲染
组件通信方式
- 父子组件通信props/$emit
父传子:利用属性绑定(v-bind:)传递,子组件使用props接收
子传父:利用事件绑定(v-on@)传递,子组件$emit触发
兄弟组件通信on
Event Bus实现跨组件通信
Vue.prototype.$bus = new Vue() // 自定义事件
跨级组件通信vuex vuex、listeners、provice/inject、children
vuex中mutation与action的区别
- mutation:必须是同步执行,专注于修改state。
- action:可以异步执行,不能直接操作state,专注于业务代码,异步请求。
描述一下vuex
- vuex主要应用于vue.js中管理数据状态的一个库。
- 优势在于可以全局共享数据,方便统一管理。
- 劣势在于页面刷新后state变量会还原清空
路由的两种模式
前端路由有两种模式:hash模式和history模式
- hash模式 hash模式是一种吧路由路径用#拼接在URL后面的模式。当#号后面路径发生变化时,浏览器并不会重新发起请求,而是会触发hashchange事件。 优点:浏览器兼容性较好,IE8也支持 缺点:路径在#号后不美观
- history模式 history是H5提供的新特性,允许开发者直接更改前端路由,即更新URL地址而不重新发起请求。
history.replaceState({}, null, '/b') // 替换路由
history.pushState({}, null, '/a') // 路由压栈
history.back() // 返回
history.forward() // 前进
history.go(-2) // 后退2次
优点:路径规范,没有#号 缺点:兼容性不如hash,且需要服务端支持,否则一刷新页面就404
devDependencies和dependencies区别
- devDependencies下的依赖包,只在本地或开发坏境下运行代码所依赖的(比如各种loader,babel全家桶及各种webpack的插件等)只用于开发环境,不用于生产环境,因此不需要打包。
- dependencies下的依赖包,是在线上(生产坏境)下所要依赖的包,比如vue,在线上时必须要使用的,dependencies依赖的包不仅开发环境能使用,生产环境也能使用。
css-loader和style-loader关系
vue生命周期理解
beforeCreate(创建前)
- 在实例初始化后,数据观测和事件配置前调用
- el及data未初始化,无法访问methods,data,computed等
- 使用场景:设置非响应式数据
created(创建后)
- 实例完成创建后,已完成数据观测,属性和方法的运算,watch/event事件回调,data数据初始化。
- el未初始化
- 使用场景:页面数据请求,初始化数据处理
beforeMount
- dom挂载前,完成编译模板,生成html
- dom未挂载到页面上
- 使用场景:初始化数据处理
mounted
- dom挂载完成,完成html渲染
- 使用场景:页面数据请求
beforeUpdated
- 数据更新前,虚拟dom重新渲染和打补丁前
- 使用场景:进一步更新状态
updated
- 数据更新且dom更新后
- 使用场景:dom更新依赖某个状态
beforeDestroy
- 实例销毁前调用
- 使用场景:清除定时器,清除监听dom事件
destroyed
- 实例销毁后调用,所有的子实例也会被销毁
插槽
具名插槽
base-layout组件
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
v-slot只能添加到template上
作用域插槽
概念:在父组件中使用子组件中的data数据
<div class="container">
<header>
<slot v-bind:userInfo="userInfos" name="headerName"></slot>
</header>
</div>
<base-layout v-slot:headerName="cHeaderNamer>
{{cHeaderNamer.userInfo}}
</base-layout>
keep-alive
概念:keep-alive是vue的内置组件,缓存不活动的动态组件实例。 作用:实现组件缓存,保持这些组件的状态,避免反复渲染导致性能问题。 应用场景:标签页使用v-if,但是使用keep-alive能缓存tab的操作状态
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
动态组件和异步组件
动态组件
<component v-bind:is="currentTabComponent">
异步组件
components: {
'my-component': () => import('./my-async-component')
}
为什么不建议v-for和v-if一起使用
- 当v-for和v-if在同一节点时,v-for的优先级较高,即v-if会重复运行在v-for循环中,造成性能浪费。
- 当存在v-for和v-if共存时,建议使用computed对数据进行过滤。
key的作用
key的作用是为了在diff算法执行时更快的找到对应节点,提高diff速度,更高效的更新虚拟dom。 为了在数据变化时强制更新组件,避免“就地复用”带来的副作用。
组件中data为什么是一个函数
组价被复用多次就会创建多个实例, 如果data是对象的话,对象属于引用类型会影响到所有实例,为保证组件不同实例间的data不冲突,data必须为一个函数。
vue文档的风格指南
代码命名规范
- JavaScript:使用camelCase(驼峰命名)
- Html:使用kebab-case(-划线命名)
文件命名规范
- 单文件组件
components/
|- MyComponent.vue
JavaScript顺序
- name
- components
- mixins
- props
- data
- computed
- watch
- 生命周期(breforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed)
- methods
## 元素attribute顺序
- v-for
- v-if(v-else-if、v-else,v-show)
- id
- ref
- key
- v-model
- 其他attribute
- v-on
props规范
props定义应该尽量详细,至少需要指定其类型
props: {
status: {
type: String,
required: true,
validator: function (value) {}
}
}
vue服务端渲染(SSR)
- 只执行created钩子函数
- try...catch会造成数据延迟
- 没有window对象
- 没有状态管理(入口设置)
window.__SSR_STORE__ = store