每个 Vue 应用都是通过用 Vue
函数创建一个新的 Vue 实例开始的:
var vm = new Vue({
// 选项
})
vm
(ViewModel 的缩写) 这个变量名表示 Vue 实例,之所以用到这个名字是受到 MVVM 模型的启发!
这个参数叫做「选项对象」,话说你叫对象不叫好了吗?为啥还有加个「选项」二字?难道说这里的选项指的是,对象里的key是可选的?
根据 API 文档中的描述,你会发现那些就是所谓的选项列表!
总之,这篇教程主要描述的就是如何使用这些选项来创建你想要的行为。
话说我有什么行为想要创建的?而且需要使用这些选项来创建?
一个 Vue 应用由一个通过
new Vue
创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成。
✎:
一个 todo 应用的组件树可以是这样的:
根实例
└─ TodoList
├─ TodoItem
│ ├─ DeleteTodoButton
│ └─ EditTodoButton
└─ TodoListFooter
├─ ClearTodosButton
└─ TodoListStatistics
想要深入了解一下?那就去看组件系统章节。
不过目前,还是建议不要!
此刻的你只需要明白所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象 (一些根实例特有的选项除外)。
为啥Vue组件都是Vue实例啊?不是说一个Vue应用只有一个根Vue实例吗?还是说可以把一个Vue应用当作是个Vue组件呢?又或者是一个Vue应用可以嵌套很多个组件,这些组件本身就类似于根实例?
总而言之,就是把Vue组件看作是Vue实例好了!既然Vue组件它是Vue实例,那么它的能力应该等价于根实例才对啊!???
或者我认为这些组件虽然叫Vue实例,但是同根Vue实例还是有点区别的!
创建了个 Vue实例,传入了一个data对象进来
你data对象搞了几个属性,并在视图中的使用了这些属性,那么一旦这些属性值变化了,那么视图将会自动更新这些值
// 我们的数据对象
var data = { a: 1 }
// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
data: data
})
// 获得这个实例上的属性
// 返回源数据中对应的字段
vm.a == data.a // => true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // => 2
// ……反之亦然
data.a = 3
vm.a // => 3
如果你的data中的某个属性是后引入的,那么不好意思,即便你修改了值,视图也不会响应式的发生变化,所以如果你在后面会用到这些数据,那么最好就给写上,并赋上初始值,如空字符串、undefined、null等等……
后来添加的属性,✎:
vm.b = 'hi'
搞点初始值,✎:
data: {
newTodoText: '',
visitCount: 0,
hideCompletedTodos: false,
todos: [],
error: null
}
使用个Object.freeze()
就好,这会阻止修改现有的属性,简单来说就是Duang一下,把这个对象给冻住了!✎:
var obj = {
foo: '我是个被冻结的字符串'
}
Object.freeze(obj)
new Vue({
el: '#app',
data: obj
})
视图的效果,✎:
<div id="app">
<p></p>
<!-- <p></p> -->
<!-- 这里的 `foo` 不会更新! -->
<button v-on:click="foo = '你肯定看不见这个值吧'">Change it</button>
</div>
如果你在视图中添加这个 <p></p>
,那么会报错,因为这个xxx
未定义,谁叫你用了模板语法呢!
还有就是别以为只有一个属性被冻结,这个obj的所有属性都被冻结了!你想更新data就能更新视图?我劝你还是死了这条心吧!
除了数据属性,Vue 实例还暴露了一些有用的实例属性与方法。它们都有前缀
$
,以便与用户定义的属性区分开来。
视图,✎:
<div id="app">
<p></p>
<button v-on:click="a = '改变a的值'">Change it</button>
</div>
JavaScript,✎:
var data = { a: 1 }
var vm = new Vue({
el: '#app',
data: data
})
console.log(vm.$data === data) // => true
console.log(vm.$el === document.getElementById('app')) // => true
// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
alert('你能看到这个,证明vm.a发生了变化!')
})
以后你可以在 API 参考中查阅到完整的实例属性和方法的列表。
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
created
钩子可以用来在一个实例被创建之后执行代码,✎:
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('Vue实例被创建后就执行')
console.log('a is: ' + this.a)
}
})
// => "a is: 1"
也有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mounted
、updated
和 destroyed
。生命周期钩子的 this
上下文指向调用它的 Vue 实例。
看来实例的生命周期与钩子紧密相连,毕竟可以让用户添加自己的demo!
不要在选项属性或回调上使用箭头函数,比如
created: () => console.log(this.a)
或vm.$watch('a', newValue => this.myMethod())
。因为箭头函数是和父级上下文绑定在一起的,this
不会是如你所预期的 Vue 实例,经常导致Uncaught TypeError: Cannot read property of undefined
或Uncaught TypeError: this.myMethod is not a function
之类的错误。
我的天,这会儿就叫选项属性了!反正这些都是些可选的属性,话说我可以直接new Vue()
吗?
可以,反正都叫选项对象了!这个对象就是可选的哈!老实说,我真想把这个选项对象叫「有很多选项属性的对象」!就像是我可以选A、选B、选C……
下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。
之前有了解过,计算机语言作为程序员控制一台计算机工作的协议,具备了协议的三要素,✎:
为此,我可以从这个方面去了解这个生命周期,一个Vue实例的生命周期就是一个规定好的协议,它有着语法、语义、顺序,我们可以根据这个周期的顺序添加一些demo,让我们的Vue实例更强大!
话说这个created
钩子函数,是在初始化后就执行吗?
$
开头的实例属性与方法这是jQuery的,✎:
➹:jquery - In Javascript, what is an options object? - Stack Overflow
我对选项对象的理解是,在这里应该强调的是选项二字吧!在创建Vue实例时,所传入的对象,Vue提供了许多的选项,即所谓的key,来让开发者来填充这些选项所对应的值。
在之前学习MVC的时候,这种赋值就是所谓的解析赋值吧!
摘录这个答案的回答,✎:
➹:Vue当中钩子函数的具体意思? - Ruphi的回答 - 知乎
按我个人理解,就是在生命周期执行流程中预留的一个能让我们执行自己代码的地方。叫钩子函数,很形象的,钩子钩子,挂载我们自己的东西。
而钩子函数的实现,基本原理就是callback。
先就这么理解吧!
似乎也可以理解成在某种条件下,就执行这个钩子函数!
当然这是Vue的钩子概念……
而JavaScript中的钩子呢?
提供一个可以影响默认的(或原有的)流程(机制)的时机。
通常就是:一个库、一个框架、一个系统或一种语言,提供一个对外公开的接口,通过这个接口,用户能够影响库、框架、系统或程序的行为。
至于具体实现,那是千差万别的。举个例子就是有同学提到了:Java中的模板方法。
所以什么是钩子呢?
套用轮子哥的话,✎:
大概跟很多人要买什么东西,要先跟老婆问候一下,的感觉是差不多的吧。这就是钩子
钩子函数与回调函数有啥关系呢?
按照我的理解就是,钩子函数可以说也是一种回调函数,不过它的这种回调更狭窄一点吧!如事件触发后才执行这钩子函数!
➹:计算机英语中总出现的”hooks” 是什么意思? “钩子” ? 这个钩子应该怎么理解? 是回调的意思? - 知乎
➹:JavaScript:理解事件、事件处理函数、钩子函数、回调函数 - 简书