Vue的快速入门

前言

还有不到十天就要开学了,想最后来简单入门一下出名的前端技能点——Vue

 

 

 

 


基础入门

概念

Vue是一个JavaScript框架,就像react一样。

它可以简化Dom操作,并且具有响应式的数据驱动(数据改变后页面更新)。

 

官网

https://cn.vuejs.org/

好好利用vue文档即可。

 

基础使用

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

开发环境版本相对内容较全,适合学习阶段使用(我们将会使用)。

生产环境版本经过压缩速度会更快。

下面我们开始使用示例:

这里打断给大家推荐一个VSCode的插件——live  server,让你的静态页面可以随着保存内容的更改即时更新。

创建一个index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue的学习</title>

</head>
<body>
    <div id="app">
        {{ message }}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app=new Vue({
            el:"#app",
            data:{
                message:"Hello World"
            }
        })
    </script>
</body>
</html>

页面输出:

Hello World

可以看到,我们创建Vue实例对象,构造中传入一个Object对象,设置el属性和data属性,使用简洁的模板语法把数据渲染到页面上。

el挂载点

el是Vue对象起作用的挂载点,通过el选择元素。

只有在el命中的元素内部,data才能起作用。

另外,el不要挂载到html、body标签上。

data数据对象

我们在页面中可以通过{{}}(插值表达式),来得到data中的数据对象:

<body>
    <div id="app">
        {{ message }} <br/>
        <span style="color: aquamarine;">{{ school.name }}</span> 
        <br/>
        <span style="color: rgb(132, 206, 98);">{{ school.mobile }}</span>
         <br/>
        <span style="color: rgb(247, 226, 109);">{{ campus[1] }}</span>
        <br/>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app=new Vue({
            el:"#app",
            data:{
                message:"Hello World",
                school:{
                    name:"六中",
                    mobile:"234234"
                },
                campus:["北京校区","上海校区","深圳校区"]
            }
        })
    </script>
</body>

打印:

Hello World
六中
234234
上海校区

我们可以看到,在data中可以存放基本类型数据外,还可以存放Object类型、数组类型(Array内置类型)等复杂类型

 

Vue指令

Vue指令指的是以v-开头的一组特殊语法。

v-text

设置标签的文本值(textContent)

在表达文本输出的情况下,可以直接使用v-text属性来将Vue对象的内容输出,但是这将是全部内容,不能再添写。

例如我们修改上例:

    <div id="app">
        {{ message }} <br/>
        <span style="color: aquamarine;" v-text="school.name"></span> 
        <br/>
        <span style="color: rgb(132, 206, 98);" v-text="school.mobile"></span>
         <br/>
        <span style="color: rgb(247, 226, 109);" v-text="campus[1]"></span>
        <br/>
    </div>

需要注意:这将是全部内容,不能再添写,即上例中在span内部再加文字将不被显示,如果要部分替换,请使用{{}}表示法。

v-text指令中可以进行字符串的拼接:

<span style="color: aquamarine;" v-text="school.name+'!'"></span> 

打印

六中!

v-html

这个标签是用来设置innerHTML。

了解前端的你应该猜到了,这个就是在标签内部添加内容,需要注意的是,这种innerHTML和text在一般情况下效果相同,但是有的时候就大相庭径。

例如,如果我们使用{{}}(插值表达式)或 v-text (文本指令)来添加内容,例如:

<body>
    <div id="app">
        <span v-text="message"></span> <br/>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app=new Vue({
            el:"#app",
            data:{
                message:"<a href='#'>有意思</a>",
            }
        })
    </script>
</body>

那么将在页面打印:

<a href='#'>有意思</a>

它的a标签将作为文本输出,如果是v-html,效果可就不一样了:

有意思

解析文本使用v-text,需要解析html结构使用v-html。

 

v-on

v-on用来为元素绑定事件,

v-on:事件名="方法名"

方法名是data中的methods下的方法

v-on: 可以直接简写为@

示例:

    <div id="app">
        <span v-html="reload" v-on:click="dolt"></span> <br/>

        <span v-html="alert" @mouseenter="aler"></span> <br/>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app=new Vue({
            el:"#app",
            data:{
                reload:"单机刷新",
                alert:"移过弹窗"
            },
            methods:{
                dolt:function(){
                    location.reload();
                },
                aler:function(){
                    alert("弹窗出现!");
                }
            }
        })
    </script>

常见的事件有:

  1. click
  2. mouseenter
  3. dbclick

