# 第二章 数据绑定
>[success] 可在此处查看运行文档中的代码示例结果:[https://github.com/jianyaoo/Vue](https://github.com/jianyaoo/Vue)
[toc]
## 1 - vue实例
每一个vue应用都是起始于先创建一个vue实例,创建方式如下,通过new关键字创建对象。
```
var vm = new Vue({
el:"",
data:"",
.....
})
```
>[info] 通过`new Vue`创建了一个vue的根实例。一个Vue应用一般由根实例、可嵌套的、可复用的组件树组成
## 2 - 响应式数据
>[info] 当一个Vue实例被创建的时候,它会将data对象中的所有属性添加到Vue的响应式系统中,当数据发生改变时,视图也会发生改变。当数据发生变化时,视图会重新渲染。
**<span style="padding-top:15px;display:inline-block;">代码实例</span>**
```
<body>
<div id="app">
<p>{{msg}}</p>
<button @click="handleClick">修改</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
msg:"hello vue",
},
methods:{
handleClick(){
this.msg = "hello click";
},
}
})
</script>
</body>
```
>[danger] 需要注意的是:只有在创建实例时添加的data属性值才会存在响应式系统中。如果是后期动态通过`vm.`的 方式添加上去的,则不会存在于响应式中
>**解决方式:尽量不要通过动态添加data属性,如果在后期需要用到一个data属性则在实例化时就声明为相对应类型的空值即可。**
```
var vm = new Vue({
data:{
newTodoList:"",
count:0,
todos:[]
}
})
```
**<div style="padding-top:15px;">阻止响应</div>**
如果定义的data对象使用了`Object.freeze()`,则会进行修改现在的属性,这会直接导致数据无法在系统中进行响应式。该现象说明:无论是修改了属性值还是修改了视图的本质都是,先修改data属性值,data属性值发生变化触发视图修改。
```
<body>
<div id="app">
<p>{{msg}}</p>
<button @click="handleClick">修改</button>
</div>
<script type="text/javascript">
var obj = {
msg:"hello vue",
}
Object.freeze(obj);
var vm = new Vue({
el:"#app",
data:obj,
methods:{
handleClick(){
this.msg = "hello click"; // 执行后显示的依旧是hello vue
},
}
})
</script>
</body>
```
## 3 - 模板语法
### 插值
在模板中数据绑定最常见的方式就是双大括号法的文本赋值
```html
<span>hello,{{name}}</span>
```
Mustache 标签将会被替代为对应数据对象上`name`属性的值。无论何时,绑定的数据对象上`name`属性发生了改变,插值处的内容都会更新。
在使用插值表达式时的两种情况:`文本`,`原始HTML`
#### 文本
**第一种:文本**
>[info] 文本插值即插入到dom元素中的信息为文本格式,即纯文本,不会对html代码进行解析。
```html
<div id="app">
<p>{{msg}}</p>
<p v-text='msg'></p>
//两者的效果一样
</div>
```
#### HTML
**第二种:原始HTML格式**
>[info] 如果想要修改dom元素的innerHtml,即将data对象中html作为html渲染输出
>
```
<p v-html="msg2"></p>
```
**代码示例**
```
<body>
<div id="app">
<p>{{msg}}</p>
<p v-text="msg1"></p>
<p v-html="msg2"></p>
<button @click="handleClick">修改</button>
</div>
<script type="text/javascript">
var obj = {
msg:"hello vue",
msg1:"<h1>v-text指令</h1>",
msg2:"<h1>v-html指令</h1>"
}
Object.freeze(obj);
var vm = new Vue({
el:"#app",
data:obj,
methods:{
handleClick(){
this.msg = "hello click"; // 执行后显示的依旧是hello vue
},
}
})
</script>
</body>
```
**运行结果比较**
![](https://img.kancloud.cn/d1/60/d1600a545fa8a0223510ec9d9b1a15ab_264x182.png)
>[danger] 在自己的站点直接渲染html是一件非常危险的事情,可能会导致跨站脚本攻击。一定 **不要** 动态渲染用户输入的内容,只对自己信任的内容使用html渲染。
#### 特性
**特性**
使用插值语法只能是渲染内容,不能直接作用到html标签上,如果想要对html标签进行操作需要使用 `v-bind`指令。
```
<div v-bind:id="app"></div>
```
#### 使用js表达式
在插值语法中允许使用简单的js表达式,但是请注意**只能使用简单的表达式,任何语句都不支持。流控制也不支持,需要使用三元表达式**。
```
<p>{{msg.split(' ').reverse().join(',')}}</p>
```
>[info] msg = "hello vue" 显示结果为vue,hello
### 指令
**<span style="padding-top:15px;display:inline-block;">什么是指令</span>**
指令是带有`v-`前缀的特殊特性
**<span style="padding-top:15px;display:inline-block;">指令的预期值<span>**
指令的预期值是单个的JS表达式
**<span style="padding-top:15px;display:inline-block;">指令的职责<span>**
当表达式的发生变化时,将其产生的影响作用到dom上
#### 参数
>[info] 一个指令可以接受一个参数,以:的形式表示
#### 修饰符
修饰符是半角句号`.`指明的特殊后缀,用于表示当前指令应该以特殊方式进行绑定。