Vue_Vue权威指南

Vue特性

Vue只是聚焦视图层,是一个构建数据驱动的Web界面的库。
Vue通过简单 API提供高效的数据绑定和灵活的组件系统

  1. 轻量

  2. 数据绑定

  3. 指令

  4. 插件化

架构从传统后台MVC 向REST API + 前端MV*迁移
DOM是数据的一种自然映射

Vue核心:
组件化数据驱动

组件化: 扩展HTML元素,封装可重用的代码
每个组件对应一个工程目录,组件所需要的各种资源在这个目录下就近维护。

Vue与其它框架的区别

对比标准:
文件大小(性能)入门曲线(易用),社区繁荣,吸取优点

与AngularJs区别

相同点:

  • 支持指令 -- 内置指令和自定义指令

  • 支持过滤器 -- 内置过滤器和自定义过滤器

  • 支持双向绑定

  • 都不支持低端浏览器(IE6/7/8)

不同点:
在性能上,ANgualrJS依赖对数据做脏检查,所以Watcher越多越慢,Vue使用依赖追中的观察并且使用异步队列更新,所有的数据都是独立触发的。

与React的区别

相同点:

  • React采用特殊的JSX语法,Vue在组建开中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用。

  • 中心思想相同:一切都是组件,组件实例之间可以嵌套。

  • 都提供合理的钩子函数,可以去定制化的去处理需求。

  • 都不内置类似AJAX,Router等功能到核心包,而是以其它方式(插件)加载。

  • 在组建开发中,都支持mixins的特性。

不同点:

  • React依赖 Virtual DOM,而Vue使用的DOM模板。React采用的Virtual DOM会对渲染出来的结果做脏检查

  • Vue在模板中提供了指令,过滤器等。可以方便快捷的操作DOM。

脏检查:在angular中,没有办法对数据是否做了更改,所以设置触发条件,当触发这些条件,就执行一个检查来遍历所有的数据,对比更改的地方,然后执行变化,保留没有更改的地方。
效率不高,很多多余,称之为 脏检查。(过程:数据修改了,结果:保留就数据)

Vue稳定版本:1.0.24

数据绑定

数据绑定是将数据和视图想关联,当数据发生变化时,可以自动更新视图。

插值

mustache标签
文本插值:{{}}
有时候只需渲染一次数据,后续数据变化不再关心,使用:{{*}}
HTML片段:{{{}}}

注意:Vue指令和自身特性内是不可以插值。

表达式

mustache标签可以由JavaScript表达式和过滤器(本质上是一个JavaScript函数)构成。

表达式:各种数值,变量,运算符的综合体。

{{var a = 100;}} // 错误。 是语句,并不是表达式
{{if (true) return 'a'}} // 条件控制语句是不支持,可以使用 三目运算符

指令

作用:当表达式的值发生变化时,将这个变化也反映到DOM上。

分隔符

  1. delimiters

    Vue.config.delimiters = ['<%', '%>'];
    

修改了默认的文本插值的分隔符,则文本插值的语法由{{example}} 变为<%example%>

  1. unsafeDelimiters

    Vue.config.unsafeDelimiters = ['<$', '$>'];
    

    如果修改了默认的HTML插值的分隔符,则HTML插值的语法由{{example}}变为 <$emample$>

指令

指令的值限定为绑定表达式。
作用:当其表达式的值改变时把某些特殊的行为应用到DOM上。

内部指令

v-if

根据表达式的值在DOM中生成或移除一个元素。

v-show

根据表达式的值来显示或隐藏HTML元素。

在切换v-if模块时,Vue有一个局部编译/卸载过程,因为v-if中的模板可能包括数据绑定或子组件,v-if是真实的条件渲染,因为它会包缺条件块在切换时合适地销毁与重建条件块内的时间监听器和子组件

v-if是惰性的---如果初始渲染时条件为假,则什么也不做,在条件第一次变为真时才开始局部编译(编译会被缓存起来)
相比v-show -- 元素始终被编译并保留,只是简单的基于CSS切换。

v-if有更高的切换消耗,而v-show有更高的初始渲染消耗。因此,如果需要频繁的切换,则使用v-show较好,如果在运行时条件不大可能变化,则使用v-if较好

v-else

必须跟着v-ifv-show后面,充当else功能

v-model

用来在 input, select, text, checkbox, radio 等表单控件元素上创建双向数据绑定。根据控件类型,v-model自动选取正确的方法更新元素。

