插值表达式
Vue 中的插值表达式类似模板引擎中的写法,通过 {{ value }}
的形式在打括号内填充数据。如下代码所示:
<body>
<!-- 插值表达式,类似模板引擎中的待填充数据 -->
<div class="container">{{msg}}</div>
<script src="../lib/vue.js"></script>
<script>
let v = new Vue({
// el 用来以 CSS 选择器的方式选择一个元素
el: '.container',
// 在选中的元素中传递值
data: {
msg: '你好 vue'
}
})
</script>
</body>
最终解析在 html
页面中的内容如下:
你好 vue
插值表达式还可以用来进行简单的计算:
<body>
<!-- 插值表达式,类似模板引擎中的待填充数据 -->
<div class="container">
<div>{{msg}}</div>
<div>{{ 1+1}}</div>
<div>{{ '哈哈哈' + msg + (1+1) }}</div>
<div>{{ 1 > 2? true : false }}</div>
</div>
<script src="../lib/vue.js"></script>
<script>
let v = new Vue({
// el 用来以 CSS 选择器的方式选择一个元素
el: '.container',
// 在选中的元素中传递值
data: {
msg: '你好 vue'
}
})
</script>
</body>
在页面中的结果如下:
你好 vue
2
哈哈哈你好 vue2
false
Vue 框架的编译分析
在 script
标签中使用了 vue
的语法,HTML
并不认识 vue
的语法,在页面中却正常解析了 vue
语法,这是因为我们所引入的 vue.js 文件将 vue
语法编译成了原生 DOM
语法。
数据绑定
数据绑定分为单向数据绑定和双向数据绑定,
- 单向数据绑定是指,Vue 对象中的属性更改,html 页面中的内容也随之更改;但是页面内容修改时,Vue 对象的属性不变
- 双向数据绑定是指,Vue 对象中的属性更改,html 页面中的内容也随之更改;html 页面中的内容被改变时,Vue 对象中的属性也会更改。
单向数据绑定
v-cloak
指令
使用插值表达式在刷新页面时,花括号中的内容会短暂的显示,对于一些配置不太好的计算机来说会更加明显;而 v-cloak
指令可以解决这种问题。
使用 v-cloak
指令在页面中的元素中设置 v-cloak
属性,然后将该元素隐藏。
一定要使用 v-cloak
属性作为选择器将元素隐藏,否则 vue 加载完成之后元素无法显示。
示例代码如下:
HTML
<body>
<div v-cloak>
<div>{{msg}}</div>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: '[v-cloak]',
data: {
msg: 'hello'
}
})
</script>
</body>
CSS
[v-cloak] {
display: none;
}
v-text
单向数据绑定
v-cloak
指令还需要设置 CSS 样式,未免太过于麻烦了。开发中经常使用 v-text
指令。v-text
指令可以直接填充纯文本,并且 v-text
指令可以直接等于一个值。
如下代码所示:
<body>
<div v-text="msg"></div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: '[v-text]',
data: {
msg: 'hello'
}
})
</script>
</body>
v-html
输入 html
v-html
和 v-text
相似,但是 v-html
指令可以插入 html 片段。如下代码所示:
<body>
<div class="container">
<div v-text="msg1"></div>
<div v-html="msg2"></div>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: '.container',
data: {
msg1: '<h1>hello vue</h1>',
msg2: '<h1>hello vue</h1>'
}
})
</script>
</body>
上面代码中有两个 div 第一个 div 使用了 v-text
指令;第二个 div 使用了 v-html
指令。结果如下:
需要注意的是,v-html
指令虽然强大,但是存在安全问题。可能被植入一些恶意代码,比如内置的 <script>
标签。
v-pre
原文输出
该指令可以让指定元素跳过编译时期,从而显示原本的带填充内容,实际用法类似模板引擎中的原文输出。
编译时期是指:
vue
框架将vue
代码编译为原生js
代码的过程。
v-pre
不需要等于一个值
如下代码所示:
<body>
<div class="container">
<div v-text="msg1"></div>
<div v-html="msg2"></div>
<div v-pre> {{msg1}} </div>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: '.container',
data: {
msg1: '<h1>hello vue</h1>',
msg2: '<h1>hello vue</h1>'
}
})
</script>
</body>
上述代码中 container
中的第三个 div
设置 了 v-pre
属性,显示结果如下:
数据响应式
- HTML5 的响应式中当页面的大小发生变化时,页面中的元素也随之发生变化。
- 数据的响应式是指数据的变化导致页面内容的变化。
如下代码所示:
<body>
<div class="container">
<div v-text="msg"></div>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: '.container',
data: {
msg: 'hello vue',
}
})
setTimeout(() => {
vm.msg = '你好 VUE'
}, 1000);
</script>
</body>
一开始页面中显示 hello vue
一秒之后延迟执行完毕,修改了 vm
对象中 msg
属性的值,页面中的内容随之改变。
如下图所示:
也就是说使用上述指令对数据进行绑定时绑定的都是响应式的。
非响应式绑定
如果想要使数据变为非响应,可以使用 v-once
指令,v-once
表示绑定数据只编译一次。
非相应式绑定适用于显示信息之后不需要修改的场景,会比响应式的数据更加节省性能。
如下代码所示:
<body>
<div class="container">
<div>响应式:{{msg}}</div>
<div v-once>非响应式:{{info}}</div>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: '.container',
data: {
msg: 'hello vue',
info: 'hello vue',
}
})
setTimeout(() => {
vm.msg = '你好 VUE'
vm.info = '你好 VUE'
}, 1000);
</script>
</body>
结果:
双向数据绑定
双向数据绑定需要使用 v-model
指令,所谓双向数据绑定是指页面中的内容被修改时 vue 对象中属性的值也随之被修改。如下代码所示:
<body>
<div class="container">
<div> {{name}}</div>
<input type="text" v-model='name'>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: '.container',
data: {
name: 'hello vue',
}
})
</script>
</body>
结果:
MVVM 设计思想
说到双向数据绑定,不得不谈及一个新的架构模式,MVVM 架构。
MVVM:Model - View - ViewModel
参考 廖雪峰的官方网站
MVVM 实际上是 MVC 的改进版,MVC:Model - View - Controller。
- Model 模型:指的是后端传递的数据。
- View 视图:指的是所看到的页面。【
- ViewModel 视图模型:MVVM模式的核心,它是连接 view 和 model 的桥梁。
它有两个方向:- 一是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。
- 二是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。
如下图所示:
单向数据绑定和双向数据绑定的区别
要理解单向数据绑定和双向数据绑定,首先需要知道无论双向绑定还是单向绑定只要 Vue 对象 data 属性中的值修改时,这两种绑定方式都会修改。
这种绑定方式的区别就是单向绑定数据的元素中元素的内容通过其他手段进行修改时 Vue 对象 data 属性中的值不会与其一同修改。就像下面代码:
<body>
<div class="container">
<div v-text='msg'></div>
<input type="text" v-model='msg'>
</div>
<button id="change">更改值</button>
<button id="show">显示值</button>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: '.container', data: {
msg: '123'
}
})
document.getElementById('change').addEventListener('click', event => {
document.getElementsByTagName('div')[1].textContent = 'Hello'
})
document.getElementById('show').addEventListener('click', event => {
console.log(`Vue 对象的 msg 属性的值:${vm.msg}`);
})
</script>
</body>
上面代码中 container
内的 div 元素使用了单向数据绑定,当更改值时结果如下:
当点击 “更改值” 按钮时,单向绑定的元素内容通过 DOM 的方式进行了修改。但是 Vue 对象中的值没有修改。
input 元素使用了双向数据绑定,更改值时结果如下:
插值表达式和 v-text
指令的区别
在测试单向和双向绑定数据时发现一个问题,使用插值表达式绑定数据时,使用 DOM 的方式更改数据之后,再次更改 Vue 下 data 的相应属性值插值表达式中的内容无法修改。如下代码所示:
<body>
<div class="container">
<span>使用 v-text 绑定:</span>
<div class="show" v-text='msg'></div>
<span v-pre>使用 {{msg}} 绑定:</span>
<div class="show">{{msg}}</div>
<button id="change_div">更改DIV值</button>
<button id="change_vue" @click="change">更改VUE值</button>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: '.container', data: {msg: '123'},
methods: { change: function () { vm.msg = 'Vue' } }
})
document.getElementById('change_div').addEventListener('click', event => {
document.getElementsByTagName('div')[1].textContent = 'DOM'
document.getElementsByTagName('div')[2].textContent = 'DOM'
})
</script>
</body>
结果: