Vue快速入门(笔记+小案例)

Vue基础

一、vue基础,介绍,基本架构
二、vue本地应用,常见语法,基于本地数据实现案例(计时器,图片切换,记事本)
三、网络应用,常见网络请求库axios,在vue中结合进行数据交互,实现案例(天气预报)
四、综合应用,基于音乐播放接口实现一个(音乐播放器)
五、结合网络数据应用开发(axios网络请求库、axios+vue结合)
六、综合应用(音乐播放器小案例)

一、第一个Vue程序Vue快速入门(笔记+小案例)_第1张图片

1、el挂载点

  • 用来设置Vue实例挂载(管理)的元素
  • Vue会管理el选项命中的元素及其内部的后代元素
  • 也可以使用其他选择器,建议使用ID选择器
  • 可以使用其他的双标签,不能使用html和body
    2、data数据对象
    vue中用的数据定义在data中,可以是复杂类型的数据,数据,对象,函数等

二、内容绑定,事件绑定

v-text,v-html,v-on

1、v-text(可设置文本内容)

Vue快速入门(笔记+小案例)_第2张图片
v-text设置标签的文本内容,默认替换全部内容,可以使用表达式{{}}替换指定内容。
与{{}}不同的是,v-text前后加数据只会显示v-text的数据。{{}}前后都可添加数据
Vue快速入门(笔记+小案例)_第3张图片

2、v-html(设置元素的innerhtml,可以解析标签)

Vue快速入门(笔记+小案例)_第4张图片

3、v-on(事件绑定)

Vue快速入门(笔记+小案例)_第5张图片
例子中使用v-on为按钮绑定了点击事件,也可使用@的方式。
Vue快速入门(笔记+小案例)_第6张图片方法内部可通过this关键字访问定义在data中的数据

例子:计数器效果如下:

Vue快速入门(笔记+小案例)_第7张图片
代码:

<div id="app">
	<div>
		<button @click="sub">-button>
		<button>{{num}}button>
		<button @click="add">+button>
	div>
div>
<script type="text/javascript">
	var app = new Vue({
		el: '#app',
		data: {
			num: 0
		},
		methods: {
			sub: function() {
				if (this.num > 0) {
					this.num--;
				} else {
					alert('已经是最小值了')
				}
			},
			add: function() {
				if (this.num < 10) {
					this.num++;
				} else {
					alert('已经是最大值了')
				}
			}
		}
	});
</script>

三、显示切换,属性绑定

v-show,v-if,v-bind

1、v-showVue快速入门(笔记+小案例)_第8张图片

2、v-if

Vue快速入门(笔记+小案例)_第9张图片

3、v-bind(设置元素的属性,比如:src,title,class)

Vue快速入门(笔记+小案例)_第10张图片
Vue快速入门(笔记+小案例)_第11张图片

例子:图片切换效果如下:

Vue快速入门(笔记+小案例)_第12张图片

html:

<div id="app">
		<img :src="imgArr[index]" alt="" />
		<a href="javascript:void(0)" v-if="index!=0" class="left" @click="prev">上一张a>
		<a href="javascript:void(0)" v-show="index" class="right" @click="next">下一张a>
	div>

css:

#app{
		position: relative;
		width: 400px;
	}
	img{
		width: 400px;
	}
	.left{
		position: absolute;
		left:0;
	}
	.right{
		position: absolute;
		right:0;
	}
	a{
		text-decoration: none;
		width:30px;
		height: 75px;
		margin-top:25%;
		background-color:#c1c1c1;
		opacity: 0.5;
		font-size: 18px;
		font-weight: bold;
		color: #ff5500;
	}

js

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<script type="text/javascript">
		var vue = new Vue({
			el: '#app',
			data: {
				imgArr: [
					"./img/1.jpg",
					"./img/2.jpg",
					"./img/3.jpg",
					"./img/4.jpg"
				],
				index: 0
			},
			methods: {
				prev: function() {
					this.index--;
				},
				next: function() {
					this.index++;
				}
			}
		})
	</script>

v-show和v-if都可以切换元素的显示状态,频繁切换请使用v-show,v-if影响性能。

四、列表循环,表单元素绑定

v-for,v-on,v-model

1、v-for(根据数据生成列表结构)

Vue快速入门(笔记+小案例)_第13张图片

v-for指令的作用是:根据数据生成列表结构
数组经常和v-for结合使用
语法是(item,index)in 数据
item和index可以结合其他指令一起使用
数组长度的更新会同步到页面上,是响应式的

2、v-on事件绑定(传递自定义参数,事件修饰符)

Vue快速入门(笔记+小案例)_第14张图片

