- 每个Vue会应用通过
new Vue()
方法创建一个根Vue实例,创建Vue实例时可传入一个选项对象。 - Vue虽然并未完全遵循MVVM模型,但Vue设计也受它启发。
- Vue应用通过
new Vue()
创建的根Vue实例,以及可选的嵌套的、可复用的组件树组成。 - 所有Vue组件都是Vue实例,并接受相同的选项对象。
import Vue from "vue";
const vm = new Vue(options={});
选项对象options
选项对象的属性涉及到的参数可划分为五类,分别是数据、DOM、生命周期钩子、资源、组合、其它。
数据
数据 | 描述 |
---|---|
data | Vue实例的数据对象 |
props | 用于接收来自父组件的数据 |
propsData | 创建Vue实例时传递给props的参数,方便测试。 |
computed | 计算属性,会被混入到Vue实例中。 |
methods | 方法,将被混入到Vue实例中。 |
watch | 对象,键是需要观察的表达式,值是对应的回调函数。 |
data
当Vue实例被创建时,它向Vue的响应式系统中加入了data
对象中能找到的所有属性。当属性发生改变时,视图产生响应,即匹配更新为新值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
</div>
<script>
//数据对象
var user = {username:'alice'};
//将数据对象添加到Vue实例中
var vm = new Vue({
data:user
});
console.log(vm.username === user.username);
//设置属性会影响到原始数据,反之亦然。
vm.username = 'ben';
console.log(user.username);
</script>
</body>
</html>
当数据改变时,视图重渲染。只有当实例被创建时data
中存在的属性才是响应式的。即若添加新属性则它的改动不会触发任何视图的更新。
若你之后需某属性,之前定义时设置初始值即可。
var vm = new Vue({
data:{
error:null,
list:[],
count:0,
}
});
唯一的例外是使用Object.freeze()
,会阻止修改现有属性,也意味着响应系统无法再追踪变化。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p>{{data.message}}</p>
<button @click="data.message='world'">change</button>
</div>
<script>
var data = {message:'hello'};
var vm = new Vue({
el:'#app',
data(){
return {data};
}
});
</script>
</body>
</html>
除了数据属性,Vue实例还暴露了一些有用的实例属性和方法。它们都有前缀$
,以便与用户自定义的属性区分。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p>{{data.message}}</p>
<input type="text" v-model="data.message">
</div>
<script>
var data = {message:'hello'};
var vm = new Vue({
el:'#app',
data:data
});
//Vue实例实例属性
console.log(vm.$el===document.getElementById('app'));//output:true
console.log(vm.$data===data);//output:true
//Vue实例方法
vm.$watch('message', function(newVal, oldVal){
console.log('message change');//回调将在vm.message改变后调用
});
</script>
</body>
</html>
DOM
DOM | 描述 |
---|---|
el | 已存在的页面DOM元素的CSS选择器或HTMLElement实例,作为Vue实力的挂载目标。 |
render | 字符串模板代替方案 |
el
如果在Vue实例化时存在el
选项,Vue实例将立即进入编译过程。否则需要显示调用vm.$mount()
方法手动开启编译。
const vm = new Vue({
el:"#app"
});
const vm = new Vue();
vm.$mount("#app");
Vue实例对象vm
提供了$muont
生命周期方法,如果vm
对象在实例化时没有收到el
选项,则会处于“未挂载”的状态,即没有关联的DOM元素。此时可使用vm.$mount(elementOrSelector)
方法手动挂载一个尚未挂载的实例。若没有提供elementOrSelector
参数,模板将被渲染为文档之外的元素。
例如:入口文件main.js
import Vue from 'vue';
import Axios from "axios";
import App from './App.vue';
import router from "./router.js";
Vue.config.productionTip = false;
Vue.prototype.axios = Axios;
//创建vue应用实例并挂在到#index元素上
const vm = new Vue({render:h=>h(App), router:router});//未挂载状态
//手工挂载vm实例
vm.$mount('#index');
$mount
方法会返回vm
实力自身,因此可链式调用其他实例方法。
render
render
作为字符串模板的替代方案,render
渲染函数接收一个createElement
方法作为第一个参数用来创建VNode
节点。若组件是一个函数组件则render渲染函数还会接收一个额外的context
上下文参数,为没有实例的函数组件提供上下文信息。
生命周期钩子
每个Vue实例在被创建时都要经过一系列初始化过程--例如,需设置数据监听、编译、模板、将实例挂载到DOM并在数据变化时更新DOM等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给用户在不同阶段添加自己的代码的机会。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<p>{{data.message}}</p>
<input type="text" v-model="data.message">
</div>
<script>
var data = {message:'hello'};
var vm = new Vue({
el:'#app',
data:data,
created:function(){
console.log('created', this.message);
},
mounted:function(){
console.log('mounted', this.message);
},
updated:function(){
console.log('updated', this.message);
},
destroyed:function(){
console.log('destroyed', this.message);
}
});
</script>
</body>
</html>
created
钩子可用来在实例被创建后执行代码,其他钩子在实例生命周期不同阶段被调用,如mounted
、updated
、destroyed
。生命周期钩子的this
上下文指向调用它的Vue实例。
不要在选项属性或回调上使用箭头函数,比如created:()=>console.log(this.message)
。因为箭头函数是和父级上下文绑定在一起的,this
不会是如你所期待的Vue实例,经常导致Uncaught TypeError: Cannot read property of undefined
或 Uncaught TypeError: this.method is not a function
之类的错误。