有了method,我们就可以对我们的元素进行处理,通过this点出来。

    <div id="app">
        <span v-on:click="changeFood">{{food}}</span> <br/>

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script> 
        var app=new Vue({
            el:"#app",
            data:{
                food:"土豆"
            },
            methods:{
                changeFood:function(){
                    this.food+="加入西红柿";
                }    
            }
        })
    </script>

当我们去点击显示的“土豆”,后面就会跟上“加入西红柿”。

另外,我们还可以给方法设置自定义参数,包括我们还可以使用事件修饰符。

//只回调一次
<span v-on:click.once="changeFood">{{food}}</span> <br/>
//按下回车响应
<input  @keyup.enter="Food">

关于更多事件修饰符可以参考官网

总结一下:

  1. v-on指令的作用是:为元素绑定事件
  2. 事件名不需要写on,例如click
  3. 指令可以简写为@
  4. 绑定的方法定义在methods属性中
  5. 事件绑定的方法写成函数调用的形式,可以传入自定义参数
  6. 事件后面跟上 .修饰符 可以对事件进行限制

 

v-show

根据表达式的真假,切换元素的显示和隐藏

    <div id="app">
        <button @click="changeIsShow" >切换图片状态</button><br/>
        <img src="/image/image.jpg" v-show="isShow"  />
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script> 
        var app=new Vue({
            el:"#app",
            data:{
                isShow:true,
            },
            methods:{
                changeIsShow:function(){
                    this.isShow=!this.isShow;
                }    
            }
        })
    </script>

一点按钮图片消失,再点在出现。

v-show的原理实际是修改元素的display,实现显示隐藏,指令后面的内容都会被解析为布尔值,true则显示、false则隐藏。

 

v-if

根据表达式的真假,切换元素的显示和隐藏(操作DOM元素)

和v-show控制display不同,v-if是控制dom元素。

例如隐藏某元素:v-show会控制display为none来实现隐藏,而v-if是直接将元素从DOM树中移除该元素。

故,处于性能考虑,我们一般在不常切换的情况用v-if,反之用v-show。

 

v-bind

设置元素的属性(比如:src、class、id、value)

设置

    <div id="app">
        <img v-bind:src="imgSrc"  />
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script> 
        var app=new Vue({
            el:"#app",
            data:{
                imgSrc:"/image/image.jpg",
            },
        })
    </script>

这样就设置了src=”/image/image.jpg”。

而设置class一般有两种方式,一种通过三元表达式,一种是封装成一个Object对象

    <div id="app">
        <span v-bind:class="isActive?'active':''">teset</span>
        <span v-bind:class="{active:isActive}">teset</span>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script> 
        var app=new Vue({
            el:"#app",
            data:{
                isActive:true
            },
        })
    </script>

另外,前面的v-bind可以省略,我们可以直接 :class、:src,即可。

总结:

  1. v-bind指令的作用是:为元素绑定属性
  2. 完整写法是 v-bind:属性名
  3. 简写的话可以直接省略 v-bind,只保留 :属性名

 

中场案例

我们来利用目前所学来做一个简单的中场案例:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue的学习</title>

    <style>
        .left{
            float: left;
        }
        .right{
            float: right;
        }
    </style>
</head>
<body bgcolor="#bbccaa">
    <div id="app" style="text-align:center;margin: 10%">
        <img v-bind:src="imgArr[index]" style="width:340px;height: 260px;"/>
        <div class="left">
            <a href="#" v-on:click="prev"  v-show="index>0">上一张</a>
        </div>
        <div class="right">
            <a href="#" v-on:click="next"  v-show="index<imgArr.length-1">下一张</a>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script> 
        var app=new Vue({
            el:"#app",
            data:{
                imgArr: [ "./image/1.jpg",
                          "./image/2.jpg",
                          "./image/3.jpg" ],
                index:0,
            }, 
            methods:{
                prev:function(){
                    this.index--;
                },
                next:function(){
                    this.index++;
                }
            }
        })
    </script>
</body>
</html>

 

v-for

