目录
一.属性和方法
1.属性基础
2.方法基础
二.计算属性和侦听器
1.计算属性
2.计算属性和函数的选择
3.计算属性的赋值
4.属性侦听
三.函数限流
四.表单数据的双向绑定
1.文本输入框
2.多行文本输入域
3.复选框和单选框
4.选择列表
5.两个常用修饰符
五.样式绑定
1.为HTML标签绑定class属性
2.绑定内联样式
六.实战
一.属性和方法
1.属性基础
在编写Vue组件时,组件的数据都放在data选项中,Vue组件的data选项是一个函数,该函数返回一些我们定义属性的数据
例如:
<script>
const App={
data(){
return{
count:0,
}
}
}
</script>
2.方法基础
组件的方法定义在methods选项中,在我们实现组件的方法时,可以放心地使用this关键字,Vue组件会自动将其绑定到当前组件实例本身
例如定义一个方法:
methods:{
addation(){
this.count++
}
}
二.计算属性和侦听器
大多数情况下,Vue组件中定义的属性数据组件都可以直接渲染到HTML元素,但是有写情况属性中的数据并不适合直接渲染,需要经过处理后再渲染,在Vue中,就可以使用计算机属性或侦听器来实现这种逻辑
1.计算属性
之前的data函数中定义的属性是存储属性,存储属性的值是我们直接定义好的,这个属性只起到存储数据的作用。在Vue中还有一种计算属性,它不是用来存储数据,而是通过一些计算逻辑来实时地维护当前属性的值,计算属性在compute选项中定义。
例如:定义一个组件的type属性,当组件的count属性大于4时,type属性值为牛逼,否则为不牛逼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="Application">
<div>{{count}}</div>
<div>{{type}}</div>
<button @click="addation">累加</button>
</div>
<script>
const App={
data(){
return{
count:0,
}
},
methods:{
addation(){
this.count++
}
},
computed:{
type(){
return this.count>4?"牛逼":"不牛逼"
}
},
}
let instance=Vue.createApp(App).mount("#Application")
console.log(instance.count)
console.log(instance.$data.count)
</script>
</body>
</html>
计算属性效果:
2.计算属性和函数的选择
上面的代码实现我们也可以通过函数来实现,函数定义为:
methods:{
addation(){
this.count++
},
type(){
return this.count>4?"牛逼":"不牛逼"
}
}
插值变量定义为函数:
<div>{{type()}}</div>
从运行的结果来说,使用函数和使用计算属性的结果一样,但实际上,计算属性是基于存储属性的值的变化而重新计算的,计算完成后,其结果会被缓存,下次访问计算属性时,只要依赖的属性没有变化,其内的逻辑代码不会被重复执行,而函数不一样,每次访问都会重新执行函数内的代码才可以得到结果。所以,在实际开发中,我们可以根据是否需要缓存这个标准来选择使用计算属性还是函数
3.计算属性的赋值
存储属性主要用于数据的存储,通常情况下,计算属性只用来取值,不会存值,这个取值的方法我们称为get方法,但存值的方法我们可以自己实现,称为set方法。
例如:
computed:{
type:{
//get方法取值
get(){
return this.count > 4?"牛逼":"不牛逼"
},
//set方法存值
set(newValue){
if (newVue=="牛逼"){
this.count=5
}else {
this.count=0
}
}
}
}
即可通过get和set方法实现计算属性的存取值功能
4.属性侦听
属性侦听是Vue非常强大的功能之一,使用属性侦听可以方便地监听某个属性的变化。在Vue组件中可以通过watch选项来定义属性侦听器。Vue侦听器提供的了两种语法的定义格式,分别是方法格式和对象格式
1.方法格式
//侦听器定义在watch中,监听哪个数据,就把哪个数据当函数名
watch:{
watchname(oldvalue,newvalue){
//语句
}
}
方法格式侦听器的缺点:
(1)首次进入浏览器的时候,无法立即触发一次侦听器
(2)如果侦听的是一个对象,对象里的数据发生了变化,并不会触发侦听器
2.对象格式
//侦听器定义在watch中,监听哪个数据,就把哪个数据当函数名
watch:{
watchname(oldvalue,newvalue){
//语句
},
//可以通过immediate控制侦听器自动触发一次,默认为false
immediate:true
//深度监听
depp:true
}
对象格式的缺点:
(1)可以通过immediate属性控制侦听器自动触发一次,当默认是false的
(2)不能监听到每一个属性的变化,除非设置deep属性
例如:
在页面输入框中输入字符,如果超过10个字符弹出警告
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="Application">
<input v-model="searchText"/>
</div>
<script>
const App={
data(){
return{
searchText:""
}
},
watch:{
searchText(oldValue,newValue){
if (newValue.length>10){
alert("文本过长")
}
}
}
}
let instance=Vue.createApp(App).mount("#Application")
</script>
</body>
</html>
效果:
三.函数限流
函数限流是指根据时间间隔,在指定时间间隔内不允许重复执行同一个函数,可以使用setTimeout函数来控制时间
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="Application">
<button @click="click">按钮</button>
</div>
<script>
const App={
data(){
return{
throttle:false
}
},
methods:{
click() {
if (!this.throttle){
console.log(Date())
}else {
return
}
this.throttle=true
setTimeout(()=>{
this.throttle=false
},2000);
},
}
}
Vue.createApp(App).mount("#Application")
</script>
</body>
</html>
还有就是使用Lodash库进行函数限流。Lodash是一款高性能的JavaScript实用工具库,它提供了debounce函数来进行方法的调用限流,在使用前要先导入Lodash库:
<script src="https://unpkg.com/lodash@4.17.20/lodash.min.js"></script>
上面的代码可以改为:
methods:{
click:_.debounce(function () {
console.log(Date())
},200)
}
四.表单数据的双向绑定
双向绑定是Vue中处理用户交互的一种方式,文本输入框,多行文本输入域,单选框与多选框等都可以进行数据的双向绑定
1.文本输入框
文本输入框的数据的绑定直接使用v-model指令设置就可以了,例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="Application">
<input v-model="textfileld">
<p>文本输入框内容:{{textfileld}}</p>
</div>
<script>
const App={
data(){
return{
textfileld:""
}
}
}
Vue.createApp(App).mount("#Application")
</script>
</body>
</html>
渲染效果:
2.多行文本输入域
多行文本可以使用textarea标签来实现,该标签支持换行和设置输出行数,绑定方式和input一样,如:
<textarea v-model="textarea"></textarea>
<p style="white-space: pre-line">多行文本:{{textarea}}</p>
效果:
需要注意的是textarea元素只能通过v-model指令的方式来设置内容,不能直接在标签内插入文本,如下是错误的:
<textarea v-modl="textarea">{{textarea}}</textarea>
3.复选框和单选框
复选框input标签的类型为checkbox,单选框为radio,例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="Application">
<input type="checkbox" value="python" v-model="box">python
<input type="checkbox" value="java" v-model="box">java
<input type="checkbox" value="c++" v-model="box">c++
<p>{{box}}</p>
<input type="radio" value="man" v-model="box_1">man
<input type="radio" value="woman" v-model="box_1">woman
<p>{{box_1}}</p>
</div>
<script>
var App={
data(){
return{
box:[],
box_1:""
}
}
}
Vue.createApp(App).mount("#Application")
</script>
</body>
</html>
效果:
4.选择列表
选择列表提供一组选项进行选择,可以单选也可以多选,标签为select,其内的option标签用来定义选项,如果想多选,主要添加上multiple属性即可
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="select">
<select v-model="select" multiple>
<option>Vue</option>
<option>React</option>
<option>Node</option>
</select>
<p>{{select}}</p>
</div>
<script>
var App={
data(){
return{
select:''
}
}
}
Vue.createApp(App).mount("#select")
</script>
</body>
</html>
图:ctrl键全选
5.两个常用修饰符
对表单进行数据绑定时,可以使用修饰符来控制绑定指令的行为,较常用的修饰符有lazy和trim。修饰符lazy的作用类似于属性的懒加载,当数据变化后不会第一时间去同步属性的值,当失去焦点后才同步,修饰符trim作用是将绑定的文本数据到首位空格去掉
代码展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="test">
<input v-model.lazy="text">
<p>懒加载:{{text}}</p>
<input v-model.trim="text1">
<p>懒加载:{{text1}}</p>
</div>
<script>
var App={
data(){
return{
text:"",
text1:""
}
}
}
Vue.createApp(App).mount("#test")
</script>
</body>
</html>
效果:
五.样式绑定
html可以通过class属性,id属性或标签绑定CSS样式,同样也可以用Vue绑定
1.为HTML标签绑定class属性
v-bind指令可以直接对class属性进行数据绑定,但如果绑定的值是一个对象,其就会产生一个新的语法规则,设置的对象中可以指定对应的class样式是否被选用
码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
<style>
.red{
color: red;
}
.blue{
color: blue;
}
</style>
</head>
<body>
<div id="test">
<div :class="{blue:isblue,red:isred}">
<p>国庆快乐!</p>
</div>
</div>
<script>
var App={
data(){
return{
isblue:true,
isred:false
}
}
}
Vue.createApp(App).mount("#test")
</script>
</body>
</html>
div元素的class属性会根据isblue和isred的属性值真假来改变,但class绑定的属性不会冲突,如果它们都为true,那就都会添加到class属性中
也可以使用数组对象控制class属性:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
<!-- <style>-->
<!-- .red{-->
<!-- color: red;-->
<!-- }-->
<!-- .blue{-->
<!-- color: blue;-->
<!-- }-->
<!-- </style>-->
</head>
<body>
<div id="test">
<div :class="[colorclass,fontclass]">
<p>国庆快乐!</p>
</div>
</div>
<script>
var App={
data(){
return{
colorclass:'blue',
fontclass:'font'
}
}
}
Vue.createApp(App).mount("#test")
</script>
</body>
</html>
2.绑定内联样式
内联样式时指直接通过HTML元素的style属性来设置样式,如将上面代码改动几处;
HTML元素:
<div :style="{color:textcolor,fontSize:textfont}">
<p>国庆快乐!</p>
</div>
Vue组件:
var App={
data(){
return{
textcolor:'blue',
textfont:'font'
}
}
}
Vue.createApp(App).mount("#test")
这样,我们就通过了设置style属性来设置class属性,但需要注意的是,内联设置的CSS和外部定义的CSS有一点区别,外部的多用“-”符号连接,如font-Size,而内联样式常用驼峰命名法,如fontSize
六.实战
完成一个功能完整的用户注册界面,并通过一些简单的CSS样式构造页面布局
看码:
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue@next"></script>
<style>
.container{
margin: 70px auto 0;
text-align: center;
width: 300px;
}
.subTitle{
color:gray;
font-size: 14px;
}
.title{
font-size: 45px;
}
.input{
width: 90%;
}
.inputContainer{
text-align: left;
margin-bottom: 20px;
}
.subContainer{
text-align: left;
}
.field{
font-size: 14px;
}
.input{
border-radius: 6px;
height: 25px;
margin-top: 10px;
border-color: cornsilk;
}
.tip{
margin-top: 5px;
font-size: 12px;
color: gray;
}
.setting{
font-size: 9px;
color: black;
}
.label{
font-size: 12px;
margin-left: 5px;
height: 20px;
vertical-align: middle;
}
.checkbox{
height: 20px;
vertical-align: middle;
}
.btn{
border-radius: 10px;
height: 40px;
width: 300px;
margin-top: 30px;
background-color: deepskyblue;
border-color: blue;
color: white;
}
</style>
</head>
<body>
<div class="container" id="Application">
<div class="container">
<div class="subTitle">加入我们</div>
<h1 class="title">创建你的账号</h1>
<div v-for="(item,index) in fields" class="inputContainer">
<div class="field">{{item.title}}<span v-if="item.required" style="color: #FF0000">*</span></div>
<input class="input" v-model="item.model" :type="item.type"/>
<div class="tip" v-if="index===2">请输入大于6位的密码</div>
</div>
<div class="subContainer">
<div class="setting">偏好设置</div>
<input v-model="receiveMsg" class="checkbox" type="checkbox"><label class="label">接收更新邮件</label>
</div>
<button @click="createAccount" class="btn">创建账号</button>
</div>
</div>
<script>
const App={
data(){
return{
fields:[
{
title:" 用户名",
required:true,
type:"text",
model:""
},{
title:" 邮箱地址",
required: false,
type: "text",
model:""
},{
title:"密码",
required: true,
type:"password",
model:""
}
],
receiveMsg:false
}
},
computed:{
name:{
get(){
return this.fields[0].model
},
set(value){
this.fields[0].model=value
}
},
email:{
get(){
return this.fields[1].model
},
set(value){
this.fields[1].model=value
}
},
password:{
get(){
return this.fields[2].model
},
set(value){
this.fields[2].model=value
}
}
},
methods:{
emailCheck(){
var verify=/^\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/;
if(!verify.test(this.email)){
return false
}else {
return true
}
},
createAccount(){
if(this.name.length===0){
alert("请输入用户名")
return
}else if(this.password.length<=6){
alert("密码输入需要大于6位")
return
}else if(this.email.length>0&&!this.emailCheck(this.email)){
alert("请输入正确的邮箱")
return
}
alert("注册成功!")
console.log('name:${this.name}\npassword:${this.password}\nemail:${this.email}' +
'\nreceiveMsg:${this.receiveMsg}')
}
}
}
Vue.createApp(App).mount("#Application")
</script>
</body>
</html>