Javascript

Vue全系列

本文主要是介绍Vue全系列,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Vue全系列

  • 基础语法
    • mustache语法
    • v-once:只会变化一次
    • v-text:插值表达式mustache的效果
    • v-html:注入带html格式的内容
    • v-pre:不编译,所见即所得
    • v-cloak:避免页面加载慢,页面展示出mustache语法
    • v-bind:动态绑定src等属性
    • v-on:监听事件
    • v-on 常用修饰符
    • 计算属性:数据需要简单的处理再显示
    • v-if和v-show
    • v-if和v-show切换登录方式
    • v-for:数据遍历
    • 计算属性实现排序和条件搜索
    • v-model
    • 其他
      • 列表删除增加等为什么要绑定key
  • 组件

参考
2021版-vue3.0+vue全家桶全系列精讲(多案例+多项目)【撩课】
vue 官网

基础语法

mustache语法

{{ 可以写简单的表达式,不能是语句 }} 只能用于开始标签与结束标签中间,不能用于标签中

    <div id="app">
        <h1>{{ msg }},love baby</h1>
        <h1>{{ msg + '' + site}}</h1>
        <h1>{{ msg }} {{site}}</h1>
        <h1>{{ count*2 / 10 }}</h1>
    </div>

v-once:只会变化一次

	<div id="app">
		<h1>会变化:{{ msg }}</h1>
		<h1 v-once>不会变化:{{ msg }}</h1>
	</div>

v-text:插值表达式mustache的效果

v-text会把innerTEXT中的内容覆盖,{{}}不会覆盖

<div id="app">
	<h1>{{ msg }}内容不被覆盖</h1>
	<h1 v-text='msg'>内容被覆盖</h1>
</div>

v-html:注入带html格式的内容

业务型功能有注入风险,不使用v-html

<div id="app">
	<div>{{ web }}解析为文本</div>
	<br>
	<div v-html='web'>解析为html标签</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			msg: '我爱宝贝',
			web: '<a href="http://www.baidu.com/">百度</a>'
		},
		methods: {

		}
	})
</script>

在这里插入图片描述

v-pre:不编译,所见即所得

<div id="app">
	<h1 v-pre>不产生编译:{{ msg }}</h1>
	<br>
	<h1>正常双向绑定:{{ msg }}</h1>
</div>

在这里插入图片描述

v-cloak:避免页面加载慢,页面展示出mustache语法

vue实例解析之前,h1标签有v-cloak属性
vue实例解析之后,h1标签没有了v-cloak属性

<style type="text/css">
	[v-cloak]{
		display: none;
	}
</style>
<div id="app">
	<h1 v-cloak>{{ msg }}</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	setTimeout(()=>{
		var app = new Vue({
			el: '#app',
			data: {
				msg: '我爱宝贝',
				web: '<a href="http://www.baidu.com/">百度</a>'
			},
			methods: {
		
			}
		})
	},1000)
</script>

v-bind:动态绑定src等属性

属性可变时,v-bind动态绑定标签属性和vue对象中数据
v-bind:src 可以写为 :src

<div id="app">
<!-- <img src="imgUrl" >  imgUrl会被解析为普通字符串-->
	<img v-bind:src="imgUrl" v-bind:alt="alt">
	<a :href="site">撩课学院</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			msg:'我爱宝贝',
			imgUrl:'https://i0.hdslb.com/bfs/face/ca4767f400f735032a9a8053db730476ea94e27d.jpg@96w_96h_1c_1s.webp',
			alt:'撩课学院',
			site:'http://www.baidu.com'
		},
		methods: {

		}
	})
</script>

模板界面中,很多元素的样式是变化的,class/style用于动态绑定类和样式

<style type="text/css">
	.red {
		color: red;
	}

	.f60 {
		font-size: 60px;
	}