遍历数组对象

    <div id="app">
        <ul>
            <li v-for="item in arr">数组内部内容:{{item}}</li>
        </ul>
        <ul>
            <li v-for="(item,index) in arr">数组下标是{{index}}的内容:{{item}}</li>
        </ul>
        <ul>
            <li v-for="(item,index) in objArr">对象数组中{{item.name}}下标为{{index}}</li>
        </ul>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script> 
        var app=new Vue({
            el:"#app",
            data:{
                arr:[1,2,3,4,5,"可爱",7],
                objArr:[
                    {name:"西红柿"},
                    {name:"土豆"},
                    {name:"鸡蛋"}
                ]
            }, 
        })
    </script>
  • 数组内部内容:1
  • 数组内部内容:2
  • 数组内部内容:3
  • 数组内部内容:4
  • 数组内部内容:5
  • 数组内部内容:可爱
  • 数组内部内容:7
  • 数组下标是0的内容:1
  • 数组下标是1的内容:2
  • 数组下标是2的内容:3
  • 数组下标是3的内容:4
  • 数组下标是4的内容:5
  • 数组下标是5的内容:可爱
  • 数组下标是6的内容:7
  • 对象数组中西红柿下标为0
  • 对象数组中土豆下标为1
  • 对象数组中鸡蛋下标为2

这个并不难理解,我们使用 (item,index)   in   数据 ,来实现数据的遍历。

 

v-model

获取和设置表单元素的值(双向数据绑定)

双向意指你修改表单中value或js中Vue对象的value,他们都会互相更新。

    <div id="app">
        <input type="text" v-model="message">
        <h2>{{message}}</h2>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script> 
        var app=new Vue({
            el:"#app",
            data:{
                message:"我是蝙蝠侠"
            }
        })
    </script>

 

 


三大入门案例

list 记事本

需求

我们的第一个小项目是一个记事本,可以满足基本的记录事件、增加、统计、删除、清空等功能。

我们的静态页面模板如下:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue的学习</title>
    <style>
        body{
            background-image: url("https://images4.alphacoders.com/193/19334.jpg");
            background-size: cover;
        }
        #todoapp{
            text-align: center;
            margin-top: 5%;
            margin-left: 25%;
            margin-right: 25%;

            padding:3%;

            background-color: rgb(198, 223, 255);
            
            border-radius: 5%;
        }
        h1{
            color: darkred;
            font-size: 40px;
        }
        #inputBox{
            margin-left: 5%;
            width:90%;
            height: 40px;
            border: 1px double rgb(255, 229, 80);
            border-radius: 10%;
        }
        .info{
            text-align: center;
        }
        .todo-list{
            list-style: none;
        }
        .index{
            color:rgb(189, 0, 0);
            font-size: 140%;

            margin-right: 2%;
        }
        .view{
            text-align: left;
        }
        .destroy{
            float:right;
            height: 30px;
            width:6%;
            background-image: url("https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcT3yJ4ckedGT9WZWCo1JLU4bgP1sDjXZ3YmYw&usqp=CAU");
            background-size: cover;

            border-radius: 35%;
        }
        .destroy:hover{
            border-radius: 75%;
        }
        .todo{
            margin: 1%;
            padding: 2%;
            background-color: rgb(209, 238, 238);
        }
        .todo:hover{
            background-color: rgb(169, 211, 211); 
        }
    </style>
</head>
<body>
    <!--主体区域-->
    <section id="todoapp">
        <!--输入框-->
        <header class="header">
            <h1>list 记事本</h1>
            <input autofocus="autofocus" autocomplete="off" placeholder="请输入事件" id="inputBox">
        </header>
        <!--列表区域-->
        <section >
            <ul class="todo-list">
                <li  class="todo">
                    <div class="view">
                        <span class="index"></span>
                        <label></label>
                        <button class="destroy">X</button>
                    </div>
                </li>
            </ul>
        </section>
        <!--统计和清空-->
        <footer>
        </footer>
    </section>
    <!--底部-->
    <footer class="info">
        <img src="https://static.alphacoders.com/alpha_system_360.png"
        style="width: 12%;"/>
    </footer>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

 

实现:新增

步骤:

  1. 生成列表结构(v-for数组)
  2. 获取用户输入(v-model)
  3. 回车,新增数据(v-on.enter 添加数据)
var app=new Vue({
    el:"#todoapp",
    data:{
        list:["吃饭","喝水","睡觉"],
        inputValue:"好好学习,天天向上"
    },
    methods:{
        add:function(){
            this.list.push(this.inputValue);
            this.inputValue="";
        }
    }
})
    <!--主体区域-->
    <section id="todoapp">
        <!--输入框-->
        <header class="header">
            <h1>list 记事本</h1>
            <input autofocus="autofocus" v-model="inputValue" @keydown.enter="add"
            autocomplete="off" placeholder="请输入事件" id="inputBox">
        </header>
        <!--列表区域-->
        <section >
            <ul class="todo-list">
                <li v-for="(item,index) in list" class="todo">
                    <div class="view">
                        <span class="index">{{ index+1 }}.</span>
                        <label>{{ item }}</label>
                        <button class="destroy">X</button>
                    </div>
                </li>
            </ul>
        </section>
        <!--统计和清空-->
        <footer>
        </footer>
    </section>

