第一章 对vue的大概认识
1.vue的特点
- 采用组件化模式—————提高代码的复用率、让代码更好的维护
- 声明式编码————————编码人员无需直接操作DOM,提高开发效率。
- 使用虚拟DOM+优秀的Diff算法————尽量复用DOM节点。
2.MVVM
- view视图层:负责展示model中的数据;
- model模型层:负责数据的存储和业务逻辑;
- viewmodel视图模型层:负责连接model和view,具有双向绑定能够自动更新视图。
优点:
- 分离view和model,降低代码耦合,提高视图或逻辑的重用性;
- 自动更新视图。
缺点:
- Bug很难被调试
MVVM的原理:
- Vue基类
3.SPA(single-page application)单页面应用
仅在页面初始化时加载相应的HTML、JavaScript和CSS,一旦页面加载完成,SPA不会因为用户的操作而进行页面的重新加载或跳转,而是利用路由机制实现HTML内容的变换,避免页面的重新加载。
1.优点
- 用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;服务器压力小;
- 前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理。
2.缺点 - 初次加载耗时长;
- SEO(搜索引擎优化)难度高;
- 页面复杂都提高,复杂逻辑程度成倍。
4.MPA(MultiPage Application)多页面应用
每个页面必须重复加载js、css等相关资源。多页应用跳转,需要整页资源刷新。
5.Vue的生命周期
所谓的vue生命周期指的是vue实例从创建到销毁的过程。
在vue的生命周期过程中,某些函数在特定的时候会自动被调用,即生命周期函数。
- 前四个函数在整个生命周期中只执行一次,为创建阶段的生命周期函数
- 一共三个阶段:创建(4)————运行(2)————销毁(2)
- 如果要处理与数据相关的逻辑,最早在created函数中进行处理。
- 在实例创建完成后created被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
1.beforeCreate(创建前) :
数据代理,$data存在
2.created(创建后) :①(可)数据初始化,ajax请求数据可以放在这里
配置了el选项或者手动调用vm.$mount(el)进入mount流程————都没有,不会进入mount流程
模板的编译,ast=>优化=>生成render函数字符串,render函数执行,渲染为内存中的DOM,Vnode
3.beforeMount(挂载前) :
挂载到页面,el 被新创建的 vm.$el 替换(create vm.$el and replace "el" with it)
4.mounted(挂载后) :
一旦数据发生改变:
5.beforeUpdate(更新前) :
6.updated(更新后) :
关闭网站、网页
7.beforeDestroy(销毁前) :
8.destroyed(销毁后) :
vue/src/core/instance/index.js
——————vue的构造函数,new Vue(options)调用的就是该函数。
function Vue (options) {
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options)
}
——————initMixin(Vue)在Vue的原型上挂载了init方法
Vue.prototype._init = function (options?: Object) {
....
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)//...包括initData() data = vm._data = typeof data === 'function'? getData(data, vm): data || {}
//proxy(vm, `_data`, key)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
}
——————lifecycleMixin(Vue)
6.Vue的模板编译
- parse 函数解析 template,把字符串类型的 template 转化成了树状结构的 AST(Abstract Syntax Tree)。
- optimize 函数会对 parse 生成的 AST优化静态内容,静态内容指的是和数据没有关系,不需要每次都刷新的内容。, 之后diff 算法会直接跳过静态节点。
- generate 函数生成 render function code
接下来 Vue 做的事情就是 new watcher,这个时候会对绑定的数据执行监听,render 函数就是数据监听的回调所调用的,其结果便是重新生成 vnode。
(当这个 render 函数字符串在第一次 mount、或者绑定的数据更新的时候,都会被调用,生成 Vnode。)
如果是数据的更新,那么 Vnode 会与数据改变之前的 Vnode 做 diff,对内容做改动之后,就会更新到真正的 DOM 上。
以上是在
<tempalte>模板标签中的内容,当不是用的.vue文件,而是采用script标签引入的vue.js,同时也没有用template模板属性时: vue会把由el指定的dom中的内容作为模板,编译模板再挂载回dom元素上。
vue/src/compiler/index.js
export const createCompiler = createCompilerCreator(function baseCompile (
template: string,
options: CompilerOptions
): CompiledResult {
const ast = parse(template.trim(), options)
if (options.optimize !== false) {
optimize(ast, options)
}
const code = generate(ast, options)
return {
ast,
render: code.render,
staticRenderFns: code.staticRenderFns
}
})
第二章 API(难点)
1.Vue.extend
Vue.extend(options)返回的是一个新的VueComponent构造函数。(在模板中遇到该组件名称作为标签的自定义元素时,Vue解析时就会创建组件的实例对象,即Vue自己执行:new VueComponent(options))
组件实例均是VueComponent的实例对象,组件和Vue实例不能划等号。 区别:
- 组件实例不能用el
- 组件实例data必须写成函数
内置关系
VueComponent.prototype.__proto__===Vue.prototype
目的:让组件实例对象可以访问到Vue原型上的方法。
2.Vue.use
Vue.use(插件)用来加载插件。
插件上的原理:
对象中的特殊的install方法,会接受vm参数(Vue的构造函数),向Vue构造函数中添加Vm.prototype.$loading=loading
- 传入插件,检查插件是否被注册,若注册过则直接跳出。
- 在处理入参时,将第一个参数之后的参数归集,并在首部塞入this上下文。
- 执行注册,如果插件没有install方法并且插件为函数则直接执行插件本身,否则调用插件上定义好的install方法传入处理的参数。
第三章 插件
1.Vuex
组件调用store提供的api:Dispatch(动作类型,数据)————操作行为触发方法。这里可直接commit.
Vuex中有三个对象:(store来管理三个对象,store.dispatch(),store.commit())
- actions操作行为处理模块。api:commit(动作类型,数据)————状态改变提交操作方法。
const actions = { jia(context,value){ context.commit('JIA',value); } } - mutations状态改变操作方法。
const mutations = { JIA(state,value){ state.sum += value; } } - state页面状态管理容器对象。
const state = { sum:0, }
其他:
- getters const getters = { bigSum(state){return state.sum*10} }
2.VueRouter
Vue.use(VueRouter)后,组件上多了$router,路由实例
第四章 配置项
1.render
render:h=>h(app)
data(){
return{
people:['小孩','大人']
}
},
render(createElement){
return createElement(this.tag,{},this.people.map(name=>createElement('li',{//第一个参数可以是组件
attrs:{class:'test'},
on:{click:()=>{console.log('li')}}
},name)))
}
第五章 属性
1.ref
是document.getElementById()等原生获取dom的替代者,ref标识。
this.$refs.值
值得注意的是:
对于组件标签,id拿到的是dom结构,而ref却能拿到组件实例对象。
2.v-on
绑定自定义事件:v-on:demo="getStudentName"
this.$refs.student.$on('demo',this.getStudentName)触发自定义事件:this.$emit("demo",this.name)