</style>
<div id="app">
	<h1 class="red">{{ msg }}</h1>
	<h1 :class="red">{{ msg }}</h1>
	<!--动态绑定样式-->
	<!--多个样式-->
	<!-- <p :class="{类名1:布尔值,类名2:布尔值}">{{ msg }}</p> -->
	<p class="box" :class="{red:true,f60:true}">{{ msg }}</p>    <!--动态绑定样式和固定样式可以并存,不会相互覆盖-->
	<p class="box" :class="{red:isRed,f60:isF60}">{{ msg }}</p>
	<button type="button" @click="change">切换</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			msg: '我爱宝贝',
			red: 'red',
			f60: 'f60',
			isRed: true,
			isF60: true
		},
		methods: {
			change(){
				this.isRed = !this.isRed,
				this.isF60 = !this.isF60
			}
		}
	})
</script>

使用数组动态绑定样式

<h1 class="red f60">{{ msg }}</h1>
<!--用数组的方式动态绑定样式-->
<h1 :class="[red,f60]">{{ msg }}</h1>
<!--样式多的时候,封装到一个函数-->
<!--使用事件调用函数时不写小括号,其他时候调用函数时要写小括号-->
<h1 :class="getClass()">{{ msg }}</h1>  

<script>
	var app = new Vue({
		el: '#app',
		data: {
			msg: '我爱宝贝',
			red: 'red',
			f60: 'f60',
		},
		methods: {
			getClass(){
				return [this.red,this.f60];
			}
		}
	})
</script>

动态绑定style样式,以键值对数组的方式绑定多个可变样式,样式长可以抽出为一个函数
style=" 之间的内容是以 css 的形式解析的"
v-bind:style=" 之间的内容是以 js 的形式解析的"
font-size 对应 fontSize

<div id="app">
	<p style="font-size: 50px;">{{ msg }}</p>
	<p :style="{fontSize: '50px'}">{{ msg }}</p>
	<!-- 以键值对数组的方式绑定多个样式 -->
	<p :style="{fontSize: f50,backgroundColor:red}">{{ msg }}</p>
	<!-- 样式多的时候抽出为一个函数 -->
	<p :style="getStyle()">{{ msg }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			msg: '我爱宝贝',
			red: 'red',
			f50: '50px',
		},    <!-- 注意这里的逗号,没有逗号报错 -->
		methods: {
			getStyle(){
				return {fontSize: this.f50,backgroundColor:this.red};
			}
		}
	})
</script>

v-on:监听事件

v-on:click 可以简写为 @click

<div id="app">
	<p>运算结果:{{count }}</p>
	<button v-on:click="sub()">-</button>    <!-- 不用传参可以去掉小括号,仅限于事件调用函数,其他情况调用函数括号都不能去掉 -->
	<button @click="add">+</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			count: 0
		},
		methods: {
			sub(){
				this.count--;
			},
			add(){
				this.count++;
			}
		}
	})
</script>

在这里插入图片描述
绑定事件的参数传递

<div id="app">
	<!--不带参数-->
	<button type="button" @click="btn1()">有括号不传参</button>
	<button type="button" @click="btn2">没括号</button>
	<button type="button" @click="btn3(123,'a',true,msg)">有参数</button>  <!--msg会在vue对象中找-->
	<!--事件对象参数用$event-->
	<button type="button" @click="btn4(123,'a',true,msg,$event)">事件对象参数</button>  <!--msg会在vue对象中找-->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			msg:'我爱宝贝'
		},
		methods: {
			btn1(args){
				console.log(args);  <!--undefined-->
			},
			btn2(args){
				console.log(args);    <!--输出click事件对象-->
			},
			btn3(arg1,arg2,arg3,arg4){
				console.log(arg1,arg2,arg3,arg4);    <!--输出所有参数-->
				// console.log(Arguments);    <!--输出所有参数-->
			},
			btn4(arg1,arg2,arg3,arg4,arg5){
				console.log(arg1,arg2,arg3,arg4,arg5);    <!--输出所有参数-->
			}
			
		}
	})