3、v-model(双向数据绑定)获取和设置表单元素的值

Vue快速入门(笔记+小案例)_第15张图片

例子:小黑记事本效果如下:

Vue快速入门(笔记+小案例)_第16张图片

功能实现思路:
1、新增
(1)生成列表结构(v-for 数组);
(2)获取用户输入(v-model);
(3)回车,新增数据(v-on,.enter添加数据)
2、删除
(1)shift()删除并返回数组的第一个元素
(2)splice()删除元素,并向数组添加新元素。
3、统计(获取数组长度)
4、清空(数组为空)
5、隐藏(内容为空时隐藏,v-show)

<div id="app">
			<h2>小黑记事本h2>
			<input type="text" v-model="inputValue" @keyup.enter="add" />
			<ul>
				<li v-for="(item,index) in arr">
					<span>{{index+1}}、span>
					<label>{{item}}label>
					<button class="destroy" @click="remove">Xbutton>
				li>
			ul>
			<div v-show="arr !=''">
				<span><strong>{{arr.length}}strong>item leftspan>
				<button class="destroy" @click="clear">Clearbutton>
			div>
	div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
	var vue = new Vue({
		el: '#app',
		data: {
			inputValue: '认真生活',
			arr: ['沉迷于工作', '疯狂吸入吃吃吃', '仗剑天涯码码字', '周末狂欢刷剧']
		},
		methods: {
			add: function() {
				this.arr.push(this.inputValue);
			},
			remove: function() {
				this.arr.shift();
			},
			clear: function() {
				this.arr = [];
			}
		}
	})
</script>

五、结合网络数据应用开发(axios网络请求库、axios+vue结合)

1、axios的基本应用
Vue快速入门(笔记+小案例)_第17张图片

例子:查询天气效果如下:

Vue快速入门(笔记+小案例)_第18张图片
完整代码:

html:

<html>
	<head>
		<meta charset="utf-8">
		<title>title>
		<link type="text/css" href="./css/sky.css" rel="stylesheet" />
	head>
	<body>
		<div class="wrap" id="app">
			<div class="search_form">
				<div class="logo"><img src="img/logo.jpg" alt="logo" />div>
				<div class="form_group">
					<input type="text" v-model="city" @keyup.enter="searchWeather" class="input_text" placeholder="请输入查询的城市" />
					<button class="input_sub">搜索button>
				div>
				<div class="hotkey">
					<a href="JavaScript:;" @click="changeCity('北京')">北京a>
					<a href="JavaScript:;" @click="changeCity('上海')">上海a>
					<a href="JavaScript:;" @click="changeCity('广州')">广州a>
					<a href="JavaScript:;" @click="changeCity('深圳')">深圳a>
				div>
			div>
			<ul class="weather_list">
				<li v-for="item in wratherList">
					<div class="info_type"><span class="iconfont">{{item.type}}span>div>
					<div class="info_temp">
						<b>{{item.low}}b>~<b>{{item.high}}b>
					div>
					<div class="info_date"><span>{{item.date}}span>div>
				li>
			ul>
		div>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
		<script src="https://unpkg.com/axios/dist/axios.min.js">script>
		<script src="./js/sky.js">script>
	body>
html>

js:

/*
请求地址:http://wthrcdn.etouch.cn/weather_mini
请求方法:get
请求参数:city
响应内容:天气查询
*/
var vue = new Vue({
	el: '#app',
	data: {
		city: '',
		wratherList: []
	},
	methods: {
		searchWeather: function() {
			var that = this;
			axios.get("http://wthrcdn.etouch.cn/weather_mini?city=" + this.city)
				.then(function(response) {
					console.log(response);
					that.wratherList = response.data.data.forecast
				}).catch(function(err) {})
		},
		changeCity: function(city) {
			this.city = city;
			this.searchWeather();
		}
	}

})

css:

.wrap {
	width: 900px;
	margin: 0 auto;
}

* {
	margin: 0;
	padding: 0;
}

.search_form {
	padding: 20px 50px;
}

.logo {
	margin-left: 80px;
}

.form_group {
	margin-left: 120px;
	line-height: 30px;
}

.hotkey {
	margin-left: 120px;
	line-height: 30px;
}

.input_text {
	width: 300px;
	height: 26px;
}

button {
	width: 45px;
	height: 30px;
	border: none;
	background-color: #55aaff;
}

ul {
	list-style: none;
	display: flex;
	justify-content: space-between;
}

li {
	padding: 20px;
	border: 1px solid red;
	text-align: center;
	align-items: flex-start;
}
.weather_list{
	padding: 20px 50px;
}
.iconfont{
	font-size:26px;
	color: #FF5500;
}
.info_temp{
	font-size: 12px;
}

