目录
Vue官方:
两种cdn:第一种有提示,第二种速度较快但是无提示
如何跑起来第一个程序
Vue挂载点和data对象
1、Vue会管理el选项命中的元素以及子代的元素
2、可以,只不过class,标签选择器容易造成语意不清晰,毕竟范围较大
3、可以,不过只支持双标签,并且html和body标签是不支持的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app" class="bpp">
{{message}}
<!-- 只能支持双标签-->
<span>
<!-- 可以发现el嵌套的元素内部,也会被data管理-->
{{message}}
</span>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app=new Vue({
//class选择器,id选择器,标签选择器:标签和class选择器会造成语意不清晰,毕竟范围较大
el:".bpp",
el:"#app",
el:"div",
data:{
message:"黑马程序员"
}
})
</script>
</body>
</html>
<body>
<div id="app">
{{message}}
<h2>{{school.name}} {{school.mobile}}</h2>
<ul>
<li>{{campus[0]}}</li>
<li>{{campus[1]}}</li>
</ul>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app=new Vue({
el:"#app",
data:{
message:"你好,Fairy同学!",
school:{
name:"长沙理工大学",
mobile:"110"
},
//数组元素
campus:["北京","上海","广州","深圳"]
}
})
</script>
</body>
v-text:会替换标签内的内容,但是你可以字符串拼接
<body>
<div id="app">
<!-- v-text会替换标签里面的内容-->
<h2 v-text="message+'!'"></h2>
<h2 v-text="info"></h2>
<h2>{{message}}深圳</h2>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app=new Vue({
el:"#app",
data:{
message:"黑马程序员!!!",
info:"前端与移动教研部"
}
})
</script>
</body>
v-html:
可以设置解析结构,对于普通文本和v-text差不多,但是如果data中的内容含html,他能够起到解析的作用
<body>
<!--html结构-->
<div id="app">
<p v-html="content"></p>
<p v-text="content"></p>
</div>
<p v-html="content"></p>
<p v-text="content"></p>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
//创建vue实例
var app=new Vue({
//只有el作用的元素才能够获得data的内容
el:"#app",
data:{
content:"<a href='http://www.itheima.com'>黑马程序员</a>"
}
})
</script>
</body>
v-text用于文本,v-html除了解析文本还可以解析html
v-on
为元素绑定事件,可以用@代替v-on
绑定的方法放在methods中
方法名与v-on/@绑定的方法名需一致
<body>
<div id="app">
<!-- 点击绑定doIt事件-->
<input type="button" value="v-on指令" v-on:click="doIt">
<input type="button" value="双击事件" @dbclick="doIt">
<!-- 一开始显示data中的food,当点击时,触发绑定事件-->
<h2 @click="changeFood">{{food}}</h2>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app=new Vue({
el:"#app",
// 设置元素,进行初始化
data:{
food:"西红柿炒蛋",
},
methods:{
//设置事件
doIt:function (){
alert("欢迎Fairy同学");
},
changeFood:function (){
//打印food
console.log(this.food);
this.food+="还不错"
}
},
})
</script>
</body>
综合应用:计数器
1、两边为button,用v-on绑定methods中的方法——>v-on绑定给+-;
2、然后中间的值用v-text表示文本——>绑定的元素给到span标签
3、>10和<10会提示
<body>
<div id="app">
<!--计数器功能区域-->
<div class="input-num">
<!-- button绑定sub事件,点击触发-->
<button @click="sub">
-
</button>
<span>{{num}}</span>
<button @click="add">
+
</button>
<img src="http://www.ithema.com/images/logo.png" alt=""/>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
//创建vue实例
var app = new Vue({
el:"#app",//元素绑定
data:{
num:1
},
//绑定方法
methods:{
add:function () {
if(this.num<10){
this.num++;//点击后触发事件,事件逻辑num+1
}
alert("别点啦,最大了")
},
sub:function () {
if(this.num>0){
this.num--;
}
alert("别点啦,最小了")
}
},
});
</script>
</body>
v-show
根据表达式值的真假与条件,来切换元素的显示和隐藏
<body>
<div id="app">
<!-- 当点击按钮v-on,触发changIsShow事件-->
<input type="button" value="切换显示状态" @click="changeIsShow">
<input type="button" value="累加年龄" @click="addAge">
<!-- 绑定v-show,状态看isShow(设置一个按钮切换装态)-->
<p v-show="isShow">我喜欢你</p>
<p v-show="age>18">可以谈爱</p>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
//实例Vue
var app = new Vue({
el:"#app",//挂载到id=app的div标签上
data:{
isShow:false,
age:17
},
methods:{
changeIsShow:function () {
this.isShow=!this.isShow;
},
addAge:function () {
this.age++;
}
}
});
</script>
</body>
v-if
跟v-show类似,但是v-if更依赖于条件,条件满足就怎么怎么样
<body>
<div id="app">
<input type="button" @click="toggleIsShow" value="切换显示">
<p v-if="isShow">Fairy同学,你好</p>
<!-- 这里区分v-if与v-show-->
<p v-show="isShow">Fairy同学,你的女朋友呢?</p>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
isShow:false
},
methods:{
//定义一个方法,当触发时,切换状态
toggleIshow:function () {
this.isShow=!this.isShow;
}
}
});
</script>
</body>
v-if与v-show的区分:前者是操作DOM元素,而后者是操作样式style;
v-bind
为元素绑定属性
v-bind:属性名
1、首先用v-bind:src=xxx绑定src元素属性值
2、添加一个class样式在style中.class{xxx},然后再在methods添加方法事件,再在图片中添加:class进行判断(用三元表达式),如果true就active显示,然后状态的切换需要v-on(@)="事件"进行切换;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
.active{
border: 1px solid red;
}
</style>
<body>
<div id="app">
<!-- 利用v-bind绑定src路径
并且利用挂载的isActive属性进行判断是否加上class(那么isActive状态切换还需要绑定事件)-->
<img v-bind:src="imgSrc" alt="" v-bind:title="imageTitle+'!!!'"
:class="isActive?'active':''"@click="toggleActive"/>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
//设置挂载元素
el:"#app",
data:{
imgSrc:"http://www/itheima.com/images/logo.png",
imgTitle:"黑马程序员",
isActive:false
},
//绑定一些方法,改变isActive状态
methods:{
toggleActive:function () {
this.isActive=!this.isActive;
}
},
});
</script>
</body>
</html>
案例:图片切换
v-if:判断是否满足条件,若不满足就移除DOM元素;
v-show:与上述类似,只不过是样式的移除,消耗肯定比v-if小;
v-on/@事件:可以绑定methods中的方法,一般数据状态改变大多用这个;
还有就是el挂载的地方要注意,这样data中的元素就可以赋值上去;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div id="mask">
<div class="center">
<h2 class="title">
<img src="./images/logo.png"alt="">
深圳创维校区
</h2>
<!-- 图片-->
<img src="imgArr[index]" alt="">
<!-- 左箭头,逻辑:v-if中index!=0则显示箭头,否则隐藏-->
<a href="javascript:void(0)" v-if="index!=0" @click="prev" class="left">
<img src="./images/prev.png">
</a>
<!-- 右箭头-->
<a href="javascript:void(0)" v-show="index<imgArr.length-1" @click="next" class="right">
<img src="images/next.png">
</a>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
//挂载
el:"#mask",
data:{
imgArr:[
"./images/00.jpg",
"./images/01.jpg",
"./images/02.jpg",
"./images/03.jpg",
"./images/04.jpg",
"./images/05.jpg",
"./images/06.jpg",
"./images/07.jpg",
"./images/08.jpg",
"./images/09.jpg",
],
//下标属性,方便变化数组下标
index:0
},
methods:{
prev:function () {
this.index--;
},
next:function () {
this.index++;
}
}
});
</script>
</body>
</html>
v-for
根据数据生成列表结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="button" value="添加数据" @click="add">
<input type="button" value="删除数据" @click="remove">
<ul>
<!-- addr是下面被挂载元素中的data的其中之一元素,这里将其遍历 -->
<li v-for="addr in arr">
{{addr}}
</li>
<!-- 输出vegatables中的每一个菜,并且通过v-bind:title绑定标题-->
<li v-for="food in vegatables" v-bind:title="food">
{{food.name}}
</li>
</ul>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
// 挂载元素
el:"#app",
data:{
arr:["北京","上海","广州","深圳"],
vegatables:[
{name:"西红柿炒蛋"},
{name:"辣椒炒肉"}
],
//添加和删除方法
methods:{
add:function () {
this.vegatables.push({name:"红萝卜炒肉"});
},
remove:function () {
this.vegatables.shift();
}
},
}
});
</script>
</body>
</html>
v-on指令补充
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- //v-on/@绑定事件方法,并且传入参数-->
<input type="button" value="点击" @click="doIt(666,'老铁')">
<!-- 事件修饰符,回车才会触发methods中的方法-->
<input type="text" placeholder="请输入用户名" @keyup.enter="sayHi">
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
//挂载
el:"#app",
data:{
},
methods:{
//前端传入形参p1
doIt:function (p1,p2) {
console.log(p1);
console.log(p2);
},
sayHi:function () {
alert("吃饭没? ");
}
},
});
</script>
</body>
</html>
v-model指令
获取前端输入内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>双向数据绑定</title>
</head>
<body>
<div id="app">
<!-- v-model绑定下面data中的message,可以进行更改,更改后的值是双向的
当回车后,会alert值-->
<input type="text" v-model="message" @keyup.enter="get">
<input type="submit" value="修改message" @click="set">
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
message:"黑马程序员"
},
methods:{
get:function () {
alert(this.message);
},
//改变message
set:function () {
this.message="酷丁鱼";
}
},
});
</script>
</body>
</html>
案例:记事本
新增:
<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>
<!-- v-model在输入框中双向绑定,这个inputvalue是默认的,可以双向修改
设置@keyup.enter=xxx,当回车后触发xxx方法-->
<input v-model="inputValue" @Keyup.enter="add" autofocus="autofocus" autocomplete="off" placeholder="请输入任务"
class="new-todo" />
</header>
<!-- 列表区域 -->
<section class="main">
<ul class="todo-list">
<!-- item,index分别为数组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"></button>
</div>
</li>
</ul>
</section>
<!-- 统计和清空 -->
<footer class="footer" >
<span class="todo-count">
<strong>1</strong> items left
</span>
<button class="clear-completed">
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:{
//增加方法,输入框输入数据后回车,将输入内容增加到数组中
add:function () {
this.list.push(this.inputValue);
}
}
});
</script>
</body>
</html>
删除
<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>
<!-- v-model在输入框中双向绑定,这个inputvalue是默认的,可以双向修改
设置@keyup.enter=xxx,当回车后触发xxx方法-->
<input v-model="inputValue" @Keyup.enter="add" autofocus="autofocus" autocomplete="off" placeholder="请输入任务"
class="new-todo" />
</header>
<!-- 列表区域 -->
<section class="main">
<ul class="todo-list">
<!-- item,index分别为数组list中的值以及对应索引,v-for是双向数据绑定的,既然index是索引
那么我们下面也可以直接调用-->
<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">
<strong>1</strong> items left
</span>
<button class="clear-completed">
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:{
//增加方法,输入框输入数据后回车,将输入内容增加到数组中
add:function () {
this.list.push(this.inputValue);
},
remove:function (index) {
console.log("删除成功");
console.log(index);
//当点击上面那个删除的button时,list数组删除当前点击的下标元素
this.list.splice(index,1);//index意思点谁删谁,1代表一次删一个
}
},
});
</script>
</body>
</html>
隐藏
<span class="todo-count" v-if="list.length!=0">
<strong>{{list.length}}</strong> items left
</span>
网络应用-axios
例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="button" value="post请求" class="post">
<input type="button" value="get请求" class="get">
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
//获取单个元素
document.querySelector(".get").onclik=function () {
//获取单个元素后点击触发事件,axios获得路径(这里由服务器处理),然后then获取响应给到前端
axios.get("https://autumnfish.cn/api/joke/list?num=6")
.then(function (response) {//响应正确信息
alert(response);
console.log(response)
},function (err) {
alert(err);//响应错误信息
})
}
document.querySelector(".post").onclick=function () {
axios.post("https://autumnfish.cn/api/user/reg",{username:"Fairy同学"})
.then(function (response) {
alert(response)
})
}
</script>
</body>
</html>
axios+Vue
注意axios.get()请求后.then()响应的数据(response.data)已经不在this范围中,所以我们可以利用中间变量来赋值,改变el挂载元素的属性(就是上面那个data中的属性)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="button" value="获取笑话" @click="getJoke">
<p>{{joke}}</p>
</div>
<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>
/*利用axios请求接口获取响应response的笑话
请求方法为get
* */
var app = new Vue({
//设置挂载元素
el:"#app",
data:{
joke:"获得一个很好笑的笑话",
},
methods:{
getJoke:function () {
//因为当数据响应时,服务器响应的数据已经不在this的范围内了
// ,所以我们要把this给一个变量,然后这个中间变量帮我们获取响应数据
var that=this;
axios.get("https://autumnfish.cn/api/joke").then(
function (response) {
//因为this的内容赋给了that,所以我们修改that中的数据即可
console.log(response);
that.joke=response.data;
}
)
}
}
});
</script>
</body>
</html>
查询天气
两个功能:
1.输入城市回车查询
2.点击列表查询
按下回车事件:v-on/@ .enter
查询数据:axios获取api中的内容,并返回数据,v-model:数据绑定
渲染数据:v-for将数据展示到列表
代码
<!DOCTYPE html>
<html lang="en">
<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">
<!-- v-model拿到js中挂载的data中的元素,@key.enter绑定methods中的方法-->
<input type="text" v-model="city" @keyup.enter="searchWeather" class="input_txt" placeholder="请输入查询的天气"/>
<button class="input_sub">
搜 索
</button>
</div>
<div class="hotkey">
<!-- 当点击触发changeCity方法,此时挂载的data属性city发生修改,因为上面v-model的原因
city发生改变,上面也会发生变化,所以input栏里面发生变化
并且还会触发searchWeather方法:服务器根据city返回响应内容-->
<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>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 官网提供的 axios 在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 自己的js -->
<script src="./js/main.js"></script>
</body>
</html>
JS
/*
请求地址:http://wthrcdn.etouch.cn/weather_mini
请求方法:get
请求参数:city(城市名)
响应内容:天气信息
1. 点击回车
2. 查询数据
3. 渲染数据
*/
var app = new Vue({
el:"#app",
data:{
city:'',
weatherList:[]
},
methods:{
searchWeather:function () {
//设置中间变量以便获取服务器返回的内容
var that=this;
// console.log('天气查询');
//当输入栏回车触发searchweather方法,v-model会将数据给到data中的city(这是与之对应的)
//然后通过this.city将当前城市进行查询,通过then()方法,服务器将数据返回
axios.get('http://wthrcdn.etouch.cn/weather_mini?city='+this.city)
.then(function (response) {
// console.log(response)
//将服务器响应的数据赋值给中间变量
that.weatherList=response.data.data.forecast
})
},
changeCity:function (city) {
this.city=city;
this.searchWeather();
}
},
});
案例:播放器
v-for:v-for="xxx in 挂载的元素属性" 以便遍历服务器返回的数据
v-model:前台输入的数据与后台进行绑定,当输入数据后台可以根据你输入的数据进行方法操作
这里我们一般在输入框input中结合v-on/@一起使用
所有歌曲展示
歌曲
封面
html:
<!DOCTYPE html>
<html lang="en">
<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">
<!-- 利用v-for遍历挂载属性中的musiclist-->
<li v-for="item in musiclist">
<!-- 点击歌曲触发methods中的方法playMusic,并将item.id传入-->
<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:isPlaying}">
<img src="images/player_bar.png" class="play_bar" />
<!-- 黑胶碟片 -->
<img src="images/disc.png" class="disc autoRotate" />
<img v-bind: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 v-bind:src="item.user.avatarUrl" alt=""></dt>
<!-- 用户昵称item.nickname-->
<dd class="name">{{ item.nickname}}</dd>
<dd class="detail">
{{ item.content }}
</dd>
</dl>
</div>
<img src="images/line.png" class="right_line">
</div>
</div>
<div class="audio_con">
<!-- v-bind:src绑定路径-->
<audio ref='audio' @play="play" @pause="pause" v-bind:src="musicUrl" controls autoplay loop class="myaudio"></audio>
</div>
<div class="video_con" v-show="isShow" style="display: none;">
<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>
<!-- 官网提供的 axios 在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="./js/1.js"></script>
</body>
</html>
Vue实现的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: [],
// 动画播放状态
isPlaying: 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;
console.log(response.data.result.songs);
},
function(err) {}
);
},
// 歌曲播放
playMusic: function(musicId) {
// console.log(musicId);
var that = this;
// 根据id获取歌曲地址,如果id存在就function(response){}
axios.get("https://autumnfish.cn/song/url?id=" + musicId).then(
function(response) {
// console.log(response);
// console.log(response.data.data[0].url);
that.musicUrl = response.data.data[0].url;
},
function(err) {}
);
// 歌曲详情获取
axios.get("https://autumnfish.cn/song/detail?ids=" + musicId).then(
function(response) {
// console.log(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);
// console.log(response.data.hotComments);
that.hotComments = response.data.hotComments;
},
function(err) {}
);
},
// 歌曲播放
play: function() {
// console.log("play");
this.isPlaying = true;
},
// 歌曲暂停
pause: function() {
// console.log("pause");
this.isPlaying = false;
},
// 播放mv
playMV: function(mvid) {
var that = this;
axios.get("https://autumnfish.cn/mv/url?id=" + mvid).then(
function(response) {
// console.log(response);
console.log(response.data.data.url);
that.isShow = true;
that.mvUrl = response.data.data.url;
},
function(err) {}
);
},
// 隐藏
hide: function() {
this.isShow = false;
}
}
});