![d12b0a1ff97a71166fa6a71ca1e40210.png](https://i-blog.csdnimg.cn/blog_migrate/7096f5073af8c7978c2588ff1732dbb5.jpeg)
什么是渲染?
把数据填充到HTML标签中。
- 原生js拼接字符串
- 使用模板引擎
以下讲解Vue模板语法
一、Vue模板语法
1.插值表达式 {{ }}
{{ msg }}
{{ 1 + 2 }}
{{ msg + '----' + 123 }}
{{ isOK? '确定' : '取消' }}
{{ text.split(',').reverse().join(',') }}
2. 指令 v-
指令本质是 自定义属性
https://cn.vuejs.org/v2/api/
v-cloak
解决 {{ }} 闪动出现了一下的问题
<style type="text/css">
[v-cloak]{
display: none;
}
</style>
<div v-cloak>{{msg}}</div>
2.1 数据绑定指令
v-text
填充纯文本,相当于不需要v-cloak的 {{ }}
v-html
填充HTML,会显示标签样式
存在安全问题,本网站内部数据可以使用
v-pre
填充原始信息
数据响应式:数据的变化导致页面内容的变化
数据绑定:将数据填充到标签中
v-once
只编译一次,显示出来就不会变了
<div v-once>{{info}}</div>
3. 双向数据绑定
v-model
修改输入框的msg,标签里的msg也改变。是个页面到数据,数据再到页面的过程。
<div>{{msg}}</div>
<div>
<input type="text" v-model='msg'>
</div>
- 页面到数据 事件监听
- 数据到页面 数据绑定
4. 事件绑定
v-on:click 简写:@click
<div id="app">
<div>{{num}}</div>
<div>
<button @click='handle'>点击</button>
</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
num: 0
}, // 注意,这里不要忘记加逗号
// methods对象中定义一些函数
methods: {
handle: function() {
// this是Vue的实例对象vm
this.num++; // 在函数中,想要使用data里面的数据,一定要加this
}
}
});
</script>
4.1 事件传参
- 直接绑定函数名,默认会传递事件对象作为事件函数的第一个参数
- 绑定函数调用,那么事件对象必须作为最后一个参数显示传递,并且事件对象的名称必须是$event
<button v-on:click='handle1'>点击1</button>
<button v-on:click='handle2(123, 456, $event)'>点击2</button>
Vue实例对象
var vm = new Vue({
el: '#app',
data: {
num: 0
},
methods: {
handle1: function(event) {
console.log(event.target.innerHTML) // 点击1
},
handle2: function(p, p1, event) {
console.log(p, p1) // 123 546
console.log(event.target.innerHTML) // 点击2
this.num++;
}
}
});
事件冒泡
<div id="app">
<div>{{num}}</div>
<div v-on:click='handle0'>
<button v-on:click='handle1'>点击1</button>
</div>
</div>
Vue实例对象
var vm = new Vue({
el: '#app',
data: {
num: 0
},
methods: {
handle0: function(){
this.num++;
},
handle1: function(event){
},
}
});
点击handle1,handle0运行
4.2 阻止冒泡
传统用stopPropagation()
handle1: function(event){
event.stopPropagation();
},
Vue用 v-on:click.stop='handle1'
4.3 阻止标签默认行为
event.preventDefault();
v-on:click.prevent='handle2'
4.4 按键修饰符
敲击回车键
v-on:keyup.enter='函数名'
敲击delete
v-on:keyup.delete='函数名'
4.5 自定义按键修饰符
定义 (数字是keyCode)
Vue.config.keyCodes.a = 65
使用
v-on:keyup.a='函数名'
5. 属性绑定
v-bind
原先
<a href="www.baidu.com">百度</a>
现在,url由数据提供可以改变。
<a v-bind:href="url">百度</a>
简写:
<a :href="url">百度1</a>
v-model就是v-bind:value="msg"允许value属性值可变,
再加上v-on:input='msg=$event.target.value'处理变化
<input type="text" v-bind:value="msg" v-on:input='msg=$event.target.value'>
<input type="text" v-model='msg'>
6. 样式绑定
6.1 class样式处理
(1)对象类型
<div id="app">
<div v-bind:class="{active: isActive, error: isError}">测试样式</div>
<button v-on:click='handle'>切换</button>
</div>
Vue对象
var vm = new Vue({
el: '#app',
data: {
isActive: true,
isError: true
},
methods: {
handle: function(){
// 控制值在true和false之间进行切换
this.isActive = !this.isActive;
this.isError = !this.isError;
}
}
});
结果:类名为 active error 的样式显示或隐藏
(2)数组类型
<div id="app">
<div v-bind:class='[activeClass, errorClass]'>测试样式</div>
<button v-on:click='handle'>切换</button>
</div>
Vue对象
var vm = new Vue({
el: '#app',
data: {
activeClass: 'active',
errorClass: 'error'
},
methods: {
handle: function(){
this.activeClass = '';
this.errorClass = '';
}
}
});
结果:类名为 active error 的样式显示或隐藏
(3)对象和数组结合使用
<div id="app">
<div v-bind:class='[activeClass, errorClass, {test: isTest}]'>测试样式</div>
<button v-on:click='handle'>切换</button>
</div>
Vue对象
var vm = new Vue({
el: '#app',
data: {
activeClass: 'active',
errorClass: 'error',
isTest: true,
},
methods: {
handle: function() {
this.activeClass = '';
this.errorClass = '';
this.isTest = !this.isTest;
}
}
});
(4)class绑定的值可以简化操作
<div v-bind:class='arrClasses'></div>
<div v-bind:class='objClasses'></div>
Vue对象
var vm = new Vue({
el: '#app',
data: {
arrClasses: ['active', 'error'],
objClasses: {
active: true,
error: true
},
isTest: true
},
methods: {
handle: function() {
this.arrClasses = [];
this.objClasses.error = false;
this.isTest = !this.isTest;
}
}
});
(5)默认的class会合并
<div class="base" v-bind:class='objClasses'> </div>
相当于
<div class="base active error"'></div>
6.2 style样式处理
(1)对象类型
<div id="app">
<div v-bind:style='{border: borderStyle, width: widthStyle, height: heightStyle}'></div>
<button v-on:click='handle'>切换</button>
</div>
Vue对象
var vm = new Vue({
el: '#app',
data: {
borderStyle: '1px solid blue',
widthStyle: '100px',
heightStyle: '200px'
},
methods: {
handle: function(){
this.heightStyle = '100px';
}
}
});
(2)对象简写
<div id="app">
<div v-bind:style='objStyles'></div>
<button v-on:click='handle'>切换</button>
</div>
Vue对象
var vm = new Vue({
el: '#app',
data: {
objStyles: {
border: '1px solid green',
width: '200px',
height: '100px'
},
},
methods: {
handle: function(){
this.objStyles.width = '100px';
}
}
});
(3)数组类型
<div id="app">
<div v-bind:style='[objStyles, overrideStyles]'></div>
<button v-on:click='handle'>切换</button>
</div>
- Vue对象
var vm = new Vue({
el: '#app',
data: {
objStyles: {
border: '1px solid green',
width: '200px',
height: '100px'
},
overrideStyles: {
border: '5px solid orange',
backgroundColor: 'blue'
}
},
methods: {
handle: function(){
this.objStyles.width = '100px';
}
}
});
// 展现的是border: '5px solid orange',width: '100px',height: '100px',backgroundColor: 'blue'
overrideStyles覆盖objStyles,冲突的后写的覆盖上,不冲突的合并上
7. 分支结构
7.1 v-if v-else-if v-else
<div id="app">
<div v-if='score>=90'>优秀</div>
<div v-else-if='score<90&&score>=80'>良好</div>
<div v-else-if='score<80&&score>60'>一般</div>
<div v-else>比较差</div>
</div>
Vue对象
var vm = new Vue({
el: '#app',
data: {
score: 10
},
});
score符合哪个就加载那个div
7.2 v-show
<div id="app">
<div v-show='flag'>测试v-show</div>
<button v-on:click='handle'>点击</button>
</div>
Vue对象
var vm = new Vue({
el: '#app',
data: {
flag: false
},
methods: {
handle: function(){
this.flag = !this.flag;
}
}
});
v-if决定是否加载,v-show决定是否显示(已经加载)。频繁显示隐藏用v-show。
8. 循环结构
v-for遍历数组
(1)
![5dc62975d206b21928524398e232547a.png](https://i-blog.csdnimg.cn/blog_migrate/ee237fbf692e00de2c4d22dc4b290818.png)
<div id="app">
<div>水果列表</div>
<ul>
<li v-for='item in fruits'>{{item}}</li>
</ul>
</div>
- Vue对象
var vm = new Vue({
el: '#app',
data: {
fruits: ['apple', 'orange', 'banana'],
}
});
(2)
![fcb622f0ea12362e1484afbef40b52eb.png](https://i-blog.csdnimg.cn/blog_migrate/01b3183b84576042e75046e34209c8c4.png)
<li v-for='(item, index) in fruits'>{{item + '---' + index}}</li>
- Vue对象
data:{
fruits:['apple','orange','banana']
}
(3)
![65226f060755589b5dc4300a69eda5d7.png](https://i-blog.csdnimg.cn/blog_migrate/e86a6b803c0c885618235bdd2a25d5be.png)
<li :key='item.id' v-for='item in myFruits'>
<span>{{item.ename}}</span>
<span>-----</span>
<span>{{item.cname}}</span>
</li>
- Vue对象
data: {
myFruits: [{
id: 1,
ename: 'apple',
cname: '苹果'
},{
id: 2,
ename: 'orange',
cname: '橘子'
},{
id: 3,
ename: 'banana',
cname: '香蕉'
}]
}
(4)没有id的话
<li :key='index' v-for='(item,index) in myFruits'>
<span>{{item.ename}}</span>
<span>-----</span>
<span>{{item.cname}}</span>
</li>
- Vue对象
data: {
myFruits: [{
ename: 'apple',
cname: '苹果'
},{
ename: 'orange',
cname: '橘子'
},{
ename: 'banana',
cname: '香蕉'
}]
}
v-for遍历对象
(1)原生JS遍历对象
var obj = {
uname: 'lisi',
age: 12,
gender: 'male'
}
for(var key in obj) {
console.log(key, obj[key])
}
(2)v-for遍历对象
![595db22bb64c30eb4fda50ab05171b4f.png](https://i-blog.csdnimg.cn/blog_migrate/77d0b86cecce7159e30c099d7968938f.png)
<div id="app">
<div v-for='(v,k,i) in obj'>{{v + '---' + k + '---' + i}}</div>
</div>
(3)结合v-if后
![f91d32ddf9e6f0c44ce0473d38654b80.png](https://i-blog.csdnimg.cn/blog_migrate/da31c58a007c1e135b35bc10632abb44.png)
<div id="app">
<div v-if='v==13' v-for='(v,k,i) in obj'>{{v + '---' + k + '---' + i}}</div>
</div>
- Vue对象
var vm = new Vue({
el: '#app',
data: {
obj: {
uname: 'zhangsan',
age: 13,
gender: 'female'
}
}
});
三、Vue常用特性
1.表单操作
1.1 Input 单行文本
<div>
<span>姓名:</span>
<span>
<input type="text" v-model='uname'>
</span>
</div>
- Vue
var vm = new Vue({
el: '#app',
data: {
uname: ''
},
methods: {
handle: function() {
console.log(this.desc)
}
}
});
1.2 radio 单选框
<div>
<span>性别:</span>
<span>
<input type="radio" id="male" value="1" v-model='gender'>
<label for="male">男</label>
<input type="radio" id="female" value="2" v-model='gender'>
<label for="female">女</label>
</span>
</div>
- Vue
data: {
gender: 2
},
1.3 checkbox 多选框
<div>
<span>爱好:</span>
<input type="checkbox" id="ball" value="1" v-model='hobby'>
<label for="ball">篮球</label>
<input type="checkbox" id="sing" value="2" v-model='hobby'>
<label for="sing">唱歌</label>
<input type="checkbox" id="code" value="3" v-model='hobby'>
<label for="code">写代码</label>
</div>
- Vue
data: {
hobby: ['2', '3'],
},
1.4 select 下拉单选
<div>
<span>职业:</span>
<select v-model='occupation' multiple>
<option value="0">请选择职业...</option>
<option value="1">教师</option>
<option value="2">软件工程师</option>
<option value="3">律师</option>
</select>
</div>
- Vue
data: {
occupation: 3
},
1.5 select 下拉多选
<div>
<span>职业:</span>
<select v-model='occupations' multiple>
<option value="0">请选择职业...</option>
<option value="1">教师</option>
<option value="2">软件工程师</option>
<option value="3">律师</option>
</select>
</div>
- Vue
data: {
occupations: ['2', '3'],
},
1.6 textarea 多行文本
<div>
<span>个人简介:</span>
<textarea v-model='desc'></textarea>
</div>
- Vue
data: {
desc: 'nihao'
},
1.7 提交按钮
阻止默认提交,提交由handle处理
<form action="http://tijiaowangzhi.cn">
…………
<div>
<input type="submit" value="提交" @click.prevent='handle'>
</div>
</form>
1.8 表单域修饰符
- number:转化为数值
- trim:去掉开始和结尾的空格
- lazy : 将input事件切换为change事件,输入触发变为焦点离开触发
<input type="text" v-model.number='age'>
<input type="text" v-model.trim='info'>
<input type="text" v-model.lazy='msg'>
2.自定义指令
2.1 自动获取焦点
使用
<input type="text" v-focus>
定义
Vue.directive('focus', {
inserted: function(el){
// el 表示指令所绑定的元素(element)
el.focus();
}
});
2.2 改变元素背景色
使用
<input type="text" v-color='msg'>
定义(全局指令)
Vue.directive('color', {
bind: function(el, binding){
el.style.backgroundColor = binding.value.color;
// binding.value 是msg
}
});
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'blue'
}
},
});
定义(局部指令)
var vm = new Vue({
el: '#app',
data: {
msg: {
color: 'red'
}
},
// 这里定义局部指令
directives: {
color: {
bind: function(el, binding){
el.style.backgroundColor = binding.value.color;
}
},
focus: {
inserted: function(el) {
el.focus();
}
}
}
});
3.计算属性
原先
<div>{{msg.split('').reverse().join('')}}</div>
现在
<div>{{reverseString}}</div>
定义
var vm = new Vue({
el: '#app',
data: {
msg: 'Nihao'
},
// 这里定义计算属性
computed: {
reverseString: function(){
return this.msg.split('').reverse().join('');
// 拆字节,翻转,拼接字节
}
}
});
computed与methods区别
computed,指加载一次,除非msg改变,否则一直用缓存值。
methods,每次使用,都会加载运行一次。
两个调用
<div>{{reverseString}}</div>
<div>{{reverseMessage()}}</div>
两个定义
methods: {
reverseMessage: function(){
return this.msg.split('').reverse().join('');
}
},
computed: {
reverseString: function(){
return this.msg.split('').reverse().join('');
}
}
4.侦听器
侦听数据,当数据变化时,触发侦听器绑定的函数。
应用在,异步或者开销大的业务逻辑上,比如ajax,定时任务,比较耗时的工作。
示例:验证用户名是否可用
<div id="app">
<div>
<span>用户名:</span>
<span>
<input type="text" v-model.lazy='uname'>
</span>
<span>{{tip}}</span>
</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#app',
data: {
uname: '',
tip: ''
},
methods: {
checkName: function(uname) {
// setTimeout的this是Window,这里给that缓存上vm
var that = this;
setTimeout(function(){
if(uname == 'admin') {
that.tip = '用户名已经存在,请更换一个';
}else{
that.tip = '用户名可以使用';
}
}, 2000);
}
},
watch: {
uname: function(val){
// 调用后台接口验证用户名的合法性
this.checkName(val);
// 修改提示信息
this.tip = '正在验证...';
}
}
});
</script>
结果:输入admin,失去焦点,显示正在验证,2s后显示 用户名可以使用。
因为有.lazy,输入name失去焦点后才出发侦听里的uname,里面的checkName触发,2s后checkName里的验证启动,得出结果。
5.过滤器
作用是处理数据,比如首字母大写,日期格式改一下。
5.1 初步使用
使用过滤器
<div>{{msg | upper}}</div> 首字母大写
<div>{{msg | upper | lower}}</div> 首字母小写,两次过滤,先变大写又变小写
<div :abc='msg | upper'>测试数据</div>
![29d80fd4dfe2424ff166eacdc7e3d860.png](https://i-blog.csdnimg.cn/blog_migrate/f8a0a88b236fb414bef543990c2fa7e9.png)
定义过滤器
// 全局过滤器
Vue.filter('lower', function(val) {
return val.charAt(0).toLowerCase() + val.slice(1);
});
var vm = new Vue({
el: '#app',
data: {
msg: ''
},
// 组件过滤器
filters: {
upper: function(val) {
return val.charAt(0).toUpperCase() + val.slice(1);
// 第一个字节 大写 拼接 第二个字节后的字节
}
}
});
5.2 带参数的过滤器
<div id="app">
<div>{{date | format('abc' 'nihao')}}</div>
</div>
定义过滤器
Vue.filter('format', function(value, arg, arg1) {
console.log (arg,arg1);
return value;
})
var vm = new Vue({
el: '#app',
data: {
date: new Date()
}
});
- value标签中收date,date是newDate(),即未处理的最新日期
- arg是abc
- arg1是nihao
示例:输入格式为参数 得到该格式的时间
![6861a6d86600fe17a0c6c5d30c0edbfb.png](https://i-blog.csdnimg.cn/blog_migrate/78c294ca80a9e197556902d583c55c31.png)
![5c8285ab3232496e2035e63f6bfbc511.png](https://i-blog.csdnimg.cn/blog_migrate/7b0b9e934e42ecca72a4cb02beefc965.jpeg)
收起来的是定义好的函数,要做的就是,对接好参数。
6.生命周期
Vue实例都有一个周期,涉及到以下钩子函数
- 挂载(初始化相关属性)
- beforeCreate
- created
- beforeMount
- mounted
2. 更新(元素或组件的变更操作)
- beforeUpdate
- updated
3. 销毁(销毁相关属性)
- beforeDestroy
- destroyed