功能: 1、回车查询 2、点击查询

1、点击查询
html:
Vue快速入门(笔记+小案例)_第19张图片
js:
Vue快速入门(笔记+小案例)_第20张图片
控制台:拿到forecast这个数组
Vue快速入门(笔记+小案例)_第21张图片

Vue快速入门(笔记+小案例)_第22张图片
回到模板中,将数据同步到列表中
Vue快速入门(笔记+小案例)_第23张图片
2、点击查询(点击城市,查询数据,渲染数据)
html
Vue快速入门(笔记+小案例)_第24张图片
js
Vue快速入门(笔记+小案例)_第25张图片

六、综合应用(音乐播放器)

功能:歌曲搜索,歌曲播放,歌曲封面,歌曲评论,播放动画,mv播放

1、歌曲搜索

按下回车(v-on)、查询数据(axios接口,v-mode),渲染数据(v-for 数组 that)

2、歌曲播放

点击播放(v-on 自定义参数)、歌曲地址的获取(接口,歌曲id),歌曲地址设置(v-bind)

3、歌曲封面

点击播放(增加逻辑)、歌曲封面获取(接口,歌曲id),歌曲封面设置(v-hind)

4、歌曲评论

点击播放,歌曲评论获取(接口 歌曲id),歌曲评论渲染(v-for)

5、播放动画

监听音乐播放(v-on play)、监听音乐暂停(v-on pause)、操纵类名(v-bind 对象)

5、播放MV

mv图标显示(v-if)、mv地址获取(接口 mvid )、遮罩层( v-show v-on)、mv地址设置(v-bind)
html:


<html>
	<head>
		<meta charset="utf-8">
		<title>title>
		<link type="text/css" href="./css/music.css" rel='stylesheet' />
	head>
	<body>
		<div class="wrap">
			<div class="play_wrap" id="player">
				<div class="search_bar">
					<img src="./img/music/player_title.png" alt="" />
					
					<input type="text" v-model="query" @keyup.enter="searchMusic" />
				div>
				
				<div class="center_con">
					
					<div class="song_wrapper">
						<ul class="song_list">
							<li v-for="item in musicList">
								<a href="javascript:;" @click="playMusic(item.id)">a>
								<b>{{item.name}}b>
								<span v-if="item.mvid !=0" @click="palyMV(item.mvid)">
									<i>i>
								span>
							li>
						ul>
						<img src="./img/music/line.png" class="switch_btn" />
					div>
					
					<div class="player_con" :class="{playing:isPlaying}">
						<img src="./img/music/player_bar.png" class="play_bar">
						<img src="./img/music/disc.png" class="disc autoRotate">
						<img :src="musicCover" class="cover autoRotate">
					div>
					<div class="comment_wrapper">
						<h5 class="title">热门留言h5>
						<div class="comment_list">
							<dl v-for=" item in hotComments">
								<dt><img :src="item.user.avatarUrl" alt="" class="img">dt>
								<dd class="name">{{item.nickname}}dd>
								<dd class="detail">
									{{item.content}}
								dd>
							dl>
						div>
						<img src="img/music/line.png" class="right_line" />
					div>
				div>
				
				<div class="audio_con">
					<audio ref='audio' @play="play" @pause="pause" :src="musicUrl" controls autoplay loop class="myaudio">audio>
				div>
				<div class="video_con" style="display: none;">
					<video src="" controls="controls">video>
					<div class="mask">div>
				div>
				<div class="video_con" v-show="isShow" style="display: none;">
					<video ref='video' :src="mvUrl" controls="controls">video>
					<div class="mask" @click="hide">div>
				div>
			div>
		div>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
		<script src="https://unpkg.com/axios/dist/axios.min.js">script>
		<script src="./js/music.js">script>
	body>
html>

css:

body,
ul,
dl,
dd {
	margin: 0px;
	padding: 0px;
}


.wrap {
	position: fixed;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	background: url(./img/music/bg.jpg) no-repeat;
	background-size: 100% 100%;
}

.play_wrap {
	width: 800px;
	height: 544px;
	position: fixed;
	left: 50%;
	top: 50%;
	margin-left: -400px;
	margin-top: -272px;
	/* background-color: #f9f9f9; */
}

.search_bar {
	height: 60px;
	padding: 0 23px;
	background-color: #1eacda;
	display: flex;
	align-items: center;
	border-top-left-radius: 4px;
	border-top-right-radius: 4px;
	justify-content: space-between;
	z-index: 11;
	position: relative;
}