v-model指令可以添加参数number,lazy,debounce







v-for

基于源数据重复渲染元素,可以使用$index来呈现相对应的数组索引

  • {{item.childMsg}}

Vue 1.0.17及以后支持 of分隔符.

使用v-for,将得到一个特殊的作用域,需要明确指定props属性传递数据,否则在组建内江获取不到数据。(隔离作用域)



    

{{item.text}}

Vue包装了被观察数据的变异方法,它们能触发视图更新。
push(),pop(),shilt(),unshift(),splice(),sort(),reverse()

Vue重写了这些方法之后,触发了notify

Vue增加了两个方法来观测变化:$set$remove

$set : 通过索引设置数组元素并触发视图更新。

vm.animals.$set(0, {name: 'Aardvark'});

$set,$remove 底层都是调用splice()方法。

应该尽量避免直接设置数据绑定的数组元素,因为这些变化不会被Vue检测到,因为也不会更新视图渲染,可以使用$set().

Vue不能检测到数组的变化

  • 直接用索引设置元素. 例如:vm.items[0] = {};

  • 修改数据的长度, 例如:vm.items.length = 0;

解决方法:

vm.items.$set(0, {});

第二个问题,用一个空数据替换items即可。

v-for遍历一个对象,每一个重复的实例都将有一个特殊的属性$key,或者给对象的简直提供一个别名。

  • {{$key}} : {{item}}
  • {{key}} : {{item.msg}}
  • v-for 支持整数

  • ECMAScript无法检测到新属性添加到一个对象上或者在对象中删除。要处理这样的状况Vue增加三种方法:$add(key,value),$set(key, value),$delete(key)这些方法可以用来添加和删除属性,同时可以触发视图的更新。

    v-text

    v-text指令可以更新元素的textContent。在内部,{{ Mustache }}插值也被编译为textNode的一个v-text指令。

    
    
    
    {{msg}}
    

    v-html
    可以更新元素的InnerHTML。内容按普通 HTML插入 -- 数据绑定被忽略。

    {{{Mustache}}} 插值也会被编译为锚节点上的一个v-html指令

    不建议直接动态渲染任意的HTML片段,很容易导致XSS攻击.

    {{{html}}}

    v-bind

    响应更新HTML特性,将一个或多个attribute,或一个组件prop动态绑定到表达式。

    
    
    

    在绑定prop时,prop必须在子组件中声明。可以用修饰符指定不同的绑定类型。

    修饰符为:

    • .sync --- 双向绑定,只能用于prop绑定。

    • .noce --- 单次绑定,只能用于prop绑定

    • .camel --- 将绑定的特性名字转换驼峰命名(通常用于绑定用驼峰命名的SVG特性)

    
    
    

    v-on
    用于绑定事件监听器,事件类型由参数指定。

    在监听原生DOM事件时,如果只定义一个参数。 DOM event 为事件的唯一参数;如果在内联语句处理器中访问原生DOM事件,则可以用特殊变量$event把它传入方法中。

    
    
    
    
    
    
    
    

    
    
    
    
    
    
    
    
    
    
    
    
    
    

    v-ref

    在父组件上注册一个子组件的索引,便于直接访问。不需要表达式,必须提供参数id。可以通过父组件的$refs对象访问子组件

    v-el

    为DOM元素注册一个索引,方便通过所属实例的$els访问这个元素。可以用v-el:smoe-el设置this.$els.smoeEl

       
    
    hello Vue

    v-pre

    编译时跳过当前元素和它的子元素。可以用来显示原始Mustache标签。跳过大量没有指令的节点会加快编译。

    v-cloak

    v-cloak 这个指令保持在元素上知道关联实例结果编译。
    解决闪烁问题

    [v-cloak] {
        dispnay: none;
    }
    
    {{message}}

    自定义指令

    自定义指令提供一种机制将数据的变化映射为DOM行为。

    钩子函数

    Vue中的钩子函数都是可选的,相互之间没有制约关系

    • bind, 只调用一次,在指令第一次绑定到元素上时调用。

    • update, 在bind之后立即以初始值为参数第一次调用,之后每当绑定值变化时调用,参数为新值与旧值。

    • unbind,只调用一次,在指令从元素上绑定时调用。

      Vue.directive('my-directive', {
          bind: function () {
              // 准备工作
              // 例如,添加时间处理器或只需要运行一次的高耗任务
          },
          update: function ( newValue, oldValue ) {
              // 值更新时的工作
              // 也会以初始值为参数调用一次    
          },
          unbind: function () {
              // 清理工作
              // 例如,删除bind() 添加的事件监听器    
          }
      });
      

    使用指令:

    只需要update函数是,可以传入一个函数替代定义对象

    
    Vue.direactive('my-directive', function () {
        // update();
    });  
    

    指令实例属性

    所有的钩子函数都将被复制都实际的指令对象中,在钩子内this指向这个指令对象。

    • el -- 指令绑定的元素

    • vm -- 拥有该指令的上下文ViewModel

    • expression -- 指令的表达式,不包括参数和过滤器。

    • arg -- 指令的参数

    • name -- 指令的名字,不包含前缀

    • modifires -- 一个对象,包括指令的修饰符

    • descriptor -- 一个对象,包含指令的解析结果

    将这些属性视为只读,不要修改他们。

    
    

    指令高级选项

    自定义指令提供一种机制将数据的变化映射为DOM行为

    params
    自定义指令可以接收一个params数组,指定一个特性列表,Vue编译器将自定提取绑定元素的这些特性。

    支持动态(v-bind),this.params[key]会自动保持更新。可以指定一个回调,在值变化时调用。

    deep

    如果自定义指令使用在一个对象上,当对象内部属性变化时要触发update,则在指令定义对象中指定 deep:true

    
    
    {{a.b.c}}

    twoWay

    如果指令想VUe实例写回数据,则在指令定义对象中指定twoWay:true
    作用:允许在指令中使用this.set(value)

    
    
    自定义组件:
    父作用域:{{a.b.c}}

    acceptStatement

    传入acceptStatement:true可以让自定义指令接受内联语句,就像v-on那样。

    {{a}}

    Terminal

    Vue通过递归遍历DOM树来编译模块。但是遇到terminal指令时会停止遍历这个元素的后代,这个指令将会接管编译这个元素及其后代的任务。 v-ifv-for都是terminal指令

    priority

    可以给指令指定一个优先级。如果没有指定优先级,普通指令默认是1000,terminal指令默认是2000.同一个元素上优先级高的指令会比其它指令处理得早已一些,优先级一样的指令按照它在元素特性列表中出现的顺序依次处理,但是不能保证这个顺序在不同浏览器中是一致的。

    流程控制指令 v-ifv-for在编译过程中始终拥有最高的优先级。

    指令可使用的配置项:

    Vue.directive(id, {
        params: [],
        deep: true, // 使用对象,对象内部属性变化,触发update
        twoWay: true, // 指令把数据写回Vue实例
        acceptStatement: true, // 自定义指令接受内联语句 (类似`v-on`)
        priority: 2222, // 优先级
        bind: function() {},
        update: function() {},
        unbind: function() {}
    });
    
    Vue.directive(id, function() {
        
    });
    

    问题:

    v-on可以绑定多个方法吗?

    v-on可以绑定多种类型的方法,可以是click,可以是focus事件,也可以是change事件
    但是使用v-on绑定了两个甚至多个click事件,那么v-on只会绑定第一个click事件,其它会被自动忽略。

    
    

    一个Vue实例可以绑定多个element元素吗?

    el为实例提供挂载元素,值可以是CSS选择符,或实际的HTML元素,或返回HTML元素的函数。这边,元素只用作挂载点。如果提供了模板,则元素被替换,除非replace为false.元素可以用vm.$el访问。

    在Vue中如何让v-for循环出来的列表里面的click事件只对当前列表内元素有效?

    1. 从数据角度出发,定好数据结构,然后操作数据

    2. 通过$event对象,获取当前事件源,然后操作下面的元素.

    • {{item.content}}

    计算属性

    通常会在模板中绑定表达式,模板是用来描述视图结构的。如果模板中的表达式存在过多的逻辑,模板会变成臃肿不堪,维护变得非常困难,因此,为了简化逻辑,当某个属性值依赖于其它属性的值,可以使用计算属性。

    什么是计算属性

    计算属性就是当其依赖属性的值发生变化时,这个属性的值会自动更新,与之相关的DOM部分也会同步自动更新。


    didi = {{didi}}, family = {{family}}, didiFamily = {{didiFamily}}

    计算属性缓存

    计算属性方法中执行大量的耗时操作,则可能会带来一些性能问题。
    例如:在计算属性getter中循环一个大的数组以执行很多操作,那么当频繁调用该计算属性时,就会导致大量不必要的运算。
    而在 Vue 0.12.8版本中,在这方面进行了优化,即只有计算属性依赖的属性值发生了改变时才会重新执行getter
    这样存在一个问题:就是只有Vue实例中被观察的数据发生了改变时才会重新执行getter。但是有时候计算属性依赖实时的非观察数据属性。

    {{welcome}}

    {{example}}

    在每次访问example时都取得最新的事件而不是缓存的事件。从Vue 0.12.11版本开始,默认提供了缓存开关。 在计算属性对象中指定cache字段来控制是否开启缓存。

    new Vue({
        el: '.app',
        data: {
            welcome: 'welcome to join didi'
        },
        computed: {
            example: {
                cache: false, // 关闭缓存,默认为true
                get: function () {
                    return Date.now() + this.welcome;
                }
            }
        }
    });
    

    设置cache为false关闭缓存之后,每次直接访问vm.example 时都会重新执行getter方法。

    问题:

    计算属性getter不执行的场景

    当计算属性依赖的数据属性发生改变时,计算属性的getter方法就会执行。在有些情况下,虽然依赖数据属性发生了改变,但计算属性的getter方法并不会执行。

    当包含计算属性的节点被移出模板中其它地方没有再引用该属性时,那么对应的计算属性的getter不会执行。

    Total Price = {{totalPrices}}

    {{totalPrices}}

    表单控件

    基本使用

    text

    设置文本框v-modelname

    
    

    checkbox

    一般的,使用多个复选框,被选中的值将会放入一个数组中。

    Checked lines: {{bizLines | json}}

    radio

    单选按钮被选择时,v-dmoel中的变量值会被赋值为对应的value值。

    select

    通过v-for指令来冬天生成option

    
    

    bizLine: {{bizLine}}

    值绑定

    checkbox

    使用 :value 进行绑定

    
    
    

    vm.bizLines === vm.flash

    v-model

    视图与Model之间同步数据

    lazy
    一般的,v-model在input时间中同步输入框的值与数据,可以添加一个lazy特性。从而改到change事件中去同步。

     
    {{msg}}

    debounce
    设置一个最小延迟,一般的在 AJAX 请求时,有效。

    number
    可以在v-model所在的控件上使用number指令,该指令会在用户输入被同步到Model中时将其转化为数值类型,如果装换结果为NaN,则对应的Model值该是用户输入的原始值。

    过滤器

    过滤器,本质上都是函数,其作用在于用户输入数据后,它能够进行处理,并返回一个数据结果。

    Vue支持在任何出现表达式的地方添加过滤器,除了{{}}mustache风格的表达式之外,还可以在绑定指令的表达式后调用。

    过滤器可以接收参数,参数跟在过滤器后面,参数之间以空格分隔。

    {{msg | filterFunction 'arg1' arg2}}

    过滤器函数始终以表达式的值作为第一个参数,带引号的参数会被当作字符串处理,而不带引号的参数会被当作数据属性名来处理。

    Linux shell 的管道符号,上一个命令的输出可以作为下一个命令的输入。
    Vue过滤器支持链式调用,上一个过滤器的输出的结果可以作为下一个过滤器的输入。

    {{'ddfe' | capitalize | reverse}}
    

    内置过滤器

    字母操作

    capitalize,uppercase,lowercase 三个过滤器用于处理英文字符。

    capitalize 过滤器: 将表达式中的首字母转大写形式。
    uppercase 过滤器:所有字母转换为大写形式。
    lowercase 过滤器:所有字母转为小写形式。

    json

    json过滤器本质上时JSON.stringify(); 的精简缩略版。
    作用:将表达式的值转换为JSON字符串。

    限制
    limitBy,filterBy,orderBy 用于处理并返回过滤后的数组。 例如与v-for搭配使用。

    limitBy

    limitBy过滤器的作用时限制数组为开始的前N个元素,其中N由传入的第一个参数指定。第二个参数可选用于指定开始的偏移量。默认偏移量为 0. 如果第二个参数为3,则表示从数组下标第3个的地方开始计数。

    
    

    filterBy

    第一个参数可以是字符串或者函数。

    orderBy

    返回排序后的数组

    • {{user.lasetName}}--{{user.firsetName}}--{{user.age}}

    自定义过滤器

    fitler语法

    Vue.filter(ID, function() {});

    单参数

    
    

    多参数

    
    

    双向过滤器

    Vue支持把视图(input元素)的值在写回模型前进行转化。

    Vue.filter('MSG', {
        // model -> view
        // read 函数可选
        read: function() {
            console.log( 123 );
        },
        
        // view -> model
        // write函数将在数据被写入Model之前调用
        // 两个参数分别为表达式的新值和旧值
        write: function( newVal, oldVal ) {
            console.log( newVal, oldVal );
        }
    });
    

    动态参数

    如果过滤器参数没有用引号包起来,则它会在当前vm作用域内动态计算。过滤器函数的this始终指向调用它的vm

    
    

    {{msg | concats userInp}}

    过滤器注意点:
    需要给定过滤器一个唯一标识。如果用户自定义的过滤器和Vue内置的过滤器冲突,那么Vue内置的过滤器将会被覆盖。如果后注册的过滤器和之前的过滤器冲突,则之前注册的过滤器层被覆盖。

    过滤器函数的作用时输入表达式的值,经过处理后输出。因此,定义的函数最好可以返回有意义的值。函数没有return语句不会报错,但这样的过滤器没有意义。

    问题

    filterBy/orderBy 过滤后$index 的索引

    在使用 filterBy 或者 orderBy 对表达式进行过滤时,如果同时需要将$index 作为参数,此时的$index将会根据表达式数组或对象过滤后的值进行索引。

    
    
    • {{item.msg}} -- {{$index}}

    自定义 filter 的书写位置

    Vue实例方法

    Vue实例提供一些有用的属性和方法,这些属性和方法名都已前缀$开头

    实例属性

    Vue_Vue权威指南_第1张图片

    组件树访问

    1. $parent 访问当前组件实例的父实例

    2. $root 访问当前组件书的根实例,当前组件没有父实例,$root 表示当前组件的实例本身。

    3. $children 访问当前组件实例的直接子组件实例。

    4. $refs 访问使用v-ref指令的子组件。

    DOM访问

    1. $el 访问挂载当前组件实例的DOM元素。

    2. $els 访问$el元素中使用了v-el指令的DOM元素。

    数据访问

    1. $data 访问组件实例观察的数据对象,该对象引用组件实例化时选项中的data属性。

    2. $options 用来访问组件实例化时的初始化选项对象。

    当实例创建后原本不存在的属性,是无法绑定在视图上的。
    可以使用Vue.set(),vm.$set() 来解决.

    实例方法

    Vue_Vue权威指南_第2张图片

    $appendTo
    $appednTo();方法用来将el所指的DOM元素或片段插入到目标元素中。

    参数:
    elementOrSelector(字符串或DOM元素),该参数可以是一个选择器字符串或者DOM元素。
    callback -- (可选,该回调函数会在el元素被插入到目标元素后背触发。(如果在el上应用了过渡效果,则回调会在过渡完成后被触发)

    $before
    用来将el所指的DOM元素或片段插入到目标元素之前

    参数:
    elementOrSelector
    callback-- (可选)

    $after
    将el所指的DOM元素或片段插入到目标元素之后。

    参数:
    elementOrSelector
    callback-- (可选)

    $remove
    将el所指的DOM元素或片段从DOM中删除
    参数:
    callback -- (可选)

    $nextITick
    在下次DOM更新循环后执行的回调函数,使用该方法可以保证DOM中的内容已经与最新数据保持同步。
    参数:
    callback -- (可选)该回调函数会在DOM更新循环后被执行。它和全局的Vue.nextTick(); 方法一样,不同的是,callback中的this会自动绑定到调用它的Vue实例上。

    实例Event方法的使用

    $on
    监听实例上的自定义事件

    $once
    监听实例上的自定义事件,当之触发一次。

    $emit
    触发事件
    参数:
    event(字符串),该参数可以是一个事件名称
    args (可选),传递给监听函数的参数

    $dispatch()
    派发事件,即先在当前实例触发,再沿着父链一层一层向上,如果对应的监听函数返回false就停止。
    参数:
    event(字符串),该参数可以是一个事件名称
    args (可选),传递给监听函数的参数

    $boradcast()
    广播事件,即遍历当前实例的$children,如果对应的监听函数false就停止。
    参数:
    event(字符串),该参数可以是一个事件名称
    args (可选),传递给监听函数的参数

    $off()
    删除事件监听器

    参数:
    event(字符串),该参数可以是一个事件名称
    args (可选),对应的回调函数

    如果没有参数,即删除所有的事件监听器,如果只提供一个参数--事件名称,即删除它对应的所有监听器。如果提供两个参数--事件名称和回调函数,即删除对应的这个回调函数。

    组件

    组件核心目标是:可重用性高,减少重复性的开发。

    Vue的组件可以理解为预先定义好行为的ViewModel类。一个组件可以预定义选项。

    组件核心选项:

    • 模板(template) -- 声明了数据和最终展现给用户的DOM之间的映射关系

    • 初始化数据(data) -- 一个组件的初始数据状态。对于可复用的组件来说,通常是私有的状态。

    • 接收的外部参数(props) -- 组件之间通过参数来进行数据的传递和共享。参数默认是单向绑定(由上至下),但也可以显示声明为双向绑定。

    • 方法(methods) -- 对数据的改动操作一般都在组件的方法内进行。可以通过v-on指令将用户输入事件和组件方法进行绑定

    • 生命周期钩子函数 -- 一个组件会触发多个生命周期钩子函数,比如:createdattacheddestoryed等。在这些钩子函数中,可以封装一些自定义的逻辑,和传统的MVC想必,着可以理解为Controller的逻辑被分散到了这些钩子函数中。

    基础

    注册

    全局注册

    Vue.component('wind-component', WindComponet);
    

    参数:
    function, 可以是Vue.extend();创建的一个组件构造器,
    Object ,Vue在背后自动调用Vue.extend();

    组件的模板替换了自定义元素,自定义元素的作用只是作为一个挂载点,可以用实例replace决定是否替换自定义元素。

    局部注册

    不需要每个组件都全局注册,可以让组件只能用在其它组件内。可以使用 实例选项中componets注册

    为了让事件更简单,可以直接传入选项对象而不是构造器给Vue.component(); 和 components选项

    数据传递

    Vue组件三种数据传递方式:

    • props

    • 组件通信

    • slot

    props

    'props'是组建数据的一个字段,期望从父组件传下来数据。因为组件的实例的作用域是孤立的,着意味着不能并且不应该在子组件的模板内直接引用父组件的数据,所以子组件需要显示的用props选项来获取父组件的数据。props选项可以是字面量,也可以是表达式,还可以绑定修饰符。

    字面量语法

    
    

    动态语法

    可以利用v-bind将动态props绑定到父组件的数据。每当父组件的数据变化时,该变化也会传到给子组件。
    动态语法:在父级组件链接 :wind="msg"。只能在Vue.extend({}).

    绑定修饰符

    props默认是单向绑定 -- 当父组件的属性变化时,将传导给子组件,但是反过来不会。着是为了防止子组件无意修改父组件的状态。

    • .sync,双向绑定

    • .once, 单次绑定

    双向绑定会把子组件的msg属性同步会父组件的parentMsg属性

    
    
    
    
    
    

    双向绑定会把子组件的msg属性同步到父组件的parentMsg属性,单次绑定在建立之后不会同步之后的变化。如果props是一个对象或数组,那么它是按引用传递的。在子组件内修改会影响父组件的状态,而不管是用哪种类型绑定。

    组件通信

    子组件可以用this.$parent访问它的父组件,父组件有一个数组this.$children,暴行它所有的子元素,根实例的后代可以用this.$root访问根实例,不过子组件应当避免直接依赖父组件的数据,尽量显式的使用 props传递数据。

    在子组件中修改父组件的状态缺点:

    • 父组件与子组件紧密地耦合

    • 只看父组件,很难理解父组件的状态,因为它可能被任意子组件修改。在理解情况下,只有组件自己能修改其状态。

    因为作用域是有层次的,所以可以在作用域链上传递时间。
    一般的,选择事件传递方式,判断规则: 查看要触发事件的作用域。如果要通知整个事件系统,就要向下广播。

    每一个Vue实例都是一个事件触发器:

    • $on() -- 监听事件

    • $emit() -- 把事件沿着作用域向上派送

    • $dispatch() -- 派发事件,事件沿着父链冒泡。 调用

    • $broadcast() -- 广播事件,事件向下传导给所有的后代

    
    
    

    Messages: {{messages | json}}

    从父组件的代码中不能直接观看到child-msg 事件来自哪里。如果在模板中子组件用到的地方声明事件处理器。 可以使用v-on来监听。

    
    
    

    Message {{messages | json}}

    当子组件触发了child-msg 事件时,父组件的 hadleIt方法将被调用。所有影响父组件状态的代码都放到父组件的hadleIt方法中。 子组件只关注触发事件。

    尽管有propsevents,但是有时候仍需要在JavaScript中直接访问子组件。因此,需要使用v-ref为子组件指定一个索引ID。

    v-ref 直接访问子组件

    slot分发内容

    场景:
    使用组件时,常常需要组合使用:

    
        
        
    

    注意:

    • 组件不知道他的挂载点会有什么内容,挂载点的内容是由的父组件决定的。

    • 组件很可能有它自己的模板。

    为了让组件可以组合,需要一种方式来混合父组件的内容与子组件自己的模板。称之为:内容分发
    Vue使用特殊的元素左右原始内容的插槽

    定义在父组件中,父组件中嵌套的其它内容不会被替换。

    编译作用域

    分发内容是在各自作用域中被编译。
    父组件模板的内容在父组件作用域内编译,子组件模板的内容在子组件作用域内编译。

    单个 slot

    父组件的内容被抛弃,除非子组件模板包含.如果子组件模板只有一个没有特性的slot,父组件的整个内容将查到slot所在的地方并替换它。

    标签的内容视为回退内容。回退内容在子组件的作用域内编译,当宿主元素为空并且没有内容供插入时显示这个回退内容。

    
    
    

    This is some original conent

    This is some more original conent

    具名slot

    元素可以用一个特殊特性name配置如何分发内容。多个slot可以有不同的名字。具名slot将皮撇内容片段中有对应slot特性的元素。

    ·具名slot·仍然可以有一个匿名slot.作为找不到匹配的内容片段的回退插槽,它是默认slot。如果没有默认slot,这些找不到匹配的内容片段将被抛弃。

    
    
    

    ONE

    TWO

    defalut A

    混合

    以一种灵活的方式为组建提供分布复用的功能。混合对象可以包含任意的组件选项。
    当组件使用了混合对象时,混合对象的所有选项将别“混入”组件自己的选项中。

    HTML中是不区分大小写,而JavaScript是区分大小写。在给组件取属性名时,要注意大小写问题。尽量使用小写加中横线


    当混合对象和组件包含同名选项时,这些选项将以适当的策略合并。
    例如:同名钩子函数被并入一个数组中,因而都会被调用。另外,混合的钩子函数将在组件自己的钩子之前调用。

    混合全局注册,一旦全局注册混合,它就会影响所有之后创建的Vue实例。
    慎用全局混合,因为它会影响到每个所创建的Vue实例,包括第三方组件。大多数情况下,它应当只用于自定义选项。

    动态组件

    多个组件可以使用同一个挂载点,然后动态的在他们之间切换。使用保留的元素,懂她id绑定到它的is特性上。

    
    
    

    keep-alive

    作用:切换组件时,保留组件状态。减少内存开销。

    activate钩子

    作用: 控制切换组件的切换时间。切入组件添加activate 钩子函数

    Vue.component('actiate-exp', {
        activate: function ( done ) {
            var self = this;
            loadDataAsync(function ( data ) {
                self.smoeData = data;
                done();
            });
        }
    });
    

    activate 钩子只作用于动态组件切换或静态组件初始化渲染的过程中,不作用于使用实例方法手工插入的过程中。

    transition-mode

    transition-mode 特性用于指定连个动态组件之间如何过渡。

    在默认情况下,进入与离开平滑的过渡。

    • in-out --- 新组建先过度进去,等它的过去完成之后当前组件过渡出去。

    • out-in 当前组件先过渡出去,等它过渡完成后新组件过渡进入

    
    
    
    
    
    

    扩展

    组件和 v-for

    自定义组件可以像普通元素一样直接使用v-for
    因为组件的作用域是孤立的,无法将数据传递那个到组件内部。

    
    

    编写可复用组件

    在编写组件时,时刻考虑组件是否可复用是否有好处的。
    一次性组件跟其它组件紧密耦合没关系,但是可复用组件一定要定义侵袭的公开接口。

    Vue组件 API来自三部分 -- prop, Evnetslot

    • prop允许外部环境传递数据组给组件

    • 事件允许组件发出发布环境的action

    • slot运行外部环境将内部插入到组件的视图结构内。

    使用v-bindv-on的简写语法,模板的缩进清楚并简洁

    异步组件需要将应用拆分为小块,每块按实现按需加载。Vue允许将组建定义为一个工厂函数,动态的解析组件的定义。Vue只在组件需要渲染时触发工厂函数,并把结果缓存起来。

    Vue.component('async-exp', function ( resoluve, reject ) {
        setTimeout(function () {
            reslove({
                tempate: '
    ASYNC!
    ' }); }, 1000); });

    工厂函数接受一个resolve回调,在收到从服务器下载的组件定义时调用。

    片段实例

    在使用template选项时,模板的内容将替换实例的挂载元素,因而推荐模板的顶级元素始终是单个元素。

    下面的情况会让实例变成一个片段实例

    • 模板包含多个顶级元素

    • 模板只包含普通文本

    • 模板包含其他组件(其它组件可能是一个片段实例)

    • 模板只包含一个元素指令,如 或 vue-router的

    • 模板根节点有一个流程控制指令,如 v-if 或 v-for

    让实例有未知数据的顶级元素,它将把其DOM内容当作片段。片段实例仍然会正确的渲染内容。不过没有一个根节点,它的$el指向一个锚节点,即一个空的文本节点(在开发模式下是一个注释节点)

    组件元素上的非流程控制指令,非prop特性和过度将被忽略。

    
    
    
    
    
    

    生命周期

    在vue中,在实例化Vue之前,他们以HTML的文本形式保存在文本编辑器中。当实例化后将经历创建,编译,销毁 主要三个阶段

    生命周期钩子:

    1. init
      在实例化开始初始化时同步调用。此时数据观测,事件和Watcher 都尚未初始化

    2. created
      在实例创建后同步调用。此时实例已经结束解析选项,意味着已建立:数据绑定,计算属性,方法,Watcher/事件回调。但是还没有开始DOM编译,$el还不存在。

    3. beforeCompile
      在编译开始前调用。

    4. compiled
      在编译结束后调用。此时所有的指令已生效,因而数据的变化将触发DOM更新。但是不是担保$el已插入文档。

    5. ready
      在编译结束和$el第一次插入文档之后调用,入在第一次attatced钩子之后调用。注意必须是有Vue插入(如vm.$appendTo()等方法或更新)才出发ready钩子的。

      //  { 模板插入到文档中了;相当于window.onload } 
    6. attached
      vm.$el 操作如DOM时调用。必须是→指令实例方法(如$appednTo()) 插入,直接操作vm.$el不会触发这个钩子

    7. detached
      vm.$el从DOM中删除时调用。必须是由指令实例方法删除,直接操作vm.$el不会触发这个钩子

    8. beforeDestroy
      在开始销毁实例时开始调用。此时实例仍然有功能。

    9. destroyed
      在实例被销毁之后调用。此时所有的绑定和实例的指令已经解绑,所有的子实例也已经被效果。如果有离开过渡,dsetroyed钩子在过渡完成之后调用。

    开发组件

    组件格式,把一个组件的模板,样式,逻辑三要素整合在同一个文件中,即方便开发,也方便复用和维护。Vue本身支持对组件的异步加载,配合webpack的分块打包功能,可以实现组件的异步按需加载。

    基于第三方组件开发

    
        
    import Chart from 'chart.js'
    
    

    问题

    camelCase & kebab-case

    HTML标签中的属性名不区分大小写。设置prop名字为camelCase形式的时候,需要装欢为keba-case形式在HTML中使用。

    
    
    
        

    字面量语法&动态语法

    错误用法:
    使用字面量语法传递数值。

    
    
    

    因为它是一个字面量prop,它的值是字符串“1”,而不是一实际的数字传下去。如果需要传递真实的JavaScript类型的数字,则需要使用动态语法。从而让它的值被当作JavaScript表达式计算。

    组件选项问题

    传入Vue构造器的多数选项也可以用Vue.extend();不过有两个特列:datael.
    场景:简单的吧一个对象作为data选项传给Vue.extend();

    var data = { a: 1 };
    var MyComponent = Vue.extend({data: data});

    存在的问题:MyComponent所有的实例哦给你共享同一个data对象。
    解决方式:使用一个函数作为data选项,让这个函数返回一个新对象。

    var MyComponent = Vue.extend({
        data: function () {
            return { a: 1 }
        }
    });

    模板解析

    Vue的模板是DOM模板,使用浏览器元素的解析器而不是自己实现一个。
    DOM模板缺点:必须是有效的HTML片段。

    一些HTML元素对什么元素都可以放在它里面有限制。

    • a 不能包含其他交互元素(如,按钮、连接)

    • ul和ol只能包含li

    • select 只能包含option和optgroup

    • table只能直接包含thead,tbody,tfoot,tr,caption,col,colgroup

    • tr只能直接包含th和td

    自定义标签(包括自定义元素和特殊标签,如.