实现:删除

        remove:function(index){
            this.list.splice(index,1);
        }
                    <div class="view">
                        <span class="index">{{ index+1 }}.</span>
                        <label>{{ item }}</label>
                        <button class="destroy" @click="remove(index)">X</button>
                    </div>

实现:统计和删除

        <!--统计和清空-->
        <footer>
            <span style="float:left;color: red;">统计:{{list.length}}</span>
            <button class="destroy" @click="clear">clear</button>
        </footer>
        clear:function(){
            this.list=[];
        }

实现:隐藏

实现没有数据的时候隐藏相关信息

        <footer v-show="list.length>0">
            <span style="float:left;color: red;">统计:{{list.length}}</span>
            <button class="destroy" @click="clear">clear</button>
        </footer>

添加一个条件:list.length大于0即可。

效果展示

 

对axios的学习

axios是一种对ajax技术的封装技术,可以非常方便的和其他库结合。

这是一个功能强大的网路请求库。

首先,导入:

    <script src="https://unpkg.com/axios@0.20.0/dist/axios.min.js"></script>

学过ajax的人应该不难理解我这里的使用:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue的学习</title>
    <style>
        body{
            background-image: url("https://images5.alphacoders.com/285/thumb-1920-285195.jpg");
            background-size: cover;
        }
        #app{
            text-align: center;
        }
        #post{
            width: 20%;
            height: 40px;
            border-radius:15%;
            background-color: goldenrod;
        }
        #post:hover{
            background-color: rgb(187, 137, 11);   
            cursor: pointer;
        }
        #result-table{
            margin: auto;
            background-color: rgb(0, 0, 0);
            
        }
        .result-tr{
            margin: 5%;
        }
        .result{
            color: rgb(255, 255, 255);
            text-align: left;
        }
    </style>
</head>
<body>
    <div id="app">
        <button class="post" id="post" @click="getWeiboRearch">
            发送一个post请求,来查看微博热搜</button>
        <table id="result-table">
            <tr v-for="(item,index) in list" class="result-tr">
                <td class="result">热搜:{{item.hot_word}}</td>
                <td class="result">热搜度:{{item.hot_word_num}}</td>
            </tr>
        </table>
    </div>

    <script src="https://unpkg.com/axios@0.20.0/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

下面是我们的index.js

var app=new Vue({
    el:"#app",
    data:{
        list:[]
    },
    methods:{
        getWeiboRearch:function(){
            var that=this;
            axios.post("https://v1.alapi.cn/api/new/wbtop",{num:35})
            .then(function(response){
                console.log(response);
                that.list=response.data.data;
            },function(err){
                console.log("程序错误  "+err);
            });
        }
    }
});

有一点我们一定要注意,在我们的Vue对象中的this,和在axios的回调方法中的this是两个东西,并不一样。

我们这里的处理是定义了一个局部变量that,保存了Vue对象中的this,然后在axios的回调中调用它。

另外,其实可以直接在then后面使用箭头函数的形式来调用,这样又是同一个this了

    methods:{
        getWeiboRearch:function(){
            console.log(this);
            axios.post("https://v1.alapi.cn/api/new/wbtop",{num:35})
            .then((response)=>{
                console.log(this);
                this.list=response.data.data;
            },(err)=>{
                console.log("程序错误  "+err);
            });
        }
    }

 

天气预报

需求

了解了axios之后,我们就可以来做这个天气查询系统了。

需求:

  1. 通过输入城市搜索出来对应城市的天气
    1. 回车查询
    2. 点击查询
  2. 有快捷点击城市

访问接口:

  • 请求地址:http://wthrcdn.etouch.cn/weather_mini
  • 请求方式:get
  • 请求参数:city(查询的城市名)
  • 响应内容:天气信息

 

基本模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue的学习</title>
    <style>
        body{
            background-image: url("https://images7.alphacoders.com/306/306617.jpg");
            background-size: cover;   
        }
        #app{
            text-align: center;
            padding-top: 10%;
        }
        #logo-img{
            width: 10%;
            height: auto;
        }
        .input_txt{
            width: 10%;
            height: 30px;
            border-radius: 10%;
            background-color: rgb(242, 242, 248);
        }
        .input_sub{
            width: 5%;
            height: 40px;
            border-radius: 10%;
            background-color: rgb(92, 236, 255);
            text-align: center;
        }
        .hotkey>a{
            color: rgb(250, 255, 246);
            margin-left: 1%;
        }
    </style>