.search_bar input {
	width: 296px;
	height: 34px;
	border-radius: 17px;
	border: 0px;
	background: url(./img/music/zoom.png) no-repeat 265px center rgba(255, 255, 255, 0.45);
	text-indent: 15px;
	outline: none;
}

/* 中间部分内容 */
.center_con {
	height: 435px;
	background-color: rgba(255, 255, 255, 0.5);
	display: flex;
	position: relative;
}

/* 歌曲列表 */
.song_wrapper {
	width: 200px;
	height: 435px;
	box-sizing: border-box;
	padding: 10px;
	list-style: none;
	position: absolute;
	left: 0px;
	top: 0px;
	z-index: 1;
}

.song_list {
	list-style: none;
	width: 100%;
	overflow-y: auto;
	overflow-x: hidden;
	height: 100%;
}

.song_list::-webkit-scrollbar {
	display: none;
}

.song_list li:nth-child(odd) {
	background-color: rgba(240, 240, 240, 0.3);
}

.song_list li {
	font-size: 12px;
	color: #333;
	height: 40px;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	width: 580px;
	padding-left: 10px;
}

.song_list li a {
	display: block;
	width: 17px;
	height: 17px;
	background-image: url(../img/music/play.png);
	background-size: 100%;
	margin-right: 5px;
	box-sizing: border-box;
}

user agent stylesheet a:-webkit-any-link {
	color: -webkit-link;
	cursor: pointer;
	text-decoration: underline;
}