</script>

v-on 常用修饰符

下面第一张图点击了button按钮,div关联的事件也触发了,称为冒泡
第二张图点击button,div关联事件不触发,阻止了冒泡
在这里插入图片描述
在这里插入图片描述

<div id="app">
<!--阻止冒泡:点击div内部按钮时,不会冒泡到div相关的事件-->
<div class="box" @click="boxClick">
	<button type="button" @click.stop="btnClick">按钮</button>
</div>

<!--阻止默认事件:阻止表单提交,不阻止的话,点击submit表单会直接提交到action-->
<form action="http://www.baidu.com/">
	<input type="submit" value="提交" @click.prevent="doSubmit"/>
</form>
<a href="http://www.baidu.com" @click.prevent="doSubmit">百度</a>

<!--响应一次事件-->
<button type="button" @click.once="btnClick">只有第一次点击生效</button>

<!--键盘事件修饰符:获取用户按键信息   .keycode  .enter  .tab  .delete  .esc  .space  .up  .down  .left .right-->
<input type="text" @keyup="getMsg" />
<input type="text" @keyup.enter="getMsg" />    <!--回车时事件才响应-->

</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
	el: '#app',
	data: {
	},
	methods: {
		boxClick(){
			console.log("点击了盒子")
		},
		btnClick(event){
			// event.stopPropagation();	<!--阻止冒泡原始写法-->
			console.log("点击了按钮")
		},
		doSubmit(event){
			// event.preventDefault();   阻止默认事件
			console.log("表单提交")
		},
		getMsg(event){
			console.log(event);
		},
		
	}
})
</script>

计算属性:数据需要简单的处理再显示

  • 页面中某个展示需要经过多个属性共同运算得到,多个属性共同运算的逻辑放到计算属性中
  • 内部实现: computed{ fullName(){ 计算属性内部其实有set和get方法,更改取值用的其实是set和get }}
  • 函数和计算属性的区别:页面中多次使用同一计算属性时,第一个计算属性加载完毕后,会缓存起来,再加载同样的计算属性时,检查计算属性中的值是否没发生变化,如果没有发生变化就不会再运算,直接用缓存,而函数每次调用都会再次计算
<div id="app">
	<p>宝贝·老婆</p>
	<!--常规写法,不应该在这里写太多的逻辑代码,容易与vue对象产生耦合-->
	<p>{{ firstName + '·' + lastName}}</p>
	<!--函数-->
	<p>{{ getFullName() }}</p>  <!--除事件调用函数之外不能省略小括号-->
	<!--计算属性-->d
	<p>{{ fullName }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			firstName:'宝贝',
			lastName:'老婆',
		},
		// 计算属性
		computed:{
			// 本质上还是属性,写法如函数,命名如属性
			fullName(){
				return this.firstName + '·' +  this.lastName;
			}
		},
		methods: {
			getFullName(){
				return this.firstName + '·' +  this.lastName;
			}
		}
	})
</script>

计算属性处理数组,用到 for(let member of this.members){} 循环for

<div id="app">
	<p>{{ members[0].score + members[1].score + members[2].score}}</p>
	<!--使用计算属性-->
	<p>{{ totalScore }}</p>   <!--计算属性本质是一个属性,不能写totalScore() -->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			members:[
				{name:'张三',score:89},
				{name:'李四',score:92},
				{name:'王五',score:91}
			]
		},
		computed:{
			totalScore(){
				let total = 0;
				for(let member of this.members){
					total += member.score;
				}
				return total;
			}
		},   
		<!--vue对象中只要有语法错误,mustache就会直接显示{{}}原始格式-->
		methods: {
			
		}
	})
</script>

v-if和v-show

  • v-if 是真正的条件渲染,实现原理是组件的销毁和创建
  • v-show不管初始条件是什么,元素都会被渲染,只会被创建一次,显示和隐藏是基于css display:none 实现
  • 经常切换用v-show,否则用v-if