</head>
<body>
    <div id="app" class="wrap">
        <div class="search_form">
            <div class="logo">
                <img src="https://cdn.serif.com/affinity/img/home/1119/affinity-hero-logo-150620201402@2x.png"
                 alt="logo" id="logo-img"/>
            </div> 
            <div class="form_group">
                <input type="text" class="input_txt" autofocus="autofocus" autocomplete="off"
                 placeholder="请输入查询城市"/>
                <button class="input_sub">查询</button>
            </div>
            <div class="hotkey">
                <a href="javascript:;">北京</a>
                <a href="javascript:;">上海</a>
                <a href="javascript:;">深圳</a>
                <a href="javascript:;">广州</a>
            </div>
        </div>
        <ul class="weather_list">
        </ul>
    </div>

    <script src="https://unpkg.com/axios@0.20.0/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

接下来我们来实现功能

回车查询

页面样式

      body{
            background-image: url("https://images7.alphacoders.com/306/306617.jpg");
            background-size: cover;   
        }
        #app{
            text-align: center;
            padding-top: 10%;
        }
        #logo-img{
            width: 10%;
            height: auto;
        }
        .input_txt{
            width: 10%;
            height: 30px;
            border-radius: 10%;
            background-color: rgb(242, 242, 248);
        }
        .input_sub{
            width: 5%;
            height: 40px;
            border-radius: 10%;
            background-color: rgb(92, 236, 255);
            text-align: center;
        }
        .hotkey>a{
            color: black;
            margin-left: 1%;
        }
        .weather_list{
            list-style: none;
            margin-top: 5%;
            margin-left: 25%;
            margin-right: 25%;
        }
        .weather_list>li{
            float:left;
            margin: 0 10px;
            background-color: rgba(31, 31, 31, 0.5) ;
            border-radius: 5%;
        }
        .result>span{
            color: rgb(250, 250, 250);
            font-size: larger;
        }

html主要内容

   <div id="app" class="wrap">
        <div class="search_form">
            <div class="logo">
                <img src="https://cdn.serif.com/affinity/img/home/1119/affinity-hero-logo-150620201402@2x.png"
                 alt="logo" id="logo-img"/>
            </div> 
            <div class="form_group">
                <input type="text" class="input_txt" autofocus="autofocus" autocomplete="off"
                 placeholder="请输入查询城市" @keyup.enter="searchWeather" v-model="city" />
                <button class="input_sub">查询</button>
            </div>
            <div class="hotkey">
                <a href="javascript:;"><b>北京</b></a>
                <a href="javascript:;"><b>上海</b></a>
                <a href="javascript:;"><b>深圳</b></a>
                <a href="javascript:;"><b>广州</b></a>
            </div>
        </div>
        <ul class="weather_list">
            <li v-for="item in weatherList">
                <div class="result">
                    <span>{{item.date}}</span><br/>
                    <span>{{item.fengxiang}}</span><br/>
                    <span>{{item.high}}</span><br/>
                    <span>{{item.low}}</span><br/>
                    <span>{{item.type}}</span><br/>
                </div>
            </li>
        </ul>
    </div>

js文件下内容:

var app=new Vue({
    el:"#app",
    data:{
        city:"",
        weatherList:[]
    },
    methods:{
        searchWeather:function(){
            var that=this;
            //调用接口
            axios.get('http://wthrcdn.etouch.cn/weather_mini?city='
                    +this.city)
                    .then(function(res){
                        console.log(res);
                        that.weatherList=res.data.data.forecast;
                        console.log(that.weatherList);
                    })
                    .catch(function(err){
                        console.log("出现异常:"+err);
                    })
        }
    }
});

 

点击查询

下面我们来实现按钮的点击以及快捷城市的点击:

按钮直接绑定方法即可。

                <button class="input_sub" @click="searchWeather">查询</button>

快捷城市速查也是通过一个带参的方法:

            <div class="hotkey">
                <a href="javascript:;" @click="searchWeatherOfCity('北京')"><b>北京</b></a>
                <a href="javascript:;" @click="searchWeatherOfCity('上海')"><b>上海</b></a>
                <a href="javascript:;" @click="searchWeatherOfCity('深圳')"><b>深圳</b></a>
                <a href="javascript:;" @click="searchWeatherOfCity('广州')"><b>广州</b></a>
            </div>