.song_list li b {
	font-weight: normal;
	width: 122px;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.song_list li span {
	width: 23px;
	height: 17px;
	margin-right: 50px;
}

.song_list li span i {
	display: block;
	width: 100%;
	height: 100%;
	cursor: pointer;
	background: url(../img/music/table.png) left -48px no-repeat;
}

/* 歌曲主页 */
.player_con {
	width: 400px;
	height: 435px;
	position: absolute;
	left: 200px;
	top: 0px;
}

.play_bar {
	position: absolute;
	left: 200px;
	top: -10px;
	z-index: 10;
	transform: rotate(-25deg);
	transform-origin: 12px 12px;
	transition: 1s;
}

.autoRotate {
	animation-name: Rotate;
	animation-iteration-count: infinite;
	animation-play-state: paused;
	animation-timing-function: linear;
	animation-duration: 5s;
}

.disc {
	position: absolute;
	left: 73px;
	top: 60px;
	z-index: 9;
}

.autoRotate {
	animation-name: Rotate;
	animation-iteration-count: infinite;
	animation-play-state: paused;
	animation-timing-function: linear;
	animation-duration: 5s;
}

.cover {
	position: absolute;
	left: 125px;
	top: 112px;
	width: 150px;
	height: 150px;
	border-radius: 75px;
	z-index: 8;
}

/* 旋转的动画 */
@keyframes Rotate {
	from {
		transform: rotateZ(0);
	}

	to {
		transform: rotateZ(360deg);
	}
}

/* 旋转的类名 */
.autoRotate {
	animation-name: Rotate;
	animation-iteration-count: infinite;
	animation-play-state: paused;
	animation-timing-function: linear;
	animation-duration: 5s;
}

/* 是否正在播放 */
.player_con.playing .disc,
.player_con.playing .cover {
	animation-play-state: running;
}

.play_bar {
	position: absolute;
	left: 200px;
	top: -10px;
	z-index: 10;
	transform: rotate(-25deg);
	transform-origin: 12px 12px;
	transition: 1s;
}

/* 播放杆 转回去 */
.player_con.playing .play_bar {
	transform: rotate(0);
}

/* 分割线 */
.switch_btn {
	position: absolute;
	right: 0;
	top: 0;
	cursor: pointer;
}

/* 留言列表 */
.comment_wrapper {
	width: 180px;
	height: 385px;
	list-style: none;
	padding: 25px 10px;
	position: absolute;
	left: 600px;
	top: 0px;
}

.comment_wrapper .title {
	position: absolute;
	top: 0;
	margin-top: 10px;
}

.right_line {
	position: absolute;
	left: 0;
	top: 0;
}

.comment_wrapper .comment_list {
	overflow: auto;
	height: 410px;
}

/* 底部播放器 */
.audio_con {
	height: 50px;
	background-color: #f1f3f4;
	border-bottom-left-radius: 4px;
	border-bottom-right-radius: 4px;
}

.comment_wrapper .title {
	position: absolute;
	top: 0;
	margin-top: 10px;
}

.comment_wrapper .comment_list {
	overflow: auto;
	height: 410px;
}

.comment_wrapper .comment_list::-webkit-scrollbar {
	display: none;
}

.comment_wrapper dl {
	padding-top: 10px;
	padding-left: 55px;
	position: relative;
	margin-bottom: 20px;
}

.comment_wrapper dt {
	position: absolute;
	left: 4px;
	top: 10px;
}

.comment_wrapper dt img {
	width: 40px;
	height: 40px;
	border-radius: 20px;
}

.comment_wrapper dd {
	font-size: 12px;
}

.comment_wrapper .name {
	font-weight: bold;
	color: #333;
	padding-top: 5px;
}

.comment_wrapper .detail {
	color: #666;
	margin-top: 5px;
	line-height: 18px;
}

.audio_con {
	height: 50px;
	background-color: #f1f3f4;
	border-bottom-left-radius: 4px;
	border-bottom-right-radius: 4px;
}

.myaudio {
	width: 800px;
	height: 40px;
	margin-top: 5px;
	outline: none;
	background-color: #f1f3f4;
}

.video_con video {
	position: fixed;
	/* width: 800px; */
	height: 546px;
	left: 50%;
	top: 50%;
	margin-top: -273px;
	transform: translateX(-50%);
	z-index: 990;
}

.video_con .mask {
	position: fixed;
	width: 100%;
	height: 100%;
	left: 0;
	top: 0;
	z-index: 980;
	background-color: rgba(0, 0, 0, 0.8);
}

.video_con .shutoff {
	position: fixed;
	width: 40px;
	height: 40px;
	background: url("../images/shutoff.png") no-repeat;
	left: 50%;
	margin-left: 400px;
	margin-top: -273px;
	top: 50%;
	z-index: 995;
}
```javascript
/*
1、回车查询音乐
请求地址:https://autumnfish.cn/search
请求方法:get
请求参数:keywords(查询的关键字)
响应内容:歌曲搜索结果

2、点击播放音乐
请求地址:https://autumnfish.cn/song/url
请求方法:get
请求参数:id(歌曲id)
响应内容:歌曲的url地址

3、歌曲封面
请求地址:https://autumnfish.cn/song/detail
请求方法:get
请求参数:get
响应内容:歌曲详情(包括封面信息)

4、歌曲评论
请求地址:https://autumnfish.cn/comment/hot?type=0
请求方法:get
请求参数:id(歌曲id,type固定为0)
响应内容:歌曲的热门评论

5、mv播放
请求地址:https://autumnfish.cn/mv/url
请求方法:get
请求参数:id(mvid,为0说明没有mv)
响应内容:mv的地址
*/
var app = new Vue({
	el: '#player',
	data: {
		query: "",
		// 歌曲数据
		musicList: [],
		// 歌曲地址
		musicUrl: "",
		// 歌曲封面
		musicCover: "",
		// 歌曲评论
		hotComments: [],
		// 动画播放状态
		isPlaying: false,
		// 遮罩层的显示状态
		isShow: false,
		// mv地址
		mvUrl: ""
	},
	methods: {
		// 歌曲搜索
		searchMusic: function() {
			var that = this;
			axios.get('https://autumnfish.cn/search?keywords=' + this.query)
				.then(function(response) {
					that.musicList = response.data.result.songs;
					// console.log(response.data.result.songs);
				}, function(err) {})
		},
		// 歌曲播放
		playMusic: function(musicId) {
			var that = this;
			// 获取歌曲地址
			axios.get("https://autumnfish.cn/song/url?id=" + musicId)
				.then(function(response) {
					that.musicUrl = response.data.data[0].url;
					// console.log(response.data.data[0].url);
				}, function(err) {})
			// 获取歌曲详情
			axios.get("https://autumnfish.cn/song/detail?ids=" + musicId)
				.then(function(response) {
					// console.log(response.data.songs[0].al.picUrl);
					that.musicCover = response.data.songs[0].al.picUrl;
				}, function(err) {})
			//获取歌曲评论
			axios.get("https://autumnfish.cn/comment/hot?type=0&id=" + musicId)
				.then(function(response) {
					// console.log(response.data.hotComments)
					that.hotComments = response.data.hotComments;
				}, function(err) {})
		},
		// 歌曲播放
		play: function() {
			this.isPlaying = true;
		},
		// 歌曲暂停
		pause: function() {
			this.isPlaying = false;
		},
		// 播放mv
		palyMV: function(mvid) {
			var that = this;
			axios.get("https://autumnfish.cn/mv/url?id=" + mvid)
				.then(function(response) {
					// console.log(response.data.data.url);
					that.isShow = true;
					that.mvUrl = response.data.data.url;
				}, function(err) {})
		},
		hide: function() {
			this.isShow = false;
		}
	}
})

你可能感兴趣的:(vue)