Vue 指令(二)
v-bind单项数据绑定
属性和数据进行绑定
通过操作数据就可以改变V中的dom样式,相当于操作了dom
- 举例:表单的value属性和一个数据绑定
- 就是不绑定一个数据在某一个属性身上
v-bind两种绑定方式
1.绑定类名
2.绑定样式
类名的绑定 两种写法
- 数组
<p :class="['size','bg']">里面的css可以改变head里面的样式直接改变</p>
<p :class="[size,bg]"> 可以通过改变data里面的属性值进行改变</p>
- 对象
<p class="size bg">简单的css用法</p>
<p :class="{size:false,bg:true}">里面的css样式还是head标签里面style的样式</p>
<p :class="{[size]:true,[bg]:true}">此时里面的css样式是vue的data数据里面定义的样式 但是 data里面定义的size:'size',用的还是head里面的样式
</p>
样式的绑定
- 数组的写法
<h4>样式绑定,数组写法</h4>
<p :style="[{width:'60px',height:'60px'},{background:'pink'}]">数组绑定</p>
<p :style=[styleobj,stylecolor]>在vue数据里面定义属性 引用</p>
- 对象的写法
<h4>样式绑定:对象写法</h4>
<p style="width:80px;height:80px;background:yellow">行内写法</p>
<p :style="{width:'100px',height:'100px',background:'green'}">对象的写法</p>
<p :style="{width:w,height:h,background:bacg}">vue 定义属性</p>
scrpt代码示例:
<script>
new Vue({
el: '#app',
data: {
msg: '今天周四',
w: '100px',
h: '100px',
bacg: 'blue',
size: 'size',
bg: 'bg',
flag: true,
color: 'color',
imgUrl: 'https://www.baidu.com/img/bd_logo1.png',
cool: '就很好',
styleobj: {
width: '90px',
height: '90px'
},
stylecolor: {
background: 'tomato'
},
}
})
</script>
项目中使用
<p :class="{[size]: true,[bg]: true}"></p>
<p :class="[ size,bg ]"></p>
- 引深 加开关的使用
<h4>引深</h4>
<p :class="{[size]:flag,[bg]:flag}"></p>
<p :class="[size,flag?bg:color]"></p>
<p :class="[ size, flag && bg || color]"></p>
<!--
flag?bg:color
三目运算:
当flag为true的时候返回bg
当flag为false的时候返回color
<p :class="[ size, flag && bg || color]"></p>
当&&的第一个值为true的时候,返回第二个值
or 第一个为true的时候返回第一个·
-->
特殊点:添加class名在原class身上
<h4>添加class名在原class身上</h4>
<p class="text" :class=[size,bg]></p>
<img :src="imgUrl" alt="">
引用路径要用 :src
v-model 双向绑定
- 单向绑定:【数据改变,视图改变】
- 双向: 【数据改变,视图改变,反之 视图改变,数据改变】
v-model 默认绑定表单元素的value值 - form 表单
- input textarea … 表单元素
<h4>双向绑定</h4>
<input type="text" v-model="cool">
思考题:如何用单向数据绑定实现双向数据邦定的效果
我们需要用到input事件
focus
blur
change
input
事件包含那几个部分?
事件源
事件类型
事件处理函数
<body>
<div id="app">
<input type="text" :value = "msg" v-on:input = "change">
<!-- 简写 -->
<input type="text" :value = "msg" @input = "change">
</div>
</body>
<script>
new Vue({
el: '#app', // 挂载
data: {
msg: '老彭很帅'
},
methods: {
//事件处理程序
change: function ( e ) {
this.msg = e.target.value
}
}
})
</script>
v-on 事件
1.基础事件绑定
2.事件传参
3.事件对象
为什么要用使用?【案例四:事件冒泡】
- 事件修饰符
- 按键修饰符
on的事件方法都是写在methods里面的
事件修饰符
案例一
简单的事件:点击button弹出老彭最帅
<body>
<div id="app">
<button @click = "fn"> 点击 </button>
</div>
</body>
<script src="../../lib/vue.js"></script>
<script>
/*
vue中写事件,记住先写逻辑在绑定
*/
new Vue({
el: '#app',
methods: {
fn () {
alert('老彭最帅')
}
}
})
</script>
**案例二 **
点击按钮,弹出input的value
经验总结:看到表单,下那个药得到它的value值,就用v-model
<input type="text" v-model = "val">
<button @click = "fn( val )"> 点击 </button>
<script>
new Vue({
el: '#app',
data: {
val: ''
},
methods: {
fn ( val ) {
alert( val )
}
}
})
</script>
案例三
当fn函数接收两个参数的时候,其中一一参数是事件对象 e
此时我们调用方法的时候,传入一个实际参数的写法是 : $event
<input type="text" v-model = "val">
<button @click = "fn( $event,val )"> 点击 </button>
<script>
new Vue({
el: '#app',
data: {
val: ''
},
methods: {
fn ( e,val ) {
console.log( val )
console.log( e )
}
}
})
</script>
案例四
使用事件冒泡解读为什么要使用事件修饰符
当我们使用普通事件的时候
在冒泡事件中我们需要阻止事件冒泡 如下所示
<div class="large" @click = "largeHandler">
<div class="middle" @click = "middleHandler">
<div class="small" @click = "smallHandler"></div>
</div>
</div>
<script>
/*
业务: 给每一个盒子都加一个事件
*/
new Vue({
el: '#app',
methods: { //方法: 里面存放的是: 事件处理程序
largeHandler ( e ) {
e.stopPropagation()
alert( 'large' )
},
middleHandler ( e ) {
alert( 'middle' )
e.stopPropagation()
},
smallHandler ( e ) {
alert( 'small' )
e.stopPropagation()
}
}
})
</script>
就像代码所展示的 我们需要在每一个事件的方法里面阻止事件冒泡,代码量较大
因此就有了我们的事件修饰符
:
<div class="large" @click.stop = "largeHandler">
<div class="middle" @click.stop = "middleHandler">
<div class="small" @click.stop = "smallHandler"></div>
</div>
</div>
<script>
new Vue({
el: '#app',
methods: { //方法: 里面存放的是: 事件处理程序
largeHandler ( e ) {
alert( 'large' )
},
middleHandler ( e ) {
alert( 'middle' )
},
smallHandler ( e ) {
alert( 'small' )
}
}
})
</script>
该写法违背了mvvm的架构思想
按键修饰符
案例一
<div id="app">
<input type="text" @keyup.13 = "fn( val )" v-model = 'val'>
<hr>
<input type="text" @keyup.enter = "fn( val )" v-model = 'val'>
<hr>
<input type="text" @keyup.p = "fn( val )" v-model = 'val'>
</div>
<script>
/*
业务: 按回车弹出input框的value
键盘事件:
keyup
keydown
keypress
*/
new Vue({
el: '#app',
data: {
val: ''
},
methods: {
fn ( val ) {
console.log( val )
}
}
})
</script>
模板语法 mustache(双大括号)
- 支持数据类型
- 数据类型分类:
- 基础数据类型:number string Boolean
- 复杂数据类型:object
- 特殊数据类型:null undefined
- 所有的数据类型都是支持的,但是console.log alert这些输出语法是不支持的
示例:
<div id="app">
<p> number: {{ num }} </p>
<p> string: {{ str }} </p>
<p> boolean: {{ bool && 1 || 2 }}</p>
<p> null: {{ nul && 3 || 4 }}</p>
<p> undefined: {{ und && 5 || 6 }} </p>
<p> array: {{ arr[1] }}</p>
<p> object: {{ obj.name }}</p>
<!-- <p> function: {{ ( function() { console.log('fn')} )() }}</p> -->
</div>
<script>
new Vue({
el: '#app',
data: {
num: 10,
str: 'Gabriel Yan',
bool: true,
nul: null,
und: undefined,
arr: [1,2,3],
obj: {
name: '老彭'
}
}
})
</script>
结果展示
computed 计算属性
1.计算属性是一个选项 ,选项值是一个对象,对象中存放的是方法
- 方法必须有返回值
2.计算属性的使用:- 直接将方法当做全局变量一样使用
<div id="app">
<p> {{ newMsg }} </p>
把newMsg当做全局变量使用
</div>
为什么要有设个属性呢?
案例:将msg这个字符串反向输出
思路:将字符串转成数组 reverse进行反向 在将数组转成字符串
<div id="app">
{{msg.split('').reverse().join('') }}
</div>
<script>
new Vue({
el: '#app',
data: {
msg: 'I Love eat 葡萄 '
},
})
</script>
结果展示:
其实像上面的改动我们只需要引用方法就好了
<div id="app">
<p> {{ newMsg }} </p>
</div>
<script>
new Vue({
el: '#app',
data: {
msg: 'I Love eat 葡萄 '
},
computed: {
//计算属性中存放的都是方法
newMsg () {
return this.msg.split('').reverse().join('')
}
}
})
</script>
升级版
输入姓和名自动拼接全名
<div id="app">
<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>
</div>
方法一
<script>
new Vue({
el: '#app',
data: {
firstName: '',
lastName: ''
},
computed: {
fullName () {
return this.firstName + this.lastName
}
}
})
</script>
方法二
<script>
new Vue({
el: '#app',
data: {
firstName: '',
lastName: ''
},
computed: {
fullName: {
get () { //getter
return this.firstName + this.lastName
},
set ( val ) { //val就是当前绑定元素的value值
// val 彭少华
this.firstName = val.slice( 0,1 )
this.lastName = val.slice( 1 )
}
}
}
})
</script>
通过方法二 我们知道了,计算属性还可以使用
- getterr
- setter
computed: {
fullName: {
get () { //getter
return this.firstName + this.lastName
},
set ( val ) { //val就是当前绑定元素的value值
// val 彭少华
this.firstName = val.slice( 0,1 )
this.lastName = val.slice( 1 )
}
}
}
计算属性的总结:
1。使用计算属性满足两个条件即可:
- 必须有逻辑处理,还有返回值
- 我们所使用的结果,要当做全局变量一样使用
2.计算属性一旦确定就可不可以更改了
watch 侦听属性
1.watch是一个选项,选项值是一个对象
- 对象中可以存放的类型有哪些
- { [key: string]: string | Function | Object | Array }
- 常用的是方法和对象
<body>
<div id="app">
<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>
</div>
</body>
<script src="../../lib/vue.js"></script>
<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 ( val ) {
// this.firstName = val.slice( 0,1 )
// this.lastName = val.slice( 1 )
// }
fullName: {
deep: true, //深度监听
handler () { // 处理程序
this.firstName = val.slice( 0,1 )
this.lastName = val.slice( 1 )
}
}
}
})
</script>
watch 侦听对象的总结:
由一个数据改变,引起的亲的数据请求