目录
学习黑马 vue 教程的笔记,视频传送门:黑马程序员vue前端基础教程-4个小时带你快速入门vue_哔哩哔哩_bilibili
开发环境:idea2021
官方帮助文档:Vue.js
若 IDEA 没有 vue 的提示,可以下载 vue.js 插件
1、vue 基础
1.1、第一个 vue 程序
1.1.1、导入 vue 依赖
根据官方文档,有两种导入依赖的方式
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
1.1.2、编写代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>第一个vue程序</title>
</head>
<body>
<div id="app">
{{ message }}
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app", /* 绑定元素id */
data: {
message: "你好,vue"
}
})
</script>
</body>
</html>
页面输出:你好,vue
1.2、el 挂载点
el是用来设置 Vue 实例挂载(管理)的元素
Vue实例的作用范围:Vue会管理 el 选项命中的元素及其内部的后代元素
是否可以使用其他的选择器? 可以使用其他的选择器,但是建议使用ID选择器
是否可以设置其他的dom元素呢? 可以使用其他的双标签,不能使用HTML和BODY
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>el挂载点</title>
</head>
<body id="body">
{{ message }} <!-- 该message无法被渲染 -->
<p id="app" class="app">
{{ message }}
<span> {{ message }} </span> <!-- 该message可以被渲染 -->
</p>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
// el: "#app", /* 绑定元素id */
// el:".app", /* . 是class选择器 */
// el:"div", /* 标签选择器 */
el:"#body", /* */
data: {
message: "你好,vue"
}
})
</script>
</body>
</html>
1.3、data 数据对象
Vue 中用到的数据定义在 data 中
data 中可以写复杂类型的数据
渲染复杂类型数据时,遵守 js 的语法即可
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>data数据对象</title>
</head>
<body>
<div id="app">
{{ message }}
<h2> {{ school.name }} {{ school.mobile }} </h2>
<ul> <!-- 无序列表标签 -->
<li> {{ campus[0] }} </li> <!-- li:定义列表标签 -->
<li> {{ campus[1] }} </li>
<li> {{ campus[2] }} </li>
</ul>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app", /* 绑定元素id */
data: {
message: "你好,vue",
school:{
name:"一中",
mobile:"10086"
},
campus:["第一校区","第二校区","第三校区"]
}
})
</script>
</body>
</html>
2、vue 常用指令
2.1、v-text
设置标签的文本值(textContent)
默认写法会替换全部内容,使用差值表达式{{}}可以替换指定内容
内部支持写表达式
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>v-text</title>
</head>
<body>
<div id="app">
<h2 v-text="message + '!'">哈哈</h2> <!-- 你好,vue! -->
<h2 v-text="info + '!'">哈哈</h2> <!-- giao! -->
<h2> {{ message + '!' }} 哈哈</h2> <!-- 你好,vue! 哈哈 -->
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app", /* 绑定元素id */
data: {
message: "你好,vue",
info:"giao"
}
})
</script>
</body>
</html>
2.2、v-html
v-html 指令的作用是:设置元素的 innerHTML
若内容为普通文本,v-html 与 v-text 的作用没有区别,内容不为普通文本,区别如下:
内容中有 html 结构会被解析为标签
v-text 指令无论内容是什么,只会解析为文本
总结:解析文本使用 v-text ,需要解析 html 结构使用 v-html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>第一个vue程序</title>
</head>
<body>
<div id="app">
<p v-html="context"></p> <!-- 百度(超链接) -->
<p v-text="context"></p> <!-- <a href='https://www.baidu.com/'>百度</a> -->
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app", /* 绑定元素id */
data: {
// context:"你好"
context:"<a href='https://www.baidu.com/'>百度</a>"
}
})
</script>
</body>
</html>
2.3、v-on
官方介绍:API — Vue.js
v-on 指令的作用是:为元素绑定事件
事件名不需要写 on
指令可以简写为 @
绑定的方法定义在 methods 属性中
方法内部通过 this 关键字可以访问定义在 data 中数据
事件绑定的方法写成函数调用的形式,可以传入自定义参数
定义方法时需要定义形参来接收传入的实参
事件的后面跟上 .修饰符 可以对事件进行限制
.enter 可以限制触发的按键为回车
事件修饰符有多种
基本使用:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>v-on</title>
</head>
<body>
<div id="app">
<input type="button" value="v-on指令" v-on:click="doIt">
<input type="button" value="v-on简写" @click="doIt">
<input type="button" value="双击事件" @dblclick="doIt">
<h2 @click="changeFood">{{ food }}</h2>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app", /* 绑定元素id */
data:{
food:"猪耳朵"
},
methods:{
doIt:function (){
alert("doIt");
},
changeFood:function (){
// console.log(this.food);
this.food += "!" /* 每点击一下多一个! */
}
}
})
</script>
</body>
</html>
补充使用:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>v-on补充</title>
</head>
<body>
<div id="app">
<input type="button" value="点击" @click="doIt(666,'没毛病')">
<!-- @keyup:键盘事件,键盘按下并松开后 -->
<!-- @keyup.enter:键盘事件,按下回车并松开后 -->
<input type="text" @keyup.enter="sayHi">
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
methods:{
doIt:function (p1,p2){
console.log("doIt");
console.log(p1);
console.log(p2);
},
sayHi:function (){
alert("你好");
}
}
})
</script>
</body>
</html>
2.4、案例 —— 计数器
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>计数器</title>
</head>
<body>
<div id="app">
<!-- 计数器功能区域 -->
<div class="input-num">
<button @click="sub"> - </button>
<span>{{ num }}</span>
<button @click="add"> + </button>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app", /* 绑定元素id */
data:{
num:1
},
methods:{
/* 加逻辑 */
add:function (){
// console.log("add");
if(this.num < 10){
this.num++;
} else{
alert("已到达最大值!");
}
},
/* 减逻辑 */
sub:function (){
// console.log("sub");
if(this.num > 0){
this.num--;
} else{
alert("已到达最小值!");
}
}
}
})
</script>
</body>
</html>
2.5、v-show
v-show 指令的作用是:根据真假切换元素的显示状
原理是修改元素的 display,实现显示隐藏
指令后面的内容,最终都会解析为布尔值
值为 true 的元素显示,值为 false 的元素隐藏
数据改变之后,对应元素的显示状态会同步更新
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>v-show</title>
</head>
<body>
<div id="app">
<img v-show="isShow" src="./img/a.jpg">
<img v-show="age>=18" src="./img/a.jpg">
<input type="button" value="切换显示状态" @click="changeIsShow">
<input type="button" value="累加年龄" @click="addAge">
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data:{
isShow:true,
age:17
},
methods:{
changeIsShow:function (){
this.isShow = !this.isShow;
},
addAge:function (){
this.age++;
}
}
})
</script>
</body>
</html>
2.6、v-if
v-if 指令的作用是:根据表达式的真假切换元素的显示状态
本质是通过操纵 dom 元素来切换显示状态
表达式的值为 true,元素存在于 dom 树中,为 false,从 dom 树中移除
频繁的切换 v-show,反之使用v-if,前者的切换消耗小
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>v-if</title>
</head>
<body>
<div id="app">
<p v-if="isShow">你好 v-if</p> <br>
<p v-show="isShow">你好 v-show</p> <br>
<input type="button" value="切换显示" @click="toggleIsShow"> <br>
<h2 v-if="temperature>=35">热成狗</h2>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
isShow:false,
temperature:40
},
methods:{
toggleIsShow:function (){
this.isShow = !this.isShow;
}
}
})
</script>
</body>
</html>
2.7、v-bind
v-bind 指令的作用是:为元素绑定属性
完整写法是 v-bind:属性名
简写的话可以直接省略v-bind,只保留:属性名
需要动态的增删 class 建议使用对象的方式
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>第一个vue程序</title>
<style>
.active{
border: 1px solid red;
}
</style>
</head>
<body>
<div id="app">
<img v-bind:src="imgSrc">
<br>
<!-- title属性设置鼠标移到图片上时,会显示title内的内容 -->
<img :src="imgSrc" :title="imgTitle + '!!!'" :class="isActive ? 'active' : ''" @click=toggleActive>
<br>
<!-- 上面的写法和下面的结果相同 -->
<img :src="imgSrc" :title="imgTitle + '!!!'" :class="{active:isActive}" @click=toggleActive>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
imgSrc:"img/a.jpg", /* 根目录为src */
imgTitle:"打工人",
isActive:false
},
methods:{
toggleActive:function (){
this.isActive = !this.isActive;
}
}
})
</script>
</body>
</html>
2.8、案例 —— 图片切换
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>图片切换</title>
</head>
<body>
<div id="app">
<!-- 图片 -->
<img :src="imgArr[index]">
<br>
<!-- javascript:void(0)可以使超链接不链接到任何地址 -->
<a href="javascript:void(0)" @click="prev" v-show="index!=0">上一张</a>
<a href="javascript:void(0)" @click="next" v-if="index<imgArr.length-1">下一张</a>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
imgArr:[
"./img/00.jpg",
"./img/01.jpg",
"./img/02.jpg",
"./img/03.jpg",
"./img/04.jpg",
"./img/05.jpg",
"./img/06.jpg",
"./img/07.jpg",
"./img/08.jpg",
"./img/09.jpg",
"./img/10.jpg"
],
index:0
},
methods:{
prev:function (){
if(this.index > 0){
this.index--;
}
},
next:function (){
if(this.index < 10){
this.index++;
}
}
}
})
</script>
</body>
</html>
2.9、v-for
v-for 指令的作用是:根据数据生成列表结构
数组经常和 v-for 结合使用
语法是 (item,index) in 数据
item 和 index 可以结合其他指令一起使用
数组长度的更新会同步到页面上,是响应式的
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>v-for</title>
</head>
<body>
<div id="app">
<ul>
<!-- index从0开始 -->
<li v-for="(item,index) in arr">
序号{{ index+1 }}:{{ item }}
</li>
</ul>
<input type="button" value="添加" @click="add1">
<input type="button" value="移除" @click="remove1">
<h2 v-for="item in food" :title="item.name">
{{ item.name }}
</h2>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
arr:["一","二","三","四"],
food:[
{name:"炒饭"},
{name:"炒面"}
]
},
methods:{
add1:function (){
this.food.push({ name:"炒米粉" })
},
remove1:function (){
this.food.shift(); /* 移除数组最左边的元素,即第一个元素 */
}
}
})
</script>
</body>
</html>
2.10、v-model
v-model 指令的作用是便捷的设置和获取表单元素的值
绑定的数据会和表单元素值相关联
绑定的数据 ←→ 表单元素的值
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>第一个vue程序</title>
</head>
<body>
<div id="app">
<input type="text" v-model="message" @keyup.enter="getM">
<!-- 将message的内容显示,证明v-model的双向改变 -->
<h2>{{ message }}</h2>
<input type="button" value="修改" @click="setM">
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
message: "你好,vue"
},
methods:{
getM:function (){
alert(this.message);
},
setM:function (){
this.message = "giao";
}
}
})
</script>
</body>
</html>
2.11、案例 —— 记事本
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>记事本</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta name="robots" content="noindex, nofollow"/>
<meta name="googlebot" content="noindex, nofollow"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" type="text/css" href="./css/index.css"/>
</head>
<body>
<!-- 主体区域 -->
<section id="todoapp">
<!-- 输入框 -->
<header class="header">
<h1>记事本</h1>
<!-- placeholder 属性规定可描述输入字段预期值的简短的提示信息 -->
<input v-model="inputValue" @keyup.enter="add" autofocus="autofocus" autocomplete="off" placeholder="请输入任务"
class="new-todo"/>
</header>
<!-- 列表区域 -->
<section class="main">
<ul class="todo-list">
<li class="todo" v-for="(item,index) in list">
<div class="view">
<span class="index">{{ index + 1 }}.</span>
<label>{{ item }}</label>
<button class="destroy" @click="remove(index)"></button>
</div>
</li>
</ul>
</section>
<!-- 统计和清空 -->
<footer class="footer">
<span class="todo-count" v-if="list.length!=0">
<strong>{{ list.length }}</strong> items left
</span>
<!-- 清空数组 -->
<button class="clear-completed" @click="clear" v-if="list.length!=0">
Clear
</button>
</footer>
</section>
<!-- 底部 -->
<footer class="info">
<p>
<a href="http://www.itheima.com/"><img src="./img/black.png" alt=""/></a>
</p>
</footer>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#todoapp",
data: {
list: ["写代码", "吃饭饭", "睡觉觉"],
inputValue: ""
},
methods: {
/* 将inputValue添加到列表中 */
add: function () {
this.list.push(this.inputValue);
},
remove: function (index) {
console.log("删除");
console.log(index);
this.list.splice(index, 1); /* 删除起始下标为index,个数为1的元素 */
},
clear:function (){
this.list = [];
}
}
})
</script>
</body>
</html>
3、Vue 生命周期
生命周期的八个阶段:每触发一个生命周期事件,会自动执行一个生命周期方法
mounted:挂载完成,Vue初始化成功,HTML页面渲染成功。发送异步请求,加载数据。
4、网络应用
4.1、axios
官方地址:GitHub - axios/axios: Promise based HTTP client for the browser and node.js
axios 基本格式:
axios.get(地址?key=value&key2=values).then(function(response){},function(err){})
axios.post(地址,{key:value,key2:value2}).then(function(response){},function(err){})
4.1.1、axios 基本使用
axios 必须先导入才可以使用
使用 get 或 post 方法即可发送对应的请求
then 方法中的回调函数会在请求成功或失败时触发
通过回调函数的形参可以获取响应内容,或错误信息
① 引入 axios
<!-- 官网提供的axios在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
② 测试
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>axios基本使用</title>
</head>
<body>
<!-- 官网提供的axios在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<input type="button" value="get请求" class="get">
<input type="button" value="post请求" class="post">
<script type="text/javascript">
/*
接口1:随机笑话
请求地址:https://autumnfish.cn/api/joke/list
请求方法:get
请求参数:num(笑话条数,数字)
响应内容:随机笑话
*/
document.querySelector(".get").onclick = function () {
axios.get("https://autumnfish.cn/api/joke/list?num=6") // 正确地址
// axios.get("https://autumnfish.cn/api/joke/list123?num=6") // 错误地址
.then(function (response) {
console.log(response);
}), function (err) {
console.log(err);
}
}
/*
接口2:用户注册
请求地址:https://autumnfish.cn/api/user/reg
请求方法:post
请求参数:username(用户名,字符串)
响应内容:注册成功或失败
*/
document.querySelector(".post").onclick = function (){
axios.post("https://autumnfish.cn/api/user/reg",{username:"giao"})
//axios.post("https://autumnfis123h.cn/api/user/reg",{username:"giao"}) //错误地址
.then(function (response){
console.log(response);
}),function (err){
console.log(err);
}
}
</script>
</body>
</html>
4.1.2、axios + vue
axios 回调函数中的 this 已经改变,无法访问到 data 中数据, 把 this 保存起来,回调函数中直接使用保存的 this 即可
和本地应用的最大区别就是改变了数据来源
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>axios+vue</title>
</head>
<body>
<div id="app">
<input type="button" value="获取笑话" @click="getJoke">
<p> {{ joke }} </p>
</div>
<!-- 官网提供的axios在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script type="text/javascript">
/*
接口:随机笑话
请求地址:https://autumnfish.cn/api/joke
请求方法:get
请求参数:无
响应内容:随机笑话
*/
var app = new Vue({
el:"#app",
data:{
joke:"这是一个笑话"
},
methods:{
getJoke:function (){
console.log(this.joke);
var that = this;
axios.get("https://autumnfish.cn/api/joke")
.then(function (response){
// console.log(response.data);
// axios回调函数中的this已经改变,无法访问到data中数据
// console.log(this.joke);
that.joke = response.data;
},function (err){
console.log(err);
})
}
}
})
</script>
</body>
</html>
4.2、案例 —— 天气预报
main.js
/*
请求地址:http://wthrcdn.etouch.cn/weather_mini
请求方法:get
请求参数:city(城市名)
响应内容:天气信息
1. 点击回车
2. 查询数据
3. 渲染数据
*/
var app = new Vue({
el:"#app",
data:{
city:'',
weatherList:[]
},
methods: {
searchWeather:function (){
// console.log('天气查询');
// console.log(this.city);
// 调用接口
var that = this;
axios.get("http://wthrcdn.etouch.cn/weather_mini?city="+this.city)
.then(function (response){
// console.log(response);
// console.log(response.data.data.forecast);
that.weatherList = response.data.data.forecast;
})
.catch(function (err){
})
},
changeCity:function (city){
this.city = city;
this.searchWeather();
}
},
})
天气预报.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>天知道</title>
<link rel="stylesheet" href="css/reset.css" />
<link rel="stylesheet" href="css/index.css" />
</head>
<body>
<div class="wrap" id="app">
<div class="search_form">
<div class="logo"><img src="img/logo.png" alt="logo" /></div>
<div class="form_group">
<input type="text" class="input_txt" placeholder="请输入查询的天气" @keyup.enter="searchWeather" v-model="city"/>
<button class="input_sub" @click="searchWeather">
搜 索
</button>
</div>
<div class="hotkey">
<!-- href="javascript:;":让超链接去执行js函数,点击此超链接时,页面不会进行任何操作,防止跳到其他页面 -->
<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 weatherList">
<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>
<!-- 官网提供的axios在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- 导入自己的js -->
<script src="./js/main.js"></script>
</body>
</html>
5、综合案例 —— 音乐播放器
main.js
/*
1:歌曲搜索接口
请求地址:https://autumnfish.cn/search
请求方法:get
请求参数:keywords(查询关键字)
响应内容:歌曲搜索结果
2:歌曲url获取接口
请求地址:https://autumnfish.cn/song/url
请求方法:get
请求参数:id(歌曲id)
响应内容:歌曲url地址
3.歌曲详情获取
请求地址:https://autumnfish.cn/song/detail
请求方法:get
请求参数:ids(歌曲id)
响应内容:歌曲详情(包括封面信息)
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:[],
// 动画播放状态
isPlay:false,
// 遮罩层的显示状态
isShow:false,
// mv地址
mvUrl:""
},
methods:{
searchMusic:function (){
var that = this;
axios.get("https://autumnfish.cn/search?keywords=" + this.query)
.then(function (response){
console.log(response);
that.musicList = response.data.result.songs;
}, function (err){})
},
playMusic:function (musicId){
// console.log(musicId);
var that = this;
// 获取歌曲地址
axios.get("https://autumnfish.cn/song/url?id=" + musicId)
.then(function (response){
that.musicUrl = response.data.data[0].url;
}, function (err){});
// 获取歌曲详情
axios.get("https://autumnfish.cn/song/detail?ids=" + musicId)
.then(function (response){
that.musicCover = response.data.songs[0].al.picUrl;
}, function (err){});
// 歌曲评论获取
axios.get("https://autumnfish.cn/comment/hot?type=0&id=" + musicId)
.then(function (response){
that.hotComments = response.data.hotComments;
}, function (err){})
},
play:function (){
// console.log("play");
this.isPlay = true;
},
pause:function (){
// console.log("pause");
this.isPlay = false;
},
playMv:function (mvid){
var that = this;
axios.get("https://autumnfish.cn/mv/url?id=" + mvid)
.then(function (response){
that.mvUrl = response.data.data.url;
that.isShow = true;
}, function (err){})
},
// 隐藏遮罩层
hide:function (){
this.isShow = false;
}
}
})
音乐播放器.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>悦听player</title>
<!-- 样式 -->
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div class="wrap">
<!-- 播放器主体区域 -->
<div class="play_wrap" id="player">
<div class="search_bar">
<img src="images/player_title.png" alt="" />
<!-- 搜索歌曲 -->
<input type="text" autocomplete="off" 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="playMv(item.mvid)"><i></i></span>
</li>
</ul>
<img src="images/line.png" class="switch_btn" alt="">
</div>
<!-- 歌曲信息容器 -->
<div class="player_con" :class="{playing:isPlay}">
<img src="images/player_bar.png" class="play_bar" />
<!-- 黑胶碟片 -->
<img src="images/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=""></dt>
<dd class="name">{{ item.user.nickname }}</dd>
<dd class="detail">
{{item.content}}
</dd>
</dl>
</div>
<img src="images/line.png" class="right_line">
</div>
</div>
<div class="audio_con">
<audio ref='audio' :src="musicUrl" @play="play" @pause="pause" controls autoplay loop class="myaudio"></audio>
</div>
<div class="video_con" style="display: none;" v-show="isShow">
<video :src="mvUrl" controls="controls"></video>
<div class="mask" @click="hide"></div>
</div>
</div>
</div>
<!-- 官网提供的axios在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- 导入自己的js -->
<script src="./js/main.js"></script>
</body>
</html>