1、Vue两大特性
数据驱动视图
数据的变化会驱动视图自动更新
好处:程序员只把数据维护好,那么页面结构会被Vue自动渲染出来。
双向数据绑定
在网页中,form表单负责采集数据,Ajax负责提交数。
js数据的变化,会被自动渲染到页面上
页面上表单采集的数据发生变化的时候,会被Vue自动获取,并更新到js数据中。
注意: 数据驱动视图和双向绑定的底层原量是MVVM(Model数据源、View视图、ViewModel。其中,ViewModel 是Vue的实例)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!--1.导入Vue的库文件-->
<script src="lib/vue-2.6.12.js"></script>
</head>
<body>
<div id="app">
</div>
<!--2.创建Vue的实例对象-->
<script>
//创建Vue的实例
const vm = new Vue({
// el属性是固定写法。
// 表示当前的VM实例要控制页面上的哪上区域,收接的是一个选择器。
el: "#app" ,
data:{
username:"zhangsan",
}
})
</script>
</body>
</html>
2、vue指令
**指令(Directives)**是Vue为开发者提供的 模板语法,用于 辅助开发者渲染页面的基本结构。
Vue中的指令按照不同的用途,可分为6大类:
内容渲染指令
属性绑定指令
事件绑定指令
双向绑定指令
条件渲染指令
列表渲染指令
指令是Vue开发中最基础、最常吸入、最简单的知识点。
2.1、内容渲染指令
内容渲染指令 用来辅助开发者 渲染 DOM 元素的文本内容 。常用的内容渲染指令有如下3 个:
v-text
{{ }}
v-html
(1)v-text
<p v-text="username"></p>
<!-- 注意:默认文本 “性别” 会被gender的值覆盖掉 -->
<p v-text="gender">性别</p>
缺点:
v-text 指令会覆 盖标签内部原本的内容,缺点很明显,实际使用少。
(2){{ }} :插值表达式
vue 提供的 {{ }} 语法,专门用来解决 v-text 会覆盖默认文本内容的问题。这种 {{ }} 语法的专业名称是 插值表达式 (英文名为:Mustache)。
<p>姓名:{{username}}</p>
<p>性别:{{gender}}</p>
插值表达式 ,只是内容的占位符,实际开发中使用最多。
只有用在内容节点,无法用在属性节点。
(3)v-html
2.2、属性绑定指令
在vue中,可以使用v-bind:指令,为元素的属性动态绑定值。
简写是: 。
v-bind: 与 插值表达式的区别?
插值表达式 只能用在 内容节点,无法用在属性节点。
v-bind: 用于为元素的属性动态绑定值。
示例:
<img v-bind:src="vueImg" />
<hr>
<!-- VUE规定v-bind指定可简写为 : -->
VUE规定v-bind指定可简写<br>
<img :src="vueImg" />
<script>
//创建Vue的实例
const vm = new Vue({
// el属性是固定写法。
// 表示当前的VM实例要控制页面上的哪上区域,收接的是一个选择器。
el: "#app" ,
data:{
vueImg:"./images/vue.jpg"
}
})
</script>
使用 Javascript 表达式
<div id="app">
num=25+10
表达式计算: {{num +10}}
<hr>
num2=25+20
<input type="text" v-bind:placeholder="num2 + 20" >
num2=25+ '-20'
<input type="text" v-bind:placeholder="num2 + '-20'" >
</div>
<script>
//创建Vue的实例
const vm = new Vue({
el: "#app" ,
data:{
num: 25,
num2: 25,
}
})
</script>
2.3、事件绑定指令
vue 提供了 v-on 事件绑定指令,用来辅助程序员为DOM 元素绑定事件监听。
v-on 简写 @ 。如 v-on:click 可简写成 @click 。
常见的原生DOM 事件有 onclick、oninput、onkeyup ,替换为vue 的事件, 分别为:v-on:click 、v-on:input 、v-on:keyup 。
以 v-on:click 为例,v-on:click 简写成 @click。 语法格式如下:
<p> count 的值是{{ count }}</p>
<!-- 语法格式为 v-on:事件=“事件处理函数的名称” -->
<button v-on:click="add"> +1 </button>
示例:
<div id="app">
<p> count 的值是{{ count }}</p>
<button v-on:click="add"> +1 </button>
<button v-on:click="sub"> -1 </button>
</div>
<script>
//创建Vue的实例
const vm = new Vue({
// el属性是固定写法。
// 表示当前的VM实例要控制页面上的哪上区域,收接的是一个选择器。
el: "#app" ,
data:{
count: 0,
},
// methods的作用,就是定义事件的处理函数
methods:{
add{
vm.count+=1
console.log(vm==this)
console.log(vm)
},
sub(){
this.count-=1
},
}
})
</script>
运行上面的代码,得到 vm 等于 this ,一般使用this 。
add 函数接收参数
<div id="app">
<p> count 的值是{{ count }}</p>
<button @:click="add(2)"> +1 </button>
<button v-on:click="sub"> -1 </button>
</div>
<script>
//创建Vue的实例
const vm = new Vue({
// el属性是固定写法。
// 表示当前的VM实例要控制页面上的哪上区域,收接的是一个选择器。
el: "#app" ,
data:{
count: 0,
},
// methods的作用,就是定义事件的处理函数
methods:{
add(n){
this.count+=n
console.log(vm)
},
sub(){
this.count-=1
},
}
})
</script>
v-on:click 简写成 @click
<div id="app">
<p> count 的值是{{ count }}</p>
<button @click="add(2)"> +1 </button>
<button @click="sub"> -1 </button>
</div>
<script>
//创建Vue的实例
const vm = new Vue({
// el属性是固定写法。
// 表示当前的VM实例要控制页面上的哪上区域,收接的是一个选择器。
el: "#app" ,
data:{
count: 0,
},
// methods的作用,就是定义事件的处理函数
methods:{
add(n){
this.count+=n
console.log(vm)
},
sub(){
this.count-=1
},
}
})
</script>
(1)事件内置的变量: $event
<div id="app">
<p> count 的值是{{ count }}</p>
<!-- 当count是偶数时,加背景色,否则没有 -->
<button @click="add(2,$event)"> +1 </button>
</div>
<script>
const vm = new Vue({
el: "#app" ,
data:{
count: 0,
},
methods:{
add(n,event){
this.count+=1
// console.log(e)
if(this.count%2==0){
event.target.style='background-color:red;'
}else{
event.target.style=''
}
},
sub(){
this.count-=1
},
}
})
</script>
(2)事件修饰符
件修饰符 说明
.prevent 阻止默认行为 (例如:阻止a 连接的跳转、阻止表单的提交等)
.stop 阻止事件冒泡
.capture 以捕获模式触发当前的事件处理函数
.once 绑定的事件只触发1次
.self 只有在 event.target 是当前元素自身时触发事件处理函数
@click.prevent
<a href="http://www.baidu.com" @click.prevent="show" >跳转到百度首页</a>
1
@click.stop
<div style="height:150px;background-color:orange;" @click="divHander">
<button @click.stop="btnHander">按钮事件</button>
</div>
(3)按键修饰符
在 监听键盘事件 时,我们经常需要 判断详细的按键。此时,可以为 键盘相关的事件 添加 按键修饰符。
.esc 、 .enter
2.4、v-model 双向数据绑定指令
vue 提供了 v-model 双向数据绑定指令,用来辅助开发者在不操作DOM 的前提下,快速获取表单的数据。
只有表单数据 才能使用 v-model 指令:
input (text、radio、checkbox、…)
textarea
select
<div id="app">
<p>用户名是 {{username}}</p>
<input type="text" v-model="username">
</div>
<script>
const vm = new Vue({
el: "#app" ,
data:{
username:'zhangsan',
},
})
</script>
示例2:(select 双向绑定)
<div id="app">
<p>选中的省份是 {{province}}</p>
<p>
<input type="text" v-model="province">
</p>
<select v-model="province">
<option>请选择</option>
<option value="1">北京</option>
<option value="2">河北</option>
<option value="3">黑龙江</option>
</select>
</div>
<script>
const vm = new Vue({
el: "#app" ,
data:{
province:'',
},
})
</script>
v-model 与 v-bind: 的区别
说明:
v-model是双向绑定 ,v-bind: 是单向绑定 。
<div id="app">
<p>用户名是 {{username}}</p>
<input type="text" v-model="username">
<p>用户名(v-bind)是 </p>
<input type="text" :value="username">
</div>
<script>
const vm = new Vue({
el: "#app" ,
data:{
username:'zhangsan',
},
})
</script>
v-model指令的修饰符
修饰符 作用 示例
.number 自动将用户的输入值转为 数值类型 <input v-model.number="age" />
.trim 自动过滤用户输入的 首尾 空白字符 <input v-model.trim="msg" />
.lazy 在“change”时而非“input”时更新 <input v-model.lazy="msg" />
示例:
不使用 .number 时是字符串拼接,加上 .number 是数值相加。
<div id="app">
<input type="text" v-model.number="n1">
+
<input type="text" v-model.number="n2">
<p>
{{ n1 + n2 }}
</p>
</div>
<script>
const vm = new Vue({
el: "#app" ,
data:{
n1:0,
n2:0,
},
})
</script>
2.5、条件渲染指令
条件渲染指令用来辅助开发者按需控制DOM 的显示与隐藏。条件渲染指令有如下两个,分别是:
v-if
v-show
v-if 和v-show 的区别
实现原理不同:
v-if 指令会动态地创建或移除DOM 元素,从而控制元素在页面上的显示与隐藏;
v-show 指令会动态为元素添加或移除 style="display: none;" 样式,从而控制元素的显示与隐藏。
性能消耗不同:
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此:
如果需要非常频繁地切换,则使用 v-show 较好 。
如果在运行时条件很少改变,则使用 v-if 较好 。
v-if v-else-if v-else 组合
<p>
<div v-if="type ==='A'">优秀</div>
<div v-else-if="type ==='B'">良好</div>
<div v-else-if="type ==='C'">一般</div>
<div v-else>差</div>
</p>
2.6、循环渲染指令
vue 提供了v-for 循环渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。v-for 指令需要使
用 item in items 形式的特殊语法,其中:
items 是待循环的数组。
item 是被循环的每一项。
只要有到 v-for 指令,一定要绑定一个 :key 属性,:key 属性的值必须是唯一的。
<div id="app">
<p>
id: <input type="text" name="id" id="id" v-model="id">
name: <input type="text" name="idname" id="name" v-model="name">
<button @click="add">添加对象</button>
</p>
<ul>
<li v-for="(item,index) in list" :key="item.id" >
索引是{{index}},姓名是{{item.name}}
</li>
</ul>
</div>
<script>
const vm = new Vue({
el: "#app" ,
data:{
id:"",
name:"",
list:[
{id:1,name:"zhangsan"},
{id:2,name:"lisi"},
{id:3,name:"wangwu"},
]
},
methods:{
add(){
var item={"id":this.id,"name":this.name};
console.log(item)
this.list.push(item)
this.id="";
this.name="";
}
}
})
</script>
key 的注意事项
① key 的值只能是 字符串 或 数字 类型
② key 的值必须具有 唯一性(即:key 的值不能重复)
③ 建议把 数据项id 属性的值 作为key 的值(因为id 属性的值具有 唯一性)
④ 使用 index 的值当作key 的值 没有任何意义(因为index 的值不具有唯一性)
⑤ 建议使用 v-for 指令时 一定要指定key 的值(既提升性能、又防止列表状态紊乱)
<ul>
<li v-for="(item,index) in list" :key="item.id" :title="'title-'+item.id" :index="'index-'+index" >
索引是{{index}},姓名是{{item.name}}
</li>
</ul>
3、Vue 过滤器 Filters
Filters : 只存在于 Vue2 ,Vue3 已没有过滤器。
3.1、Vue2的过滤器的定义
过滤器 (Filters)是vue 为开发者提供的功能,常用于文本的格式化。
过滤器可以用在两个地方:插值表达式 {{ }} 和 v-bind 属性绑定。
过滤器 应该被添加在 JavaScript 表达式的 尾部,由 管道符 进行调用,示例代码如下:
<!-- capitalize 就是一个名称为capitalize的过滤器 ,对message的值进行处理 -->
<p>{{ message | capitalize }}</p>
<!-- formatId 就是一个名称为 formatId的过滤器 ,对rawId 的值进行处理 -->
<div v-bind:id="rawId | formatId" ></div>
3.2、Vue2的定义过滤器
<div id="app">
<div>{{message | capi}}</div>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script type="text/javascript">
const vm =new Vue({
"el":"#app",
filters:{
// 注意:过虑器函数形参中的val,永远都是“管道符”前面的那个值
capi(val){
// 强调,过滤器中,一定要有一个返回值
const first=val.charAt(0).toUpperCase()
const other = val.slice(1)
return first+""+other;
}
}
});
</script>
3.3、Vue2 全局过滤器
全局过滤器:在filters 节点下定义的过滤器,称为 私有过滤器, 因为它 只能在当前vm 实例所控制的 el 区域内使用。 如上一个示例。
全局过滤器:如果希望在多个vue 实例之间共享过滤器,则定义全局过滤器。格式如下
<div id="app">
<div>{{message | capi2}}</div>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script type="text/javascript">
// Vue.fiter() 接收两个参数:
// 第1个参数,全局过滤器的 “名称”
// 第2个参数,全避过滤器的 “处理函数”
Vue.filter('capi2',(str)=>{
const first=str.charAt(0).toUpperCase()
const other = str.slice(1)
return first+""+other;
})
const vm =new Vue({
"el":"#app",
data:{
message:"hello vue.js",
},
filters:{
// 注意:过虑器函数形参中的val,永远都是“管道符”前面的那个值
capi(val){
// 强调,过滤器中,一定要有一个返回值
const first=val.charAt(0).toUpperCase()
const other = val.slice(1)
return first+""+other;
}
}
})
</script>
3.4、带参数的过滤器
<div id="app">
<div>{{message | filterA( arg1 ,arg2) }}</div>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script type="text/javascript">
// fiter() 函数的形参 列表中
// 第1个参数,永远都是“管道符”前面待处理的值
// 第第2个参数开始,才是调用过滤器时传递过来的arg1,argument参数
Vue.filter('capi2',(msg , arg1 , arg2)=>{
...省略...
});
</script>
4、watch 监听器
4.1、watch 监听器的定义
watch监听器公允开发者监听数据的变化,从而针对数据的变化做出特定的操作。
语法格式:
<div id="app">
<input type="text" v-model="username" >
</div>
<script type="text/javascript">
const vm =new Vue({
"el":"#app",
data:{
username:'',
},
watch:{
// 监听 username 值的变化
// newVal是变化后的新值,oldVal是变化之前的旧值
username(newVal,oldVal){
console.log(newVal +" , "+oldVal)
}
}
})
</script>
注意事项:
input中必须使用 v-model 。
页面加载完毕后,如果没有对 username 进行任何操作时,是不监听的。只有当对username 进行操作后,才开始监听。
4.2、监听器的格式
方法格式的监听器
格式:监听 username 时, 格式是 username(newVal,oldVal) 。
缺点1:无法在刚进入页面时,自动触发监听。
缺点2:如果监听的是一个对象,对象中属性值的变化不会触发监听器。
对象格式的监听器
格式::监听 username 时, 格式是 username:{ ... } 。
好处1:可以通过 immediate 选项,让 监听器 自动触发 监听(就是立即监听)。
好处2:可以通过 deep 选项,让 监听器 深度监听。
方法格式:
username(newVal,oldVal){
//...
}
对象格式:
username:{
handler(newVal,oldVal){
//...
},
deep: true,
immediate: true,
}
下面是改成 对象格式 的相关示例。
4.3、立即监听(immediate 选项)
默认情况下,组件在初次加载完毕后,不会调 用 watch 监听器。
如果想让 watch 监听器立即被调用,则用 immediate 选项。
<div id="app">
<input type="text" v-model="username" >
</div>
<script type="text/javascript">
const vm =new Vue({
"el":"#app",
data:{
username:'',
},
watch:{
// 此处是对象格式的监听
username:{
// handler 是固定写法,表示当username的值变化时,自动调用 handler函数
handler: function(newVal ,oldVal) {
console.log(newVal +" , "+oldVal)
// ... 其它操作省略
},
// 表示页面渲染好之后,就立即触发当前的watch监听器
immediate: true,
}
}
})
</script>
说明:
当页面加载完成后,立即监听 username 的值。
handler: function(newVal ,oldVal) 的简写是 handler (newVal ,oldVal) 。
4.4、监听对象的属性值的变化(deep选项)
如果watch 监听的是一个 对象,如果 对象中的属性值 发生了变化,则无法被监听到, 必须使用 deep 才能监听到。
<script type="text/javascript">
const vm =new Vue({
"el":"#app",
data:{
info:{username:'admin'}
},
watch:{
// 对象格式的监听,监听对象的所有属性值的变化
info:{
// handler 是固定写法,
handler(newVal){
console.log(newVal)
},
deep: true
},
}
})
</script>
监听对象时的必须配置:
使用对象监听器
配置 deep参数
4.5、监听对象单个属性值的变化
<script type="text/javascript">
const vm =new Vue({
"el":"#app",
data:{
info:{username:'admin'}
},
watch:{
// 对象格式的监听,监听对象的单个属性值
'info.username':{
// handler 是固定写法,
handler(newVal){
console.log(newVal);
},
},
}
})
</script>
监听对象时的必须配置:
使用对象监听器
无须配置 deep参数
5、计算属性(computed)
5.1、计算属性的定义
计算属性指的是 通过一系列运算 之后,最终得到一个 属性值。
这个动态计算出来的属性值 可以被模板结构或methods 方法使用。
没有使用 计算属性 前的代码:
<div id="app">
Red: <input type="text" v-model="r" > <br>
Green: <input type="text" v-model="g" > <br>
Blue: <input type="text" v-model="b" > <br>
<div class="box" :style="{ backgroundColor:`rgb(${r},${g},${b})` }" >
{{ `rgb( ${r},${g},${b} )` }}
</div>
<button @click="show">按钮</button>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script type="text/javascript">
const vm =new Vue({
"el":"#app",
data:{
r:0,
g:0,
b:0,
},
methods:{
// 点击按钮,在终端显示最新的颜色
show(){
console.log(`rgb(${this.r},${this.g},${this.b})`)
}
}
})
</script>
使用 计算属性 的代码
<div id="app">
Red: <input type="text" v-model="r" > <br>
Green: <input type="text" v-model="g" > <br>
Blue: <input type="text" v-model="b" > <br>
<div class="box" :style="{ backgroundColor: rgb }" >
{{ rgb }}
</div>
<button @click="show">按钮</button>
</div>
<script src="./lib/vue-2.6.12.js"></script>
<script type="text/javascript">
const vm =new Vue({
"el":"#app",
data:{
r:0,
g:0,
b:0,
},
// 所有的计算属性,都要定义到computed 节点下。
//计算属性在定义的时候,要定义成 "方法格式"
computed:{
// rgb作为一个计算属性,被定义成方法格式
// 最终,在这个方法中,要返回一个生成好的 rgb(x,x,x) 的字符串
rgb(){
return `rgb( ${this.r} ,${this.g} ,${this.b} )`
}
},
methods:{
// 点击按钮,在终端显示最新的颜色
show(){
console.log( this.rgb )
}
}
})
</script>
特点:
所有的计算属性,都要定义到 computed 节点下。
计算属性在定义的时候,要定义成 “方法格式” 。
好处:
实现了代码的复用。
只要计算属性中依赖的数据源变化了,则计算属性的值会自动重新求值。
全部评论