vue简介
vue是一套用于构建用户界面的前端框架
构建用户界面:用vue往HTML页面中填充数据 框架:是一套现成的解决方案
vue的特性
1.数据驱动视图 2.双向数据绑定
1.数据驱动视图
vue监听数据变化,自动渲染页面。 数据变化会驱动(vue)视图的自动更新。
只管维护好数据,页面结构会被自动渲染出来。
2.双向数据绑定
在网页中form负责采集数据,ajax负责提交数据。
开发者在不操作dom时,会自动把用户填写的内容同步到数据源中。 当js数据发生变化时,表单中的值也会发生变化。 页面表单中的值发生变化,vue会自动获取,对应的数据也会自动进行更新。
MVVM
MVVM是vue实现数据驱动视图和双向数据绑定的核心原理。 MVVM是指Model,view,viewModel,将每个html页面都拆分成这三个部分。
Model表示当前页面渲染时所依赖的数据源。 View表示当前页面所渲染的DOM 结构。 ViewModel表示vue 的实例,它是MVVM 的核心。
MVVM工作原理: ViewModel作为vue的实例,将页面数据源Model和页面结构view连接在一起。 当数据源发生变化时,会被ViewModel 监听到,VM 会根据最新的数据源自动更新页面的结构。 当表单元素的值发生变化时,也会被VM 监听到,VM 会把变化过后最新的值自动同步到Model 数据源中。
vue基本使用
导入vue.js 的script 脚本文件 在页面中声明一个将要被vue 所控制的DOM 区域 创建vm 实例对象(vue 实例对象)
<!-- vue控制下面div,将数据填空到div内部 -->
<div id="app">{{username}}</div>
<!-- 1.导入vue的库文件,在window全局就有了vue构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.创建vue实例对象 -->
<script>
//创建vue实例对象
const vm=new Vue({
//el属性为固定写法,表示当前vue实例要控制页面上的哪个区域,接收的值是一个选择器
el:'#app',
//data对象就是要渲染到页面上的数据
data:{
username:'zhangsan'
}
});
</script>
</body>
vue指令与过滤器
指令是vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。
vue 中的指令按照不同的用途可以分为如下6 大类: ①内容渲染指令 ②属性绑定指令 ③事件绑定指令 ④双向绑定指令 ⑤条件渲染指令 ⑥列表渲染指令
1.内容渲染指令
内容渲染指令用来辅助开发者渲染DOM 元素的文本内容。
v-text指令
缺点:会覆盖元素内部原有的内容。
{{}}插值表达式
用于解决内容覆盖问题,只起到占位符的作用,不会覆盖其他内容。 插值表达式只能用于元素的内容节点,不能用于属性节点。
v-html指令
<!-- vue控制下面div,将数据填空到div内部 -->
<div id="app">
<p v-text='username'></p>
<p v-text='gender'>性别</p>
<hr>
<p>姓名:{{ username }}</p>
<p>性别:{{ gender }}</p>
<hr>
<p v-text='info'></p>
<div v-html='info'></div>
</div>
<!-- 1.导入vue的库文件,在window全局就有了vue构造函数 -->
<script src="./lib/vue-2.6.12.js"></script>
<!-- 2.创建vue实例对象 -->
<script>
const vm=new Vue({
el:'#app',
data:{
username:'zhangsan',
gender:'女',
info:'<h3 style="color:red">hello world</h4>'
}
});
</script>
</body>
2.属性绑定指令
插值表达式只能用于元素的内容节点,不能用于属性节点。
如果需要为元素的属性动态绑定属性值,则需要用到v-bind属性绑定指令,简写为: 。
在vue 提供的模板渲染语法中,除了支持绑定简单的数据值之外,还支持Javascript 表达式的运算。
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
在使用v-bind属性绑定期间,如果绑定内容需要进行动态拼接,则字符串的外面一个包裹单引号,如:
<div :title="'box'+index">这是一个div</div>
box为字符串,与变量index进行拼接。
3.事件绑定指令
vue提供v-on事件绑定指令,为DOM元素绑定事件监听。 v-on绑定的事件为原生事件去除on v-on简写为@ v-on绑定事件处理函数,在methods节点中进行声明,并且可以使用()进行传参。
可以通过this访问并修改data中的数据。
<!-- vue控制下面div,将数据填空到div内部 -->
<div id="app">
<p>count的值为{{ count }}</p>
<button v-on:click="add(2)">+1</button>
<button @click="sub">-1</button>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
//创建vue实例对象
const vm=new Vue({
el:'#app',
data:{
count:0,
},
//methods定义事件处理函数
methods:{
add(n){
console.log(vm)
console.log(this === vm) //this指向vue实例对象vm
this.count+=n;
},
sub(){
this.count-=1;
}
}
});
</script>
</body>
当v-on绑定的事件处理函数没有参数时,存在默认有个参数e,代表事件对象。
若给事件处理函数传递参数后,默认参数e会被参数所覆盖。
vue提供内置变量$event,就是原生DOM的事件对象e。
当v-on绑定的事件处理函数有传参且需要使用事件对象e时,可以使用$event作为参数(顺序无关),防止e被其他参数所覆盖。
<!-- vue控制下面div,将数据填空到div内部 -->
<div id="app">
<button v-on:click="add(2,$event)">+1</button>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm=new Vue({
el:'#app',
data:{
count:0,
},
methods:{
add(n,e){
console.log(vm)
console.log(e);
this.count+=n;
if(this.count % 2===0){
e.target.style.backgroundColor='red'
}else{
e.target.style.backgroundColor=''
}
},
}
});
</script>
</body>
事件修饰符 vue 提供了事件修饰符的概念,来辅助程序员更方便的对事件的触发进行控制。
| 事件修饰符 | 作用 |
|---|---|
| .prevent | 阻止默认行为(阻止链接跳转) |
| .stop | 阻止事件冒泡 |
| .capture | 以捕获模式触发当前的事件处理函数 |
| .once | 绑定的事件只触发一次 |
| .self | 只有在event.target是当前元素自身时触发事件处理函数 |
按键修饰符
在监听键盘事件时,需要判断详细的按键,可以为键盘相关事件添加键盘修饰符。
<!--当按键为enter键时,调用submit-->
<input @keyup.enter='submit'>
<!--当按键为esc键时,调用clearinput-->
<input @keyup.esc='clearInput'>
methods:{
clearinput(e){
console.log('触发esc');
e.target.value=''
},
}
4.双向绑定指令
vue 提供了v-model 双向数据绑定指令,用来辅助开发者在不操作DOM 的前提下,快速获取表单的数据。
v-model为双向绑定,表单输入的内容可以改变数据源的数据,数据源数据修改也可以改变表单上的数据。 v-bind是单向数据绑定,数据源可以改变页面表单数据,但是页面表单数据发生改变不会影响数据源数据。
v-model指令修饰符 为了方便对用户输入的内容进行处理,提供修饰符。
| 修饰符 | 作用 |
|---|---|
| .number | 自动将用户的输入值转为数值类型 |
| .trim | 自动过滤用户输入的首尾空白字符 |
| .lazy | 不在改变时实时更新,在改变结束之后更新 |
<input type="text" v-model.number='n1'>+<input type="text" v-model.number='n2'>=<span>{{ n1+ n2 }}</span>
<hr>
<input type="text" v-model.trim='username'>
<button @click='showName'>获取用户名</button>
<hr>
<input type="text" v-model.lazy='username'>
</div>
data:{
n1:1,
n2:2,
username:'zhangsan',
}
methods:{
showName(){
console.log('用户名为:'+ this.username)
}
}
5.条件渲染指令
辅助开发者按需控制DOM的显示与隐藏。 v-if 和 v-show
区别:
1.实现原理不同:
v-if 指令会动态地创建或移除DOM 元素,从而控制元素在页面上的显示与隐藏;
v-show指令会动态为元素添加或移除 style="display:none;"样式,从而控制元素的显示和隐藏;
2.性能消耗不同:
v-if有更高的切换开销,而v-show有更高的初始渲染开销。
若在运行时条件很少改变,则使用v-if较好。
若需要非常频繁的切换元素的显示与隐藏,使用v-show更友好;
在实际开发中,绝大多数情况,不用考虑性能问题,直接使用 v-if 就好了
v-else-if
v-else 指令必须配合v-if 指令一起使用,否则它将不会被识别
<div v-if="type === 'A'">优秀</div>
<div v-else-if="type === 'B'">良好</div>
<div v-else-if="type === 'C'">一般</div>
<div v-else>差</div>
data:{
type:'A'
},
6.列表渲染指令
vue 提供了v-for列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。
v-for 指令需要使用item in items 形式的特殊语法。
items 是待循环的数组
item 是被循环的每一项
v-for 指令还支持一个可选的第二个参数,即当前项的索引。语法格式为(item,index)in items。
v-for 指令中的item 项和index 索引都是形参,可以根据需要进行重命名。
官方建议,只要使用到v-for指令,就一定要绑定一个key属性,而且尽量把id作为key的值。
key 的注意事项 1.key 的值只能是字符串或数字类型 2.key 的值必须具有唯一性(即:key 的值不能重复) 3.建议把数据项id 属性的值作为key 的值(因为id 属性的值具有唯一性) 4.使用index 的值当作key 的值没有任何意义(因为index 的值不具有唯一性) 5.建议使用v-for 指令时一定要指定key 的值(既提升性能、又防止列表状态紊乱)
<table>
<thead>
<th>索引</th>
<th>Id</th>
<th>姓名</th>
</thead>
<tbody>
<tr v-for="(item,index) in list" :key="item.id" :title="item.name">
//列表的属性在元素身上也可以使用
<td>{{ index }}</td>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</tbody>
</table>
data:{
list:[
{ id:1,name:'zhangsan' },
{ id:2,name:'lisi' },
{ id:3,name:'zhaoliu' }
]
}
过滤器
过滤器(Filters)是vue 为开发者提供的功能,常用于文本的格式化。
过滤器可以用在两个地方:插值表达式和v-bind 属性绑定。
过滤器应该被添加在JavaScript 表达式的尾部,由“管道符”(|)进行调用。
在创建vue 实例期间,可以在filters 节点中定义过滤器。
<body>
<div id="app">
<p>message的值为 {{ message | capi }}</p>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script>
const vm=new Vue({
el:'#app',
data:{
message:'hello vue.js'
},
//过滤器函数必须被定义到filters节点之下
//过滤器本质上就是函数
filters:{
//过滤器函数形参中的val永远都是管道符前面的那个值
//将首字符转换为大写的过滤器
capi(val){
//字符串charAt方法,接收索引值。
const first=val.charAt(0).toUpperCase();
//字符串slice方法,可以截取字符串
const other=val.slice(1)
//过滤器中一定要有个返回值
return first+other
}
}
})
</script>
</body>
注:
过滤器要定义到filters节点下,本质是一个函数;
在过滤器函数中一定要有return值;
在过滤器的形参中,就可以获取的管道符前面待处理的那个值。
私有过滤器和全局过滤器
在filters 节点下定义的过滤器,称为“私有过滤器”,因为它只能在当前vm 实例所控制的el 区域内使用。
如果希望在多个vue 实例之间共享过滤器,则可以按照如下的格式定义全局过滤器:
//使用vue.filter定义全局过滤器
Vue.filter('capi',function(str){
return str.charAt(0).toUpperCase()+str.slice(1)
})
如果全局过滤器和私有过滤器名称重复,则按照就近原则,调用私有过滤器。
连续调用多个过滤器
过滤器可以串联地进行调用
<!-- 把message的值交给capi过滤器进行处理 -->
<!-- 把capi过滤器处理的结果交给filterA和filterB处理 -->
<!-- 将filterB处理之后的结果作为最终的值渲染到页面上 -->
<p>message的值为 {{ message | capi | filterA | filterB }}</p>
过滤器传参
过滤器的本质是JavaScript函数,可以接收参数。
<!-- 给过滤器filter传入参数arg1和arg2 -->
<p>message的值为 {{ message | filter(arg1,arg2) }}</p>
//过滤器处理函数中的形参,第一个永远是管道符前待处理的值,第二个参数开始时传给过滤器的参数
Vue.filter('filter',(message,arg1,arg2)=>{
//过滤器代码
})