1)建立vue实例,初始化生命周期钩子函数
2)数据检测及方法和计算属性代理。在数据检测和初始化数据以前调用beforeCreated(),这时还获取不到props或者data中的数据;数据、属性、方法初始化以后,调用created(),能够访问以前访问不到的数据,可是组件尚未挂载,$el属性尚未显示,因此看不到组件。
3)判断是否有el属性,若是没有就判断是否调用了$mount方法,若是也没有则中止解析。若是调用了两者之一,就继续解析。
4)获取视图模板。判断是否有template属性,若是没有则将el的视图节点的outerhtml做为模板;若是有则将template视图做为模板。
5)编译模板。生成虚拟DOM,解析指令、组件。
6)将虚拟DOM挂载到真实DOM上。挂载前调用beforemount方法,挂在后调用mounted方法。
7)数据更新致使视图更新。更新前调用beforeUpdate,更新后调用updated。
8)销毁vue实例。销毁前调用beforedestroy,销毁后调用destroyed。javascript
若是你须要在组件切换的时候,保存一些组件的状态防止屡次渲染,就可使用 keep-alive 组件包裹须要保存的组件。html
对于 keep-alive 组件来讲,它拥有两个独有的生命周期钩子函数,分别为 activated 和 deactivated 。用 keep-alive 包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行 deactivated 钩子函数,命中缓存渲染后会执行 actived 钩子函数。vue
父组件经过props传递数据给子组件,子组件经过$emit发送事件传递数据给父组件,这两种方式是最经常使用的父子通讯实现方法。
父子通讯方式是单向数据流,父组件经过props传递数据,子组件不能直接修改props,而是必须经过发送事件的方式告知父组件修改数据。java
对于这种状况能够经过查找父组件中的子组件实现,也就是 this.$parent.$children,在 $children 中能够经过组件 name 查询到须要的组件实例,而后进行通讯。缓存
1)全局钩子函数:beforeEach、afterEach
router.beforeEach(to, from , next) 全局钩子函数,每次每个路由改变的时候都得执行一遍。
to:即将要进入的目标路由对象;form:当前导航正要离开的路由;next:Function
next( ):进行管道中的下一个钩子。若是所有钩子执行完了,则导航的状态就是confirmed。
next( false):中断当前的导航。
next( '/' ):跳转到一个不一样的地址。函数
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })
router.afterEach全局后置钩子,这些钩子不会接受 next 函数也不会改变导航自己:this
router.afterEach((to, from) => { // ... })
2)单个路由里面的钩子:beforeEnter、beforeLeave
你能够在路由配置上直接定义 beforeEnter 钩子函数,在进入对应路由时调用对应的beforeEnterurl
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
3)组件内的钩子函数:beforeRouteEnter 、beforeRouteUpdate 、beforeRouteLeave.net
const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用;不!能!获取组件实例 `this`; 由于当守卫执行前,组件实例还没被建立 }, beforeRouteUpdate (to, from, next) { // 在当前路由改变,可是该组件被复用时调用;举例来讲,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候;因为会渲染一样的 Foo 组件,所以组件实例会被复用。而这个钩子就会在这个状况下被调用。 能够访问组件实例 `this` }, beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由时调用; 能够访问组件实例 `this` } }
1)直接调用$router.push实现路由跳转:3d
this.$router.push({ path: `/login/${id}`, })
对应路由配置以下:
{ path: '/login/:id', name: 'Login', component: Login }
在子组件中获取参数值:
this.$route.params.id
2)经过路由属性中的name来肯定匹配的路由,经过params来传递参数。
this.$router.push({ name: 'Login', params: { id: id } })
对应路由配置以下:
{ path: '/login', name: 'Login', component: Login }
在子组件中获取参数值:
this.$route.params.id
3)使用path来匹配路由,而后经过query来传递参数。这种状况下 query传递的参数会显示在url后面?id=?
this.$router.push({ path: '/login', query: { id: id } })
对应路由配置以下:
{ path: '/login', name: 'Login', component: Login }
在子组件中获取参数值:
this.$route.params.id
一个组件的 data 选项必须是一个函数,所以每一个实例能够维护一份被返回对象的独立的拷贝:
data: function () { return { count: 0 } }
缘由:对象为引用类型,当重用组件时,因为数据对象都指向同一个data对象,当在一个组件中修改data时,其余重用的组件中的data会同时被修改;而使用返回对象的函数,因为每次返回的都是一个新对象(Object的实例),引用地址不一样,则不会出现这个问题
// 1.对象方式(全部重用的实例中的data均为同一个对象) var data = { x: 1 }; var vm1 = { data: data }; var vm2 = { data: data }; console.log(vm1.data === vm2.data);// true,指向同一个对象 // 2.函数方式(全部重用的实例中的data均为同一个函数) var func = function () { return { x: 1 } }; var vm3 = { data: func }; var vm4 = { data: func }; console.log(vm3.data() === vm4.data()); // false,指向不一样对象
参考博文:https://blog.csdn.net/qq_33576343/article/details/82793894
v-show只是在display:none和display:block之间切换。不管初始条件是什么都会被渲染出来,后面只需切换CSS,DOM仍是一直保留。
v-if 初始值为false时,组件不会被渲染,直到条件为true,而且切换条件时会触发销毁/挂载组件。
对比来讲,v-show在初始时有更高的开销,可是切换开销小,适于频繁切换的场景;v-if初始渲染开销小,切换时开销更高,不适合常常切换的场景。
一、全局注册指令
二、局部注册指令
使用:
三、自定义指令的钩子函数
bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数能够定义一个绑定时执行一次的初始化动做。
inserted:被绑定元素插入父节点时调用(父节点存在便可调用,没必要存在于document中)。
update:被绑定于元素所在的模板更新时调用,而不管绑定值是否变化。经过比较更新先后的绑定值,能够忽略没必要要的模板更新。
componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
unbind:只调用一次,指令与元素解绑时调用。
参考:https://juejin.im/book/5bdc715fe51d454e755f75ef/section/5c024ecbf265da616a476638