## Vue.js 提供了 MVVM 数据绑定和一个可组合的组件系统,具有简单、灵活的 API
1.MVVM模型
使用Vue的过程就是定义MVVM各个组成部分的过程的过程。
* 定义View
* 定义Model
* 创建一个Vue实例或"ViewModel",它用于连接View和Model。
====
<body>
<!--这是我们的View-->
<div id="app">
{{ message }}
</div>
</body>
<script src="js/vue.js"></script>
<script>
// 这是我们的Model
var exampleData = {
message: 'Hello World!'
}
// 创建一个 Vue 实例或 "ViewModel"
// 它连接 View 与 Model
// {el:"",data:""}是选项对象,可以包含数据、挂载元素、方法、模生命周期钩子等等。
new Vue({
el: '#app',
data: exampleData
})
</script>
====
2.双向数据绑定:
v-model:实现表单输入和应用状态之间的双向绑定
====
<!--这是我们的View-->
<div id="app">
<p>{{ message }}</p>
<input type="text" v-model="message"/>
</div>
====
将message绑定到文本框,当更改文本框的值时,<p>{{ message }}</p> 中的内容也会被更新。
顺序是input和Model对象属性message绑定,<p>{{message}}</p>和Model对象属性message绑定。
3.vue指令是什么呢?(通过指令实现双向数据绑定)
vue.js的指令是以v-开头的,它们作用于HTML元素,指令提供了一些特殊的特性,将指令绑定在元素上时,指令会为绑定的目标元素添加一些特殊的行为,我们可以将指令看作特殊的HTML特性(attribute)。
* 每个Vue实例都会代理其选项对象里的data属性。
*
* v-if指令:
v-if是条件渲染指令,它根据表达式的真假来删除和插入元素,它的基本语法如下:
v-if="expression",expression是一个返回bool值的表达式。
====
<body>
<div id="app">
<h1>Hello, Vue.js!</h1>
<h1 v-if="yes">Yes!</h1>
<h1 v-if="no">No!</h1>
<h1 v-if="age >= 25">Age: {{ age }}</h1>
<h1 v-if="name.indexOf('jack') >= 0">Name: {{ name }}</h1>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
yes: true,
no: false,
age: 28,
name: 'keepfool'
}
})
</script>
====
数据的yes属性为true,所以"Yes!"会被输出;
数据的no属性为false,所以"No!"不会被输出;
运算式age >= 25返回true,所以"Age: 28"会被输出;
运算式name.indexOf('jack') >= 0返回false,所以"Name: keepfool"不会被输出。
* v-show指令:
v-show也是条件渲染指令,和v-if指令不同的是,使用v-show指令的元素始终会被渲染到HTML,它只是简单地为元素设置CSS的style的display属性。
* v-else指令:
可以用v-else指令为v-if或v-show添加一个“else块”。v-else元素必须立即跟在v-if或v-show元素的后面——否则它不能被识别。
* v-for指令:
v-for指令基于一个数组渲染一个列表,它和JavaScript的遍历语法相似:v-for="item in items"
items是一个数组,item是当前被遍历的数组元素。
* v-bind指令:缩写是:号
v-bind指令可以在其名称后面带一个参数,中间放一个冒号隔开,这个参数通常是HTML元素的特性(attribute),例如:v-bind:class。
语法:v-bind:argument="expression"
* v-on指令:缩写是@
v-on指令用于给监听DOM事件,它的用语法和v-bind是类似的,例如监听<a>元素的点击事件:
语法:<a v-on:click="doSomething">
4.小demo跑起来:
====
<body>
<div id="app">
<fieldset>
<legend>
Create New Person
</legend>
<div class="form-group">
<label>Name:</label>
<input type="text" v-model="newPerson.name"/>
</div>
<div class="form-group">
<label>Age:</label>
<input type="text" v-model="newPerson.age"/>
</div>
<div class="form-group">
<label>Sex:</label>
<select v-model="newPerson.sex">
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</div>
<div class="form-group">
<label></label>
<button @click="createPerson">Create</button>
</div>
</fieldset>
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Sex</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr v-for="person in people">
<td>{{ person.name }}</td>
<td>{{ person.age }}</td>
<td>{{ person.sex }}</td>
<td :class="'text-center'"><button @click="deletePerson($index)">Delete</button></td>
</tr>
</tbody>
</table>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
newPerson: {
name: '',
age: 0,
sex: 'Male'
},
people: [{
name: 'Jack',
age: 30,
sex: 'Male'
}, {
name: 'Bill',
age: 26,
sex: 'Male'
}, {
name: 'Tracy',
age: 22,
sex: 'Female'
}, {
name: 'Chris',
age: 36,
sex: 'Male'
}]
},
methods:{
createPerson: function(){
this.people.push(this.newPerson);
// 添加完newPerson对象后,重置newPerson对象
this.newPerson = {name: '', age: 0, sex: 'Male'}
},
deletePerson: function(index){
// 删一个数组元素
this.people.splice(index,1);
}
}
})
</script>
====
5.组件系统是什么? 所有的 Vue.js 组件其实都是被扩展的 Vue 实例 ***********重要视角**********************
组件可以扩展HTML元素,封装可重用的HTML代码,我们可以将组件看作被扩展的 Vue 实例
|
* Vue.js的组件的使用有3个步骤:创建组件构造器、注册组件和使用组件。
第一步:调用Vue.extend()方法创建组件构造器
第二步:调用Vue.component()方法注册组件(全局组件)
第三步:在Vue实例的作用范围内使用组件
====
<body>
<div id="app">
<!-- 3. #app是Vue实例挂载的元素,应该在挂载元素范围内使用组件-->
<my-component></my-component>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
// 1.返回一个vue实例
var myComponent = Vue.extend({
template: '<div>This is my first component!</div>'
})
// 2.将组件的vue实例与<my-component>对应起来
Vue.component('my-component', myComponent)
new Vue({
el: '#app'
});
</script>
|
* 全局注册和局部注册:
调用Vue.component()注册组件时,组件的注册是全局的,这意味着该组件可以在任意Vue示例下使用。如果不需要全局注册,或者是让组件使用在其它组件内,可以用选项对象的components属性实现局部注册。
====
<script>
// 1.创建一个组件构造器
var myComponent = Vue.extend({
template: '<div>This is my first component!</div>'
})
new Vue({
el: '#app',
components: {
// 2. 将myComponent组件注册到Vue实例下
'my-component' : myComponent
}
});
</script>
====
|
* 父组件和子组件:
我们可以在组件中定义并使用其他组件
====
<body>
<div id="app">
<parent-component>
</parent-component>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var Child = Vue.extend({
template: '<p>This is a child component!</p>'
})
var Parent = Vue.extend({
// 在Parent组件内使用<child-component>标签
template :'<p>This is a Parent component</p><child-component></child-component>',
components: {
// 局部注册Child组件,该组件只能在Parent组件内使用
'child-component': Child
}
})
// 全局注册Parent组件
Vue.component('parent-component', Parent)
new Vue({
el: '#app'
})
</script>
====
Child组件是在Parent组件中注册的,它只能在Parent组件中使用,确切地说:子组件只能在父组件的template中使用。
小结:介绍了组件从创建到使用的步骤,并介绍了几种不同的方式去创建和注册组件;然后介绍了组件的props选项,它用于将父组件的数据传递给子组件。
8.深入分析vue项目:
1.每个 Vue.js 应用都是通过构造函数创建一个 Vue 的根实例启动
====
new Vue({}); 这是构造实例的过程。传入参数:传入一个选项对象,它可以包含数据、模板、挂载元素、方法、生命周期钩子等选项
2.所有的 Vue.js 组件其实都是被扩展的 Vue 实例
3.vue实例的属性与方法:
* 每个 Vue 实例都会代理其 data 对象里所有的属性
* 注意只有这些被代理的属性是响应的
* 除了 data 属性, Vue 实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀 $,以便与代理的 data 属性区分。
4.初始化过程。
* 例如,实例需要配置数据观测(data observer)、编译模版、挂载实例到 DOM ,然后在数据变化时更新 DOM
* 也有一些其它的钩子,在实例生命周期的不同阶段调用,如 mounted、 updated 、destroyed 。钩子的 this 指向调用它的 Vue 实例
*
* vue实例创建后,data和event已经初始化完成;
创建后,检测el和template,若存在el,编译自定义模板或者el的自有模板;
将创建的vm.$el去替换原网页中的el(dom对象);此时已经挂载成功。
5.模板语法
* 在底层的实现上, Vue 将模板编译成虚拟 DOM 渲染函数。
* 结合【响应系统】,在【应用状态改变】时, Vue 能够智能地计算出重新渲染组件的最小代价并应用到 DOM 操作上。
* 模板上的【计算】和【css改变】的解决方法
6.组件:
* 在 Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。
* 注意在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。
* 父子组件之间的访问:
父组件访问子组件:使用$children或$refs
子组件访问父组件:使用$parent
子组件访问根组件:使用$root
* 非父子组件通信:
应该考虑使用专门的 状态管理模式.
* 为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板;
使用特殊的 <slot> 元素作为原始内容的插槽