<div id="app">
	<div v-if="flag">和宝贝去深圳</div>
	<div v-else="flag">和宝贝去北京</div>
	<p>===============</p>
	<div v-show="flag">和宝贝去北京</div>
	<div v-show="!flag">和宝贝去天津</div>
	<br>
	<button type="button" @click="flag=!flag">切换</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			flag:true
		},
		methods: {
			
		}
	})
</script>

v-if和v-show切换登录方式

  • v-if切换登录方式,会把原来输入的内容清空,因为原理是div的销毁和创建
  • v-show切换登录方式,会记录上一次填入的内容
<div id="app">
	<!-- v-if切换登录方式,会把原来输入的内容清空,因为原理是div的销毁和创建 -->
	<!-- <div v-if="loginType==='phone'">     === 三个等号表示恒等于,类型相同值相同
		手机:<input type="text" placeholder="请输入手机号码"/><br>
		密码:<input type="password" placeholder="请输入密码"/><br>
	</div>
	<div v-else>
		邮箱:<input type="text" placeholder="请输入邮箱"/><br>
		密码:<input type="password" placeholder="请输入密码"/><br>
	</div> -->
	
	<!-- v-show切换登录方式,会记录上一次填入的内容 -->
	<div v-show="loginType ==='phone'"> 
		手机:<input type="text" placeholder="请输入手机号码"/><br>
		密码:<input type="password" placeholder="请输入密码"/><br>
	</div>
	<div v-show="loginType === 'email'">
		邮箱:<input type="text" placeholder="请输入邮箱"/><br>
		密码:<input type="password" placeholder="请输入密码"/><br>
	</div>
	<button @click="change">切换登录方式</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			loginType:'phone'
		},
		methods: {
			change(){
				this.loginType === 'phone' ? this.loginType = 'email' : this.loginType = 'phone'
			}
		}
	})
</script>

v-for:数据遍历

v-for=“e in elements” 或者v-for="(e,index) in elements"
v-if 的优先级大于 v-for,一般不要在同一个标签中,同时使用两者

<div id="app">
	<ul>
		<li v-for="e in aicheng">{{ e }}</li>
	</ul>
	<ul>
		<li v-for="(e,index) in aicheng">{{ index }}:{{ e }}</li>
	</ul>
	<ul>
		<li v-for="e in date">{{ e.begin }}-{{ e.location }}-{{ e.love }}</li>
	</ul>
	<ul>
		<li v-for="item in baby">{{ item }}</li>  <!--得到的是value-->
		<p>===============</p>
		<li v-for="(item,key) in baby">{{ key }}:{{ item }}</li>
		<p>===============</p>
		<li v-for="(item,key,index) in baby">{{ index }}-{{ key }}:{{ item }}</li>
	</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
		    //数组
			aicheng:['宝贝','老婆','宝儿','媳妇儿'],
			//json数组
			date:[
				{begin:'1.5',location:'邯郸',love:'爱你'},
				{begin:'4.22',location:'武汉',love:'永远爱你'},
				{begin:'7.2',location:'济南',love:'这辈子就是你了'},
			],
			//对象
			baby:{
				name:'宝贝',
				age:18,
				love:'我可爱的女朋友',
			}
	})
</script>

计算属性实现排序和条件搜索

<head>
<meta charset="utf-8">
<title>Vue基础</title>
<style type="text/css">
	ul li{
		list-style: none;
		line-height: 40px;
	}
	body{
		text-align: center;
	}
