Vue初步分析

Vue的简介

  • Vue是一套用于构建用户界面的渐进式框架
  • 可以自底向上逐层引用
  • Vue的核心库只关注视图层

Vue组件

  • 跨组件数据流
  • 自定义事件通信
  • 构建工具集成
  • 单向数据流

组件注册

或者如果你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:

1
2
3
4
5
6
7
8
import ComponentA from './ComponentA.vue'

export default {
components: {
ComponentA
},
// ...
}

注意在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写,即这个变量名同时是:

  • 用在模板中的自定义元素的名称
  • 包含了这个组件选项的变量名

动态组件

1
2
3
4
5
<component v-bind:is="currentTabComponent"></component>

在上述的示例中,currentTabComponent 可以包括
已注册组件的名字
一个组件的选项对象

全局组件

如果你的组件颗粒度很小,那么可以考虑将其注册在全局上

记住全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生

props属性

1
2
3
4
5
6
7
8
9
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}

这不仅为你的组件提供了文档,还会在它们遇到错误的类型时从浏览器的 JavaScript 控制台提示用户

注意事项
  • 即使传递的是静态数组,也需要使用v-bind

  • 单向数据流

    • 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
    • 如果真的需要改
      • 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。
      • 这个 prop 以一种原始的值传入且需要进行转换

Vue实例

var vm = new Vue({

​ el: ‘#example’, Vue 实例使用的根 DOM 元素

​ data: data, Vue实例观察的数据对象,Vue实例代理了对其data对象属性的访问

​ props 当前组件接收到的props对象,Vue实例代理了对其props对象属性的访问

​ options

​ 用于当前Vue实例的初始化选项。需要在选项中包含自定义属性时会有用处

1
2
3
4
5
6
new Vue({
customOption: 'foo',
created: function() {
console.log(this.$options.customOption) => 'foo'
}
})

​ parent 父实例,如果当前实例有的话

​ root 当前组件树的根实例,如果没有父实例–将会是其自己

​ children

​ 当前实例的直接子组件,需要注意$children并不保证顺序,也不是响应式的。

​ 如果你发现自己正在尝试使用$children来进行数据绑定,考虑使用一个数组配置v-for来生成子组件,并且使用Array作为真正的来源

​ slots

​ scopedSlots

​ refs 一个对象,持有注册过 ref特性的所有的DOM元素和组件实例

​ isServer 当前 Vue 实例是否运行于服务器。

​ attrs { [key: string]: string }

​ 包含了父作用域中不作为prop被识别(且获取)的特性绑定(class和style除外)。当一个组件没有声明任何prop时,这里会包含所有父作用域的绑定,并且可以通过v-bind=”$attrs”传入内部组件

​ listeners

​ 包含了父作用域中的(不含.native修饰器的)v-on 事件监听器。它可以通过v-on=”$listeners” 传入内部组件

});

所有的Vue组件都是Vue实例,并且接受相同的选项对象(一些根实例特有的选项除外:el) –参考Vue-router

实例方法

vm.$watch(expOrFn, callback, [options])
  • 参数:

    • {string | Function} expOrFn
    • {Function | Object} callback
    • {object} [options]
      • {boolean} deep
      • {boolean} immediate
  • 返回值: {Function} unwatch

    1
    2
    3
    4
    5
    6
    7
    vm.$watch('a.b.c', function(newVal, oldVal) {
    'do something'
    })

    var unwatch = vm.$watch('a', Fun);
    取消观察操作
    unwatch()
  • 选项 :deep

    • 为了发现对象内部值的变化,可以在选项参数中指定 deep: true 。–(注意数组不需要这么做)

      1
      2
      3
      4
      5
      vm.$watch('someObject', callback, {
      deep: true
      })
      vm.someObject.nestedValue = 123
      // callback is fired
  • 选项:immediate

    • 在选项参数中指定 immediate:true 将立即以表达式的当前值触发回调

      1
      2
      3
      4
      vm.$watch('a', callback, {
      immediate: true
      })
      // 立即以 'a' 的当前值触发回调
vm.$set(target, propertyName/index, value);
vm.$delete(target,propertyName/index,value);

实例属性-数据

  • 只有当实例被创建时,data中存在的属性才是响应式的
    • 递归defineProperty() ,采用数据劫持结合发布-订阅模式
  • 如果你知道你晚些会用一些值,你需要设置一些初始值
  • 唯一的例外是使用Object.freeze()
    • 无法再次修改本身及原型

向外暴露的实例属性和方法

vm.$data === data; => true

vm.$el === document.getElementById(‘example’) => true

vm.$watch (‘a’, function(newValue, oldValue) {})

computed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 计算属性将被混入到vue的实例中
computed: {
//计算属性的getter
reversedMessage: function() {
// this指向vm实例
return this.message.split('').reverse().join()
}
}
《tips》: 如果使用了箭头函数,需要传递一个参数--获取vm实例对象
计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果某个依赖(比如非响应式属性)在该实例范畴之外,则计算属性是不会被更新的 --- 比如为对象新增一个属性,这个属性一开始没被定义
this.myObject.newProperty = 'hi')

-----------------------------------计算属性的setter----------------------------
computed: {
fullName: {
// getter
get: function() {},
// setter
set: function(newValue) {
var names = newValue.split('');
this.firstName = names[0];
this.lastName = names[names-length -1]
}
}
}
现在再运行 vm.fullNam = 'ken Done' 时,setter会被调用

watch

1
2
3
4
5
6
7
// 虽然计算属性在大多数情况下更合适,但是在数据变化时执行异步或开销较大的操作时,这个方式是最有用的
watch: {
question: function(val) {
this.answer = 'wait ...'
this.someMethod();
}
}

生命周期

创建前后

挂载前后

更新前后

删除前后

DOM模板的注意事项

有些 HTML 元素,诸如 <ul><ol><table><select>,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li><tr><option>,只能出现在其它某些特定的元素内部。

这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:

1
2
3
<table>
<blog-post-row></blog-post-row>
</table>

这个自定义组件 <blog-post-row> 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is 特性给了我们一个变通的办法:

1
2
3
<table>
<tr is="blog-post-row"></tr>
</table>

—————————————————-或者使用.vue文件的template模板

文章目录
  1. 1. Vue的简介
  2. 2. Vue组件
    1. 2.0.0.1. 组件注册
    2. 2.0.0.2. 动态组件
    3. 2.0.0.3. 全局组件
    4. 2.0.0.4. props属性
      1. 2.0.0.4.1. 注意事项
  • 3. Vue实例
    1. 3.0.0.1. 实例方法
      1. 3.0.0.1.1. vm.$watch(expOrFn, callback, [options])
      2. 3.0.0.1.2. vm.$set(target, propertyName/index, value);
      3. 3.0.0.1.3. vm.$delete(target,propertyName/index,value);
    2. 3.0.0.2. 实例属性-数据
    3. 3.0.0.3. computed
    4. 3.0.0.4. watch
  • 4. 生命周期
  • 5. DOM模板的注意事项
  • |