方法的具体实现:

        searchWeatherOfCity:function(city){
            this.city=city;
            this.searchWeather();       
        }

效果

 

音乐播放器

需求与接口

一个web端的音乐播放器,实现:

  1. 歌曲的搜索
  2. 歌曲的播放
  3. 歌曲的封面

我们主要访问的接口:

  • 搜索歌曲信息
    • 请求地址:https://autumnfish.cn/search
    • 请求方式:get
    • 请求参数:keywords(关键字,歌手或歌名等)
  • 歌曲url
    • 请求地址:https://autumnfish.cn/song/url
    • 请求方式:get
    • 请求参数:id(歌曲id,从歌曲信息中得到)
  • 歌曲封面
    • 请求地址:https://autumnfish.cn/song/detail
    • 请求方式:get
    • 请求参数:ids(歌曲id,从歌曲信息中得到)

代码

       body{
            background-color: rgb(230, 213, 195);

        }
        #player{
            width:800px;
            margin: 0 auto;
            border:5px solid rgb(255, 140, 0);
        }
        .search_bar{
            padding: 10px;
            background-color: seagreen;
        }
        #search_form{
            float:right;
            margin: 15px;
            width: auto;
            height: 20px;
            background: sandybrown;
        }
        #search_form:hover{
            background: rgb(255, 150, 58);
        }
        .song_wrapper{
            width: 300px;
            background: rgb(129, 125, 110);
            height: 1600px;
            float: left;
        }
        .player_con{
            float: right;
            width: 499px;
            background-color: cadetblue;
            height: 1600px;

            text-align: center;
        }
        .song_list{
            list-style: none;
        }
        .info{
            color: rgb(255, 255, 162);
        }
        #music_play{
            width: 100%;
            height: 35px;
            background-color: black;
        }
        .music_pic{
            width: 400px;
            height: auto;
            margin-top:15px ;
        }
    <div id="app" class="wrap">
        <!--播放器主体区域-->
        <div class="play_wrap" id="player">
            <div class="search_bar">
                <img src="https://www.easyicon.net/api/resizeApi.php?id=1187281&size=48"
                 alt="" />
                 <span style="color: rgb(214, 214, 214);font-size: larger;">有诗意</span>
                <!--搜索歌曲-->
                <input type="text" autocomplete="off" v-model="query"
                id="search_form" placeholder="搜索音乐" @keydown.enter="searchMusic"/>
            </div>
            <div class="audio_con">
                <audio ref="audio" :src="musicUrl" id="music_play"
                 controls autoplay loop class="muAudio"></audio>
            </div>
            <div class="center_con">
                <!--搜索歌曲列表-->
                <div class="song_wrapper">
                    <ul class="song_list">
                        <li v-for="item in musicList" style="margin:2%;">
                            <a href="#" @click="playMusic(item.id)">
                                <img src="https://www.easyicon.net/api/resizeApi.php?id=1279830&size=24">
                            </a>
                            <b class="info">{{item.name}}</b>
                            <span class="info" style="font-size: small;">
                                {{item.artists[0].name}}
                            </span>
                        </li>
                    </ul>
                    <img src="" class="switch_btn" alt=""/> 
                </div>
                <!--歌曲信息容器-->
                <div class="player_con">
                    <img :src="musicPic" class="music_pic"/>
                </div>
            </div>
        </div> 
    </div>
var app=new Vue({
    el:"#player",
    data:{
        query:"",
        musicList:[],
        musicUrl:"",
        musicPic:""
    },
    methods:{
        searchMusic:function(){
            var that=this;
            axios.get("https://autumnfish.cn/search?keywords="+this.query)
            .then(function(res){
                that.musicList=res.data.result.songs;
                that.query="";
                console.log(res);
            },function(err){
                console.log("错误"+err);
            })
        },
        playMusic:function(musicID){
            var that=this;

            axios.get("https://autumnfish.cn/song/url?id="+musicID)
            .then(function(res){
                that.musicUrl=res.data.data[0].url;
            })
            .catch(function(err){
                console.log("错误"+err);          
            });
            //歌曲详情信息
            axios.get("https://autumnfish.cn/song/detail?ids="+musicID)
            .then(function(res){
                that.musicPic=res.data.songs[0].al.picUrl;
            })
            .catch(function(err){
                console.log("错误"+err);          
            });
        }
    }
});

效果

 

 

 


 

 

 

商业转载 请联系作者获得授权,非商业转载 请标明出处,谢谢

 

发表评论