Vue笔记系列(二)Vue.js渐进

Vue笔记系列
1、Vue.js入门
3、Vue.js进阶

API

以下会随用随记一些API,可能会不定期更新。

  • Vue.component( id, [definition] ) .

注册或获取全局组件。注册还会自动使用给定的id设置组件的名称。

// 注册组件,传入一个扩展过的构造器
Vue.component('my-component', Vue.extend({ /* ... */ }))
// 注册组件,传入一个选项对象(自动调用 Vue.extend)
Vue.component('my-component', { /* ... */ })
// 获取注册的组件(始终返回构造器)
var MyComponent = Vue.component('my-component')
  • Vue.extend(options) .

使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。注意:data 选项是特例,在 Vue.extend() 中它必须是函数。


// 创建构造器
var Profile = Vue.extend({
      template: '

', data: function () { return { name: '第一个构造器!' } } }) // 创建 Profile 实例,并挂载到一个元素上(会替换#mount-pointer)。挂载的组件会把被挂载的元素替换掉。 new Profile().$mount('#mount-pointer');

结果如下:

第一个构造器!

如果挂载元素不想被替换掉,可以用以下方法:

var component = new Profile().$mount()
document.getElementById('mount-pointer').appendChild(component.$el)
  • Vue.set( object, key, value ) 设置对象的属性。

Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。Vue 不允许在已经创建的实例上动态添加新的根级响应式属性(所以,set方法的object参数也不能是 Vue 实例,或者 Vue 实例的根数据对象)。可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象
之前说过的v-for指令,当你利用索引直接设置一个项时,例如上文的example1.words[0] = {text: 'A'},如果想让视图更新,其中一种方法就是用set。

Vue.set(example1.items, 0, {text: 'A'})
  • Vue.nextTick( [callback, context] )  涉及到Vue的异步更新队列

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

{{message}}
  var vm = new Vue({ el: '#example', data: { message: '123' } }) vm.message = 'new message' // 更改数据 vm.$el.textContent === 'new message' // false Vue.nextTick(function () { vm.$el.textContent === 'new message' // true })

为毛第一次DOM里面的内容没有变,拿不到改变的内容,经过nextTick方法后才才能拿到改变的内容。
这是因为,当你设置 vm.someData = 'new value' ,该组件不会立即重新渲染。当刷新队列时,组件会在事件循环队列清空时的下一个“tick”更新。


全局配置

全局配置——Vue.config 是一个对象,包含 Vue 的全局配置。有以下属性:

  • silent    Vue.config.silent = true; 取消 Vue 所有的日志与警告,false时开启。
  • devtools  Vue.config.devtools = true; 配置是否允许 vue-devtools 检查代码。开发版本默认为 true,生产版本默认为 false。vue-devtools指的是一个浏览器插件,在谷歌应用里面有。

Vue笔记系列(二)Vue.js渐进_第1张图片

安装之后,是在google 开发者工具的这里找到。
Vue笔记系列(二)Vue.js渐进_第2张图片


组件

一、使用组件

  • 注册

1、全局注册
注册一个全局组件,可以使用 Vue.component(tagName, options)
注意:对于自定义标签名,Vue.js 不强制要求遵循 W3C规则 (小写,并且包含一个短杠),但是建议这样写。
组件在注册之后,便可以在父实例的模块中以自定义元素的形式使用。谨记要确保在初始化根实例之前注册了组件。并且, el 和 data 选项必须是函数


// 注册,这就是所谓的语法糖,因为下面的方法有点麻烦。
Vue.component('my-component', {
      template: '
我的第一个组件!
' }) // 创建父实例 new Vue({ el: '#example' })

渲染为:

我的第一个组件!

2、构造器用作组件
可以使用 Vue.extend({...}) 创建一个组件构造器,extend 方法创建基础Vue构造器的子类,参数是一个对象,包含组件选项,这里要注意的特例是 el 和 data 选项,在 Vue.extend() 中,它们必须是函数注册组件的component方法也一样。这是因为,如果使用一个数据对象(是一个引用),那么所有的组件实例都共享这一个对象,这样就会牵一发而动全身。
有了这个构造器,我们既可以用全局注册的方式用 Vue.component(tag, constructor) 注册,也可以利用该构造器构建一个实例,然后用 Vue.$mount() 将该组件实例添加到DOM树上。


// 创建构造器
var Profile = Vue.extend({
      template: '

', data: function () { return { name: '第一个构造器组件!' } } }) // 注册 Vue.component('my-component',Profile) // 创建父实例 new Vue({ el: '#example' })

渲染为:

第一个构造器组件!

3、局部注册
通过使用组件实例选项注册,可以使组件仅在另一个实例/组件的作用域中可用。即在注册的对象参数中添加 components 成员,components成员的标签就只在该组件内使用,不在全局DOM树中使用局部注册的组件。

//实例作用域
var Child = {
  template: '
一个局部组件!
' } new Vue({ // ... components: { // 将只在父模板可用 'my-component': Child } })   //组件作用域

子组件只能在父组件的template中使用。注意下面两种子组件的使用方式是错误的:

  1. 以子标签的形式在父组件中使用

因为当子组件注册到父组件时,Vue.js会编译好父组件的模板,模板的内容已经决定了父组件将要渲染的HTML。
相当于运行时,它的一些子标签只会被当作普通的HTML来执行,不是标准的HTML标签,会被浏览器直接忽视掉。

  1. 在父组件标签外使用子组件

运行这段代码,浏览器会提示以下错误:

Vue笔记系列(二)Vue.js渐进_第3张图片

4、is特性
一些 HTML 元素,如

      ...

      二、组件通信

      良好的流程: Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。
      Vue笔记系列(二)Vue.js渐进_第4张图片

      1、Prop显式声明

      • (1)、使用prop传递数据

      组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。prop 是父组件用来传递数据的一个自定义属性。子组件需要显式地用 props选项声明 “prop”:

      读到这里,我们掌握的组件的构造选项对象的属性包括了:

      • template,要渲染的内容
      • data,数据,必须是一个函数,函数返回一个对象
      • props,从父组件传递数据到子组件。
      3、内容分发
      • (1)编译作用域

      父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。说白了,就是一眼看上去,在谁里面就是谁的

      在my-component标签上使用指令v-show="display",这个display数据是来源于Vue实例vm ,还是my-component组件呢?
      答案是Vue实例

      Vue笔记系列(二)Vue.js渐进_第5张图片

      • (2)单个Slot

      下面的代码在定义my-component组件的模板时,指定了一个元素。

      这是父组件的内容!

       

      第一个标签有一段分发内容

      这是父组件的内容!

      ,渲染组件时显示了这段内容。
      第二个标签则没有,渲染组件时则显示了slot标签中的内容。

      Vue笔记系列(二)Vue.js渐进_第6张图片

      • (3)具名slot

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

      这是一个头部

      neirong

      neirong

      这是一个底部
       

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

      • (4)作用域插槽

      作用域插槽是一种特殊类型的插槽,用作使用一个(能够传递数据到)可重用模板替换已渲染元素。
      数据传递,可重用,自然而然的想到循环

      • 基于官网给出一个完整的例子
       
      三、组件小贴士
      • (1)组件的命名

      当注册组件(或者 props)时,可以使用 kebab-case ,camelCase ,或 TitleCase。但是,在 HTML 模版中,请使用 kebab-case 形式:

      // 在组件定义中
      components: {
        // 使用 kebab-case 形式注册
        'kebab-cased-component': { /* ... */ },
        // register using camelCase
        'camelCasedComponent': { /* ... */ },
        // register using TitleCase
        'TitleCasedComponent': { /* ... */ }
      }
       
      
      
      
      

      注意:当使用字符串模式时,可以不受 HTML 的 case-insensitive 限制。


      生命周期

      Vue笔记系列(二)Vue.js渐进_第7张图片

      1、生命周期的各阶段
      • (1)beforeCreate

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

      • (2)created

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

      • (3)beforeMount

      在挂载开始之前被调用:相关的 render 函数首次被调用。该钩子在服务器端渲染期间不被调用。

      • (3)mounted

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

      • (4)beforeUpdate

      数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。
      你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
      该钩子在服务器端渲染期间不被调用。

      • (5)updated

      由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
      当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
      该钩子在服务器端渲染期间不被调用。

      • (6)activated

      keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用。

      • (7)deactivated

      keep-alive 组件停用时调用。该钩子在服务器端渲染期间不被调用。

      • (8)beforeDestroy

      实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用。

      • (8)destroyed

      Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

      2、实例方法
      • (1) vm.$mount( [elementOrSelector] )

      手动地挂载一个未挂载的实例,返回值是实例自身。因而可以链式调用其它实例方法。
      如果没有提供 elementOrSelector 参数,模板将被渲染为文档之外的的元素,并且你必须使用原生DOM API把它插入文档中。

      var MyComponent = Vue.extend({
        template: '
      Hello!
      ' }) // 创建并挂载到 #app (会替换 #app) new MyComponent().$mount('#app') // 同上 new MyComponent({ el: '#app' }) // 或者,在文档之外渲染并且随后挂载,这种方式不会替换#app var component = new MyComponent().$mount() document.getElementById('app').appendChild(component.$el)
      • (2) vm-destroy()

      完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。触发 beforeDestroy 和 destroyed 的钩子。
      注意:在大多数场景中你不应该调用这个方法。最好使用 v-if 和 v-for 指令以数据驱动的方式控制子组件的生命周期。

      • (3)vm.$nextTick( [callback] )  涉及到Vue的异步更新队列

      回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
      应用上,在组件内使用 vm.$nextTick() 实例方法特别方便,因为它不需要全局 Vue ,并且回调函数中的 this 将自动绑定到当前的 Vue 实例上:

      Vue.component('example', {
        template: '{{ message }}',
        data: function () {
          return {
            message: 'not updated'
          }
        },
        methods: {
          updateMessage: function () {
            this.message = 'updated'
            console.log(this.$el.textContent) // => '没有更新'
            this.$nextTick(function () {
              console.log(this.$el.textContent) // => '更新完成'
            })
          }
        }
      })

你可能感兴趣的:(vue.js)