</style>
</head>
<body>
<div id="app">
	<h3>搜索</h3>
	<label><input type="text" placeholder="请输入关键词" v-model="searchStr"/></label>
	<h3>排序</h3>
	<button type="button" @click="setOrderType(2)">年龄升序</button>
	<button type="button" @click="setOrderType(1)">年龄降序</button>
	<button type="button" @click="setOrderType(0)">还原</button>
	<div>
		<ul>
			<li v-for="(p,index) in filterPerson">{{ index + 1 }}-{{ p.name }}-{{ p.age }}</li>
		</ul>
	</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			person:[
				{name:'张三',age:'19'},
				{name:'王五',age:'22'},
				{name:'张六',age:'20'}
			],
			//管理输入框
			searchStr:'',
			//flag 默认0,升序1,降序2
			orderType:0
		},
		//计算属性,得到筛选后的展示数组
		computed:{
			filterPerson(){
				//1.取出相关属性
				const{person,searchStr,orderType} = this;
				//2.定义过滤数组
				let arr = [...person];		//深拷贝
				//3.根据条件过滤
				if(searchStr.trim()){
					arr = person.filter((p)=>{
						return p.name.indexOf(searchStr) != -1;
					})
				}
				//4.排序
				if(orderType){
					arr.sort((p1,p2)=>{		//sort底层是冒泡排序
						//升序
						if(orderType === 2){
							return p1.age - p2.age;	//表示从p1到p2升序
						//降序
						}else{
							return p2.age - p1.age;
						}
					})
				}
				
				//5.返回过滤后的数组
				return arr;
			}
		},
		methods:{
			setOrderType(orderType){
				this.orderType = orderType;
			}
		}
	})
</script>
</body>

v-model

v-model绑定的元素值和输入框同步

<div id="app">
	<!-- <input type="text" :value="msg" @input="valueChange"/> -->
	<input type="text" :value="msg" @input="msg=$event.target.value"/>
	<h1>{{ msg }}</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			msg:'我爱宝贝'
		},
		methods:{
			valueChange(event){
				console.log("---------------")
				this.msg = event.target.value;
			}
		}
	})
</script>

v-model 结合单选

<div id="app">
	<label><input name="sex" type="radio" value="男" v-model="sex"/>男</label>
	<label><input name="sex" type="radio" value="女" v-model="sex"/>女</label>
	<p>==========</p>
	<h2>选择的性别是:{{ sex }}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var app = new Vue({
		el: '#app',
		data: {
			sex:''
		}
	})
</script>

v-model 结合多选

<div id="app">
<!-- 单个选项 -->
<label>
	<input type="checkbox" v-model="isAgree"/>同意永远爱宝贝协议
</label>
<h2>是否同意协议:{{ isAgree ? '同意' : '不同意' }}</h2>
<button type="button" :disabled="!isAgree">注册</button>

<p>=================</p>

<!-- 多个选项 -->
<label>兴趣爱好:</label>
<input type="checkbox" value="宝贝" v-model="hobbies"/>宝贝
<input type="checkbox" value="老婆" v-model="hobbies"/>老婆
<input type="checkbox" value="小韩" v-model="hobbies"/>小韩
<h2>用户兴趣爱好:{{ hobbies }}</h2>

<p>==================</p>

<!-- 值绑定 -->
<label v-for="like in likes" :for="like">  <!-- :for 关联ID-->
	<!-- 循环的是like,绑定的是love ,选中什么,在love中存入什么 -->
	<input type="checkbox" :value="like" :id="like" v-model="love"/>{{ like }}
</label>
<h2>用户兴趣爱好:{{ love }}</h2>

</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
	el: '#app',
	data: {
		isAgree:'',
		hobbies:[],
		likes:["宝贝","老婆","小韩"],
		love:[]
	}
})
</script>

其他

列表删除增加等为什么要绑定key

为了给vue一个提示,方便它追踪每个节点的身份,从而重用和重新排序现有的元素,需要为每一项提供一个唯一的key

不要使用对象或者数组之类的非基本类型的值作为v-for的key,请使用字符串或数值类型的值

<div v-for="item in items" :key="item.id">
</div>

在这里插入图片描述

组件

这篇关于Vue全系列的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!