vue小记

vue原理
如何追踪变化
模型层(model)只是普通 JavaScript 对象,修改它则更新视图(view)。
把一个普通 Javascript 对象传给 Vue 实例的 data 选项Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。通过它们(getter/setter)可以让 Vue 在访问属性时进行依赖追踪,以及修改属性时进行变更通知
每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。
变化检测问题
Vue 不允许在已经创建的实例上动态添加新的根级响应式属性。
添加到对象上的新属性不会触发更新。在这种情况下可以创建一个新的对象,让它包含原对象的属性和新的属性:
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
声明响应式属性
data 对象就像组件状态的概要,提前声明所有的响应式属性。
消除了在依赖项跟踪系统中的一类边界情况;Vue 实例在类型检查系统的帮助下运行的更高效;让组件代码在以后阅读时更易于被理解。
异步更新队列
Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会一次推入到队列中。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际(已去重的)工作。
Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。
为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在DOM 更新完成后就会调用。


每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等


beforeCreate:

在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

created:

在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始$el 属性目前不可见。

beforeMount:

在挂载开始之前被调用:相关的 render 函数首次被调用。

mounted:

扫描二维码关注公众号,回复: 158939 查看本文章

el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。

注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

该钩子在服务器端渲染期间不被调用。

beforeUpdate:

数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。

updated:

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。

注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated

updated: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been re-rendered
  })
}

该钩子在服务器端渲染期间不被调用

activated:

keep-alive 组件激活时调用。

该钩子在服务器端渲染期间不被调用。

deactivated:

keep-alive 组件停用时调用。

该钩子在服务器端渲染期间不被调用。

beforeDestroy:

实例销毁之前调用。在这一步,实例仍然完全可用。

该钩子在服务器端渲染期间不被调用。

destroyed:

Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

该钩子在服务器端渲染期间不被调用。

errorCaptured:

2.5.0+ 新增,当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。



#v-cloak

这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。简单的就是说防止页面刚载入时出现{{msg}}等信息。

#keep-alive

当引入keep-alive 的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。

#key

key 的特殊属性主要用在 Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素。

当你遇到如下场景时它可能会很有用:

  • 完整地触发组件的生命周期钩子
  • 触发过渡

#实现tab页面切换
1.子路由:利用router-link和router-view切换tab。
路由中写法,需要子路由形式,不然会跳转页面,不会在router-view中渲染页面。
{
        path: '/tabs/list',
        name: 'tabs_list',
        component: resolve => require.async('/static/tabs/list.vue', proxy(resolve)),
        children:[
            {
                path: '/tabs/first',
                name: 'tab_first',
                component: resolve => require.async('/static/tabs/first.vue', proxy(resolve))
            },
            {
                path: '/tabs/second',
                name: 'tab_second',
                component: resolve => require.async('/static/tabs/second.vue', proxy(resolve))
            }
        ]
    },

<template>
<vm-page>
    <div id="account"> 
        <p class="tab"> 
            <!-- 使用 router-link 组件来导航. -->
            <!-- 通过传入 `to` 属性指定链接. -->
            <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
            <router-link to="/tuopan/first">选项一</router-link> 
            <!-- 注意这里的路径,first和second是tuopan的子路由 -->
            <router-link to="/tuopan/second">选项二</router-link> 
        </p> 
    <!-- 路由出口 -->
    <!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view> 
    </div> 
</vm-page>
</template>
2.动态组件:利用#is和#component切换页面,利用#keep-alive缓存,保留切换前的状态,避免重新渲染。
<template>
<vm-page>
    <vm-topbar slot="header">
        <div class="group">   
            <span v-for="(tab,index) in tabs" :class="{cur:iscur==index}" @click="onSwitch(index)">{{tab.name}}</span>  
        </div>
    </vm-topbar>
    <keep-alive>
        <component :is="currentView"></component>
    </keep-alive>
</vm-page>
</template>
<script>

import first from './first.vue';
import second from './second.vue';

export default {
    data() {
        return {
            iscur: 0,
            currentView: 'first',
            tabs: [{name: "选项一"}, {name: "选项二"} ]
        }
    },
    activated() {
    },
    components: { 
         first,
         second
    },
    methods: {
        onSwitch(index) {
            switch(index){
                case 1:
                this.iscur = 1;
                   this.currentView = 'second';
                   break; 
                default:
                this.iscur = 0;
                    this.currentView = 'first';
                   break;        
            }
        }
    }
}
</script>

<style scoped lang="less">  
  .group{font-size:0;height: 26px;line-height:26px;}  
  .group>span{cursor:pointer;display:inline-block;font-size:16px;text-align:center;width:100px;}  
  .cur{color:#fff;background-color: #20a0ff;}  
</style> 

#React 和 Vue

React 和 Vue 有许多相似之处,它们都有:

  • 使用 Virtual DOM
  • 提供了响应式(reactive)和可组合的视图组件(composable view component)。
  • 将注意力集中保持在核心库,同时也关注路由和负责处理全局状态管理的辅助库。

猜你喜欢

转载自blog.csdn.net/panying0903/article/details/79287958