上节我们讲了什么是mvvm模型,以及我们vue的一些常用指令,今天给大家讲一下vue的基本使用,在将之前我们需要重点讲解我们的一个指令,v-model指令
v-model
v-model
可以在组件上使用以实现双向绑定,什么是双向绑定呢?意思就是当我们的数据发生变化的时候,我们的视图也会跟着变化;视图发生变化的时候,我们的数据也会发生变化
你可以用 v-model
指令在表单 <input>
、<textarea>
及 <select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model
本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
话多说直接上代码!!!!!
在这里我们定义了一个input最基本的输入框,唯一的不同是让他对 msg 这个数据进行了双向绑定,并且我们还展示了一下我们的 msg 这个属性的值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../static/vue.global.js"></script>
</head>
<body>
<div id="app">
测试:<input type="text" v-model="msg"><br>
{{msg}}
</div>
<script>
const app=Vue.createApp({
data() {
return {
msg:"aaa"
}
}
})
app.mount("#app")
</script>
</body>
</html>
效果:当我们的视图发生了变化,数据也会跟着变化.
这里我们还可以对 <select/>:下拉框 <textarea/>:文本框等做一些常用的案例,我会给大家一一解释我们的意思是什么
我们直接从性别开始:
在这里我们使用的是input的radio属性,声明它是一个单选框,value 是选择的值,这里我们使用的是0或者1,也可以写作男或者女,他们都对sex属性进行了双向绑定,我们标签后面的男或者女是为了在视图中显示,没有任何实际作用,当我们的男被选中,我们的双向绑定就会将被选中的这个值 value 赋值给 sex属性,也就是 sex就是0
爱好:
在这里我们先需要定义一个数组,用来存储我们的爱好,因为我们的爱好不会只有一个的,跟刚才性别的逻辑是一样的,当我们的多选框的某一个被选中之后,会将value的值,存放到我们双向绑定的happy属性中
班级:
我们的下拉框的值只有一个,所以只需要定义一个空字符,将其绑定到下拉框的select上,为什么我们不需要写value属性呢?在我们有开闭标签时,是不需要写任何的value,我们就可以获取到开闭标签中间值的,什么是开闭标签呢? <option></option>有开始有结束就是开闭标签 还有一种方式是<input/> 这个是需要写我们的value属性的。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../static/vue.global.js"></script>
</head>
<body>
<div id="app">
测试:<input type="text" v-model="msg"><br>
{{msg}} <br/>
性别:<input type="radio" name="sex" value="0" v-model="sex">男
<input type="radio" name="sex" value="1" v-model="sex">女
<br>
展示性别: {{sex}}
<br>
爱好:
<input type="checkbox" value="rapper" name="happy" v-model="happy">rapper
<input type="checkbox" value="打篮球" name="happy" v-model="happy">打篮球
<input type="checkbox" value="唱" name="happy" v-model="happy">唱
<input type="checkbox" value="跳" name="happy" v-model="happy">跳
<br>
爱好:{{happy}}
<br>
班级:<select v-model="aaa">
<!--为什么不用加value,因为我们的下拉框有默认值,就是没有value的是时候,我们的值就是标签中间的值-->
<option value="A365">A365</option>
<option value="A265">A265</option>
<option value="A165">A165</option>
</select>
{{aaa}}
<br>
文本框:
<textarea v-model="bbb"></textarea>
{{bbb}}
</div>
<script>
const app=Vue.createApp({
data() {
return {
msg:"aaa",
sex:"0",
happy:["rapper"],
aaa:"A365",
bbb:"aa"
}
}
})
app.mount("#app")
</script>
</body>
</html>
v-on
-
缩写:
@
-
预期:
Function | Inline Statement | Object
-
参数:
event
-
修饰符:
.stop
- 调用event.stopPropagation()
。.prevent
- 调用event.preventDefault()
。.capture
- 添加事件侦听器时使用 capture 模式。.self
- 只当事件是从侦听器绑定的元素本身触发时才触发回调。.{keyCode | keyAlias}
- 只当事件是从特定键触发时才触发回调。.native
- 监听组件根元素的原生事件。.once
- 只触发一次回调。.left
- (2.2.0) 只当点击鼠标左键时触发。.right
- (2.2.0) 只当点击鼠标右键时触发。.middle
- (2.2.0) 只当点击鼠标中键时触发。.passive
- (2.3.0) 以{ passive: true }
模式添加侦听器
用法:
绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。
用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event
property:v-on:click="handle('ok', $event)"
。
直接上代码!!!
我们直接用的是简写形式,@click,如果不喜欢的话我们可以使用v-on:click,我们只是声明的点击事件,我们还可以声明其他的事件, 语法 v-on:动作=“方法名字(参数)”
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../static/vue.global.js"></script>
</head>
<body>
<div id="app">
<button @click="test1()">普通按钮1</button>
<button @click.once="test2()">once按钮2</button>
<button @click.left="test3()">left按钮3</button>
<button @click.right="test4()">right按钮4</button>
</div>
<script>
const app=Vue.createApp({
methods: {
test1(){
alert("点击事件")
},
test2(){
alert("once,只会触发一次")
},
test3(){
alert("left 鼠标左键点击")
},
test4(){
alert("rigth 鼠标右键点击")
}
}
})
app.mount("#app")
</script>
</body>
</html>
简易轮播图
这里我们使用到了 v-bind,以及鼠标点击事件
思路: 通过点击事件,每点一次,照片路径的数组就切换,如果到最后一个照片,索引从0开始切换
这里我们先定义一个数组,里面存放的是我们照片的路径,再定义一个初始为0的索引,让我们的img这个标签的src属性绑定,可以相当于识别出我们的imgs是谁,index是谁,然后就是我们的点击事件,每次点击,索引加一,意思就是 本来是 src="imgs[0]",点击一次按钮就是 src="imges[1]"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../static/vue.global.js"></script>
<style>
img{
width: 100px;
heigth:100px
}
</style>
</head>
<body>
<div id="app">
<img :src="imgs[index]"/>
<button @click="changeImge()">切换</button>
</div>
<script>
const app=Vue.createApp({
data() {
return {
imgs:["../static/img/1.jpg","../static/img/2.jpg","../static/img/3.jpg","../static/img/4.jpg","../static/img/5.jpg"],
index:0
}
},
methods: {
changeImge() {
if(this.index>=this.imgs.length-1){
this.index=0
}else{
this.index++
}
}
},
})
app.mount("#app")
</script>
</body>
</html>
watch
watch:用于监听数据的变化,当数据发送变化的时候,我们可以进行一些逻辑操作.
这里我们的案例是: 当m 这个属性发生变化的时候,km也随着变化,我们输入2000m,km的输入框会变成2,输入3000m,km的输入框会变成3……
我们的watch是一个属性,属性里面是我们监听的哪个属性 属性名(新值,旧值){ 逻辑代码 }
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../static/vue.global.js"></script>
<style>
img{
width: 100px;
heigth:100px
}
</style>
</head>
<body>
<div id="app">
m:<input type="text" v-model="m"><br>
km:<input type="text" v-model="km"><br>
</div>
<script>
const app=Vue.createApp({
data() {
return {
m:"1000",
km:"1"
}
},
watch: {
m(newValue, oldValue) {
this.km=this.m/1000
}
},
})
app.mount("#app")
</script>
</body>
</html>
computed
计算属性是vue的强大功能之一,假如我们的逻辑代码中只需要拿到一个值,都可以放在我们的计算属性之中,计算属性的结果会被缓存,也就是说,当第一次调用的时候,才会被计算,计算之后被放在缓存之中,为我们节省了许多的资源,只要内部的数据发生变化,还是会重新进行计算
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../static/vue.global.js"></script>
</head>
<body>
<div id="app">
{{add()}}
{{add()}}
{{sex}}
{{sex}}
{{sex}}
</div>
<script>
const app=Vue.createApp({
data(){
return{
idcard:"410424200101274021"
}
},
methods: {
add(){
console.log("方法执行")
return this.idcard.substr(16,1)%2==0?"女":"男";
}
},
computed: {
sex() {
console.log("计算属性执行")
return this.idcard.substr(16,1)%2==0?"女":"男";
}
},
})
app.mount("#app")
</script>
</body>
</html>
我们是调用了两次方法,三次计算属性,我们可以发现计算属性只是被调用了一次,其他都是从缓存里拿的
component组件
组件(component)是vue.js最强大的功能之一。组件的作用就是封装可重用的代码,通常一个组件就是一个功能体,便于在多个地方都能够调用这个功能体。 每个组件都是Vue的实例对象。 我们实例化的Vue对象就是一个组件,而且是所有组件的根组件 ,在我的理解看来,组件就是一个标签,这个标签内有什么需要你自己定义,然后向拼积木一样,拼起来搭建一个自己的网站
每个组件都会有自己的方法以及数据,并且他们是不会互相干涉的,当两个重复的组件使用时,数据是不会共享的
全局组件
my-test就是我们组件的名字自定义的标签,官方建议我们使用 xx-xx的形式来写,或者是驼峰命名的方式
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../static/vue.global.js"></script>
</head>
<body>
<div id="app">
<my-test></my-test>
<my-test></my-test>
<my-test></my-test>
</div>
<script>
const app=Vue.createApp()
/* 定义组件 全局组件 */
app.component("my-test",{
data(){
return {
name:"test"
}
},
template:
`<div>
<div>我就是一个测试</div>
<button @click='test'>按钮</button>
</div>`
,
methods:{
test(){
alert("这就是一个测试的按钮呀 "+this.name)
}
}
})
app.mount("#app")
</script>
</body>
</html>
局部组件
在vue的实例对象中内部注册我们的组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../static/vue.global.js"></script>
</head>
<body>
<div id="app">
<xue-cheng></xue-cheng>
</div>
<script>
const app=Vue.createApp({
components:{
"xue-cheng":{
template:"<h1>111</h1>"
}
}
})
app.mount("#app")
</script>
</body>
</html>