Vue指令、methods、computed、watch、
vue的指令有:v-html、v-text、v-show、v-if、v-else、v-else-if、v-for、v-on、v-bind、v-model、v-slot、v-once、v-pre、v-cloak共14种。
其中:
1、v-html和v-text是用来数据展示的,两者区别:
v-html可以识别标签并解析,v-text不会识别标签,直接展示。
<p v-html="msg"></p>//会展示粗体的大小二字
<p v-text="msg"></p>//<h3>大小</h3>会把标签原样输出
data:{
msg:'<h3>大小</h3>'
}
2、条件渲染:v-if、v-else-if、v-else
<p v-if="type==='A'">A</p>//一开始显示的就是A
<p v-else-if="type==='B'">B</p>//将type值改为B时,这里显示B
<p v-else>C</p>//type为其它值时,显示C
data:{
type:'A'
}
3、v-if 和 v-show
<p v-if="flag">{{msg}}</p> //v-if后面的布尔值可以控制msg的显示与否,这里是dom结构的销毁和创建
<p v-show="flag">{{msg}}</p> //v-show后面的flag也可以控制msg的显示情况,这里是用的display:none.
//v-show不管flag的值如何,都会渲染出dom结构来,所以v-show用在需要频繁切换隐藏和显示的地方
//v-if用在切换次数少的地方,v-if的渲染开销相对v-show比较大
data:{
msg:'我喜欢睡觉',
flag:true
}
4、列表渲染 v-for
<ul v-for="(item,index) in shuju"> -->
{{item.info}}
<li v-for="(coo,index) in item.content">{{coo.w}}</li>//这里的coo和item是随便取得,两个可以
//取的一样,因为两者根本就不同,不会有影响(当然,尽量不一样,好区分)
</ul>
data:{
shuju:[
{
id:1,
info:'a',
content:[
{
w:'宽1',
h:'高1'
}
]
},
{
id:2,
info:'b',
content:[
{
w:'宽2',
h:'高2'
}
]
},
{
id:3,
info:'c',
content:[
{
w:'宽3',
h:'高3'
}
]
}
]
}
5、v-bind 单向数据绑定
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> 指令 </title>
<style>
.size{
width: 100px;
height: 100px;
}
.bg{
background: red;
}
.color{
background: blue;
}
</style>
</head>
<body>
<div id="app">
<h3> v-bind 单向数据绑定 </h3>
<input type="text" v-bind:value = "msg">
<!-- 简写,用冒号替代v-bind -->
<input type="text" :value = "msg">
<h4> 样式绑定 - 对象形式写法 </h4>
<p style = "width: 100px;height: 100px;background: green;"></p>
<!--上面是内联样式-->
<p :style = "{width: '100px',height: '100px',background: 'blue'}"></p>
<p :style = "{width: w,height: h,background: backg}"></p>
<h4> 样式绑定 - 数组形式写法 </h4>
<p :style = "[{width: '100px',height: '100px'},{background: 'pink'}]"></p>
<p :style = "[ styleObj,styleColor ]"></p>
<hr>
<h3> v-bind 绑定类名 </h3>
<h4> 类名绑定 - 对象形式写法 </h4>
<p class = "size bg"> </p>
<p :class = "{size: true,bg: true}"></p>
<!--上面的size和bg是style中的类名-->
<p :class = "{[a]: true,[b]: true}"></p>
<!--上面的[a]是data数据里面的键,[b]也是-->
<hr>
<h4> 类名绑定 - 数组形式写法 </h4>
<p :class = "['size','bg']"></p>
<!--上面的size和bg是style中的类名-->
<p :class = "[a,b]"></p>
<!--上面的size和bg是data中的数据-->
<!-- 总结: 项目中建议使用,因为一般都是要在data中写上数据的,那么就是从data中而不是从style中,变量形式 -->
<p :class = "{[a]: true,[b]: true}"></p>
<p :class = "[ a,b ]"></p>
<!-- 引申: 灵活使用 -->
<h4> 引申 </h4>
<p :class = "{ [a]: flag,[b]: flag}" ></p>
<p :class = "[ size, flag?bg:color ]"></p><!--flag控制颜色-->
<p :class = "[ size, flag && bg || color ]"></p>
<h4> 更神奇的 </h4>
<p class = "text" :class = [size,bg]></p>
<!--这时就有三个类名,text这个类名不会被覆盖-->
<h4> v-bind 可以绑定任意一个dom身上的属性 </h4>
<img :src="imgUrl" alt="">
<hr>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
/*
*/
new Vue({
el: '#app', // 挂载
data: {
imgUrl: 'https://www.baidu.com/img/bd_logo1.png',
msg: 'hello 各位今天周四了',
a: 'size',
b: 'bg',
flag: true,
color: 'color',
w: '100px',
h: '100px',
backg: 'blue',
styleObj: {
width: '100px',
height: '100px'
},
styleColor: {
background: 'yellow'
}
}
})
</script>
</html>
- 绑定类名 绑定样式
- 为什么要绑定?
- 答: 通过操作数据就可以改变V中dom的样式,相当于操作了dom
- 类名的绑定 【 两种写法 】
- 数组的写法 【 推荐 】
- 对象的写法
- 样式的绑定
- 数组的写法 【 推荐 】
- 对象的写法
6、v-model 【 双向数据绑定 】
-
单向 【 数据改变, 视图改变 】
-
双向 【数据改变, 视图改变,反之,视图改变,数据改变 】
-
v-model默认绑定表单元素的value值
- form 表单标签
-
input textarea … 表单元素
-
思考: 如何使用单向数据绑定实现双向数据绑定效果,如下:
<input type="text" :value = "msg" @input = "change"> :value="msg"单向数据绑定使得数据变,视图就变了 @input="change"使得视图变了,数据也跟着变了 new Vue({ el: '#app', // 挂载 data: { msg: '我很帅' }, methods: { //事件处理程序 change: function ( e ) { this.msg = e.target.value } } })
7、v-on 事件(如v-on:click:“fn”----->简写为@click )
- 基础事件绑定
- 事件传参
- 事件对象
- 为什么要使用?【 案例: 事件冒泡 】(为了减少冗余代码和简便操作,但这样将一定的逻辑放入了V视图中,总之利大于弊)
- 事件修饰符(使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用
v-on:click.prevent.self
会阻止所有的点击,而v-on:click.self.prevent
只会阻止对元素自身的点击。)- stop:比如@click.stop:“fn”,用来阻止事件冒泡
- prevent:用来阻止默认事件
- self:用来只触发自己,有阻止事件冒泡的作用
- capture:事件捕获(即元素自身触发的事件先在此处理,然后才交由内部元素进行处理)
- 按键修饰符
- enter
- esc
- tab
- delete
- space
- up
- down
- left
- right
- 事件修饰符(使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用
- 思考: MVVM架构思想,是将逻辑放在VM中来做,V是用来展示视图的
- 模板语法 mustache 【 双大括号 】
- 支持度
- 支持数据类型
- 所有的类型都是支持的,但是console.log alert这些输出语法是不支持的
method 方法
-
用来存储事件处理程序
-
事件处理程序中,有两个参数,其中一个为事件对象e时,调用时,对应e的位置写$event,否则e会丢失。
/* 业务: 如果我们的fn函数接收2个参数,其中一个参数是事件对象 问题: 事件对象e丢失了 解决: 在调用方法时,对应传入一个实际参数: $event 这里也体现了事件传参 */ <div id="app"> <input type="text" v-model = "val"> <button @click = "fn( $event,val )"> 点击 </button> </div> new Vue({ el: '#app', data: { val: '' }, methods: { fn ( e,val ) { console.log( e ) console.log( val ) } } })
computed 计算属性
-
为什么要有这个选项?
-
案例: 【 字符串反向 】
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> {{ msg.split('').reverse().join('') }} <hr> <p> {{ newMsg }} </p> </div> </body> <script src="../../vue.js"></script> <script> /* 业务:将msg这个字符串 反向 输出 思路: 转数组 reverse 再转字符串 思考: V应该是用于数据展示,但是我们这么处理,发现V做了一部分逻辑判断,又违背了MVVM 解决: 使用计算属性 */ new Vue({ el: '#app', data: { msg: 'I Like eat 葡萄 ' }, computed: { //计算属性中存放的都是方法 newMsg () { return this.msg.split('').reverse().join('') } } }) </script> </html>
-
-
计算属性是一个 选项, 选项值是一个对象,对象中存放的是方法
- 方法必须要有返回值
-
计算属性的使用
- 直接将方法名当做全局变量一样直接使用
<p> {{ newMsg }} </p>
-
总结: 什么时候使用计算属性?
- 满足两个条件即可
- 必须有逻辑处理,还有返回值
- 我们使用的结果,要当做全局变量一样使用
- 满足两个条件即可
-
计算属性一旦确定就不可更改了
-
案例联系计算属性
- 用户名书写
- 通过上面的案例我们知道了,计算属性还可以使用getter和setter
computed: { fullName: { get () { //getter,写出firstname和lastname自动拼接出fullname return this.firstName + this.lastName }, set ( val ) { //val就是当前绑定元素的value值,写出fullname,自动填好firstname和lastname this.firstName = val.slice( 0,1 ) this.lastName = val.slice( 1 ) } } }
watch 侦听属性
-
以案例来学习watch - > 用户名写入
-
watch是一个选项, 选项值是一个对象
- 对象中可以存放的类型有哪些
- { [key: string]: string | Function | Object | Array }
- 常用的是方法和对象
-
总结:
由一个数据改变,引起的新的数据请求时用watch<div> 姓: <input type="text" v-model = "firstName"> </div> <hr> <div> 名: <input type="text" v-model = "lastName"> </div> <hr> <div> 全名: <input type="text" v-model = "fullName"> </div> <script> new Vue({ el: '#app', data: { firstName: '', lastName: '', fullName: '' }, watch: { // 侦听 -> data中的数据 // watch中可以存放方法 firstName ( val ) { // console.log('firstname改变了') this.fullName = val + this.lastName }, lastName ( val ) { this.fullName = this.firstName + val }, fullName: { deep: true, //深度监听 handler () { // 处理程序 this.firstName = val.slice( 0,1 ) this.lastName = val.slice( 1 ) } } } }) </script>