Vue基础入门(Vue指令篇)

Vue基础

    • 一、基础知识点
        • 1. el:挂载点
        • 2. data:数据对象
    • 二、本地应用
        • 1. Vue指令
            • 1.1 v-cloak 指令用法
            • 1.2 内容绑定,数据绑定(v-text | v-html | v-pre | v-once)
            • 1.3 事件绑定( v-on)
            • 1.4 显示切换,属性绑定(v-show | v-if | v-else-if | v-else | v-bind)
            • 1.5 列表循环,表单元素(双向)绑定(v-for | v-model)
            • 1.6 案例:tab选项卡
    • 三、网络应用
        • 1. axios基本使用
        • 2. axios+vue
        • 3. 案例:天气预报查询
            • (1) 回车查询:
            • (2) 点击查询:
            • (3) 结果演示:
    • 四、综合应用
        • 1. 歌曲搜索
        • 2. 歌曲播放
        • 3. 歌曲封面
        • 4. 歌曲评论
        • 5. 播放动画
        • 6. 播放mv
        • 7. 结果演示

一、基础知识点

1. el:挂载点

作用:el是用来设置Vue实例挂载(管理)的元素。

问:Vue实例的作用范围是什么呢?
答:Vue会管理el选项命中的元素及其内部的后代元素

问:是否可以使用其他的选择器?
答:可以使用其他的选择器,但是建议使用ID选择器

问:是否可以设置其他的dom元素呢?
答:可以使用其他的双标签,不能使用HTMLBODY

2. data:数据对象

  • Vue中用到的数据定义在data中。
  • data中可以写复杂类型的数据。
  • 渲染复杂类型数据时,遵守js的语法即可。

二、本地应用

1. Vue指令

1.1 v-cloak 指令用法

插值表达式存在的问题:“闪动”。
如何解决该问题:使用v-cloak指令。
解决该问题的原理:先隐藏,替换好值之后再显示最终的值。

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-cloak指令</title>
    <style>
        [v-cloak] {
            display: none;
        }
    </style>
</head>

<body>
    <div id="app">
    <!-- 
        v-cloak指令的用法
        1.提供样式
        [v-cloak]{
            display:none;
        }
        2.在插值表达式所在的标签中添加v-cloak指令 
    -->
        <h2 v-cloak>{{message}}</h2>
    </div>
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                message: "你好 Vue!"
            }
        });
    </script>
</body>
1.2 内容绑定,数据绑定(v-text | v-html | v-pre | v-once)

(1) v-text

作用:设置标签的内容(textContent)。
默认写法会替换全部内容,使用插值表达式{{}}可以替换指定内容。

<div id="app">
    <h2 v-text="message+'!'">厦门</h2>
    <!-- 部分替换使用{{}}写法 -->
    <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: "你好 Vue"
        }
    });
</script>

结果演示:
Vue基础入门(Vue指令篇)_第1张图片

(2) v-html

作用:设置元素的innerHTML。
内容中有 html结构会被解析为 标签
v-text指令无论内容是什么,只会解析为 文本
解析文本 使用 v-text ,需要 解析html结构 使用 v-html。

<div id="app">
    <!-- 普通文本两者 没什么显示的差异 -->
    <h2 v-html="message"></h2>
    <h2 v-text="message"></h2>
    <!-- 有html结构的 -->
    <h2 v-html="content"></h2>
    <h2 v-text="content"></h2>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好 Vue",
            content: "百度链接"
        }
    });
</script>

结果演示:
Vue基础入门(Vue指令篇)_第2张图片
(3) v-pre

作用:显示原始显示,跳过编译过程。

<div id="app">
  <h2 v-pre>{{message}}</h2>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "你好 Vue!"
        }
    });
</script>

在这里插入图片描述
(4) v-once

作用:只编译一次,显示内容之后不再具有响应式功能。
应用场景:如果显示的信息后续不再需要修改,可以使用v-once提高性能。

1.3 事件绑定( v-on)

(1) v-on

作用:为元素绑定事件。
事件名不需要写 on , 指令可以简写为 @
绑定的方法定义在methods属性中。
方法内部通过this关键字可以访问定义在data中的数据。

① 事件直接绑定函数名

如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数

<div id="app">
<input type="button" value="v-on指令" v-on:click="doIt"></input>
    <input type="button" value="v-on简写" @click="doIt"></input>
    <input type="button" value="双击事件" @dblclick="doIt"></input>
    <h2 @click="changeFood">{{food}}</h2>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            food: "番茄炒蛋"
        },
        methods: {
            doIt: function() {
                alert('前端');
                console.log(event.target.value);
            },
            changeFood: function() {
                //console.log(this.food);
                this.food += "好好吃";
            }
        }
    });
</script>

结果演示:
Vue基础入门(Vue指令篇)_第3张图片
② 事件绑定函数调用

如果事件绑定函数调用,那么事件对象作为最后一个参数进行显示传递,并且事件对象的名称必须是$event

<div id="app">
    <input type="button" value="点击" @click="doIt(666,999,$event)">
</div>

<script src=" https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
<script>
    var app = new Vue({
        el: "#app",
        methods: {
            doIt: function(p1, p2, event) {
                console.log(p1);
                console.log(p2);
                console.log(event.target.tagName);
                console.log(event.target.value);
            }
        },
    });
</script>

结果演示:
Vue基础入门(Vue指令篇)_第4张图片
(2) 事件修饰符

  • .stop 阻止冒泡
  • .prevent 阻止默认行为
<div id="app">
   <div>{{num}}</div>
    <!-- 事件冒泡 -->
    <div v-on:click='handle1'>
        <!-- 阻止冒泡 -->
        <button v-on:click.stop="handle2">点击</button>
    </div>
    <div>
        <!-- 阻止默认行为:阻止跳转到百度 -->
        <a href="http://www.baidu.com" v-on:click.prevent="handle2">百度</a>
    </div>
</div>

<script src=" https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            num: 0
        },
        methods: {
            // 事件冒泡
            handle1: function() {
                this.num++;
            }
        }
    });
</script>

(3)按键修饰符

  • .enter 回车键
  • .delete 删除键
<div id="app">
   <form action="">
        <div>
            用户名:
            <input type="text" @keyup.enter="handleSubmit" v-model="uname">
        </div>
        <div>
            密码:
            <input type="password" @keyup.delete="clearContent" v-model="pwd">
        </div>
        <div>
            <input type="button" @click="handleSubmit" value="提交">
        </div>
    </form>
</div>

<script src=" https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            uname: '',
            pwd: ''
        },
        methods: {
            handleSubmit: function() {
                console.log(this.uname + this.pwd);
            },
            clearContent: function() {
                //按下delete键清空密码
                this.pwd = '';
            },
        }
    });
</script>

(4) 自定义按键修饰符

规则:自定义按键修饰符名字自定义的,但是对应的必须是按键对应event.keyCode值。
全局变量config.keyCodes对象。

<div id="app">
        <input type="text" @keyup.aaa="handle" v-model="info">
    </div>

    <script src=" https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
    <script>
        Vue.config.keyCodes.aaa = 65;
        var app = new Vue({
            el: '#app',
            data: {
                info: ''
            },
            methods: {
                handle: function(event) {
                    console.log(event.keyCode);
                }
            }
        });
    </script>

(5) 案例:计数器

<div id="app">
    <!-- 计数器功能区域 -->
    <div class="input-num" style="text-align: center;margin-top: 100px;">
        <button @click="sub">-</button>
        <span>{{num}}</span>
        <button @click="add">+</button>
    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            num: 1
        },
        methods: {
            add: function() {
                this.num++;
            },
            sub: function() {
                if (this.num > 0) {
                    this.num--;
                } else {
                    alert('不能在减少了!');
                }
            }
        }
    });
</script>

结果演示:
点击2次-按钮:
Vue基础入门(Vue指令篇)_第5张图片
点击3次+按钮:
在这里插入图片描述

1.4 显示切换,属性绑定(v-show | v-if | v-else-if | v-else | v-bind)

(1) v-show

作用:根据真假切换元素的显示状态。
原理是修改元素的display, 实现显示隐藏。
指令后面的内容,最终都会被解析为布尔值
值为true元素显示,值为false元素隐藏
数据改变之后,对应元素的显示状态会同步更新

<div id="app">
    <input type="button" name="" id="" value="切换显示状态" @click="changeIsShow">
    <img v-show="isShow" src=" ./img/monkey.gif " alt=" ">
    <input type="button" name="" id="" value="累加年龄" @click="addAge">
    <img v-show="age>=18" src=" ./img/monkey.gif " alt=" ">
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
<script>
    var app = new Vue({
        el: "#app ",
        data: {
            isShow: false,
            age: 17
        },
        methods: {
            changeIsShow: function() {
                this.isShow = !this.isShow;
            },
            addAge: function() {
                this.age++;
            }
        }
    });
</script>

结果演示:
Vue基础入门(Vue指令篇)_第6张图片
(2) v-if | v-else-if | v-else

作用:根据表达式的真假切换元素的显示状态。
本质是通过操纵dom元素来切换显示状态。
指令后面的内容,最终都会被解析为布尔值
值为true,元素存在dom树中,值为false,从dom树中移除
频繁的切换使用v-show,反之使用v-if,前者的切换消耗小。

 <div id="app">
     <div v-if="score>=90">优秀</div>
     <div v-else-if="score<90&&score>=80">良好</div>
     <div v-else-if="score<80&&score>=60">一般</div>
     <div v-else>比较差</div>
 </div>

 <script src=" https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
 <script>
     var app = new Vue({
         el: "#app",
         data: {
             score: 100
         }
     });
 </script>

(3) v-bind

1.作用:为元素绑定属性。
2.完整写法是 v-bind:属性名
3. 简写的话可以直接省略v-bind,只保留:属性名
4.class样式处理建议使用对象的方式,< div :class="{active:isActive,error:isError}">。
5.默认的class会被保留。

① class样式处理

<div id="app">
  <img v-bind:src="imgSrc" alt="">
    <br>
    <!-- 简写 -->
    <img :src="imgSrc" alt="">
    <br>
    <img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class="isActive?'active':''" @click="toggleActive">
    <!-- 使用对象的格式 -->
    <img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class="{active:isActive}" @click="toggleActive">
</div>

<script src=" https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
<script>
    var app = new Vue({
        el: "#app ",
        data: {
            imgSrc: "http://www.itheima.com/images/logo.png ",
            imgTitle: "程序员 ",
            isActive: false
        },
        methods: {
            toggleActive: function() {
                //控制isActive的值在true和false之间切换
                this.isActive = !this.isActive;
            }
        }
    });
</script>

② style样式处理

<div id="app">
    <div :style="{border:borderStyle,width:widthStyle,height:heightStyle}"></div>
    <div :style="objStyles"></div>
</div>

<script src=" https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
<script>
    var app = new Vue({
        el: "#app ",
        data: {
            borderStyle: '1px solid blue',
            widthStyle: '100px',
            heightStyle: '200px',
            // 对象方式
            objStyles: {
                border: '1px solid red',
                width: '200px',
                height: '100px'
            }
        },
        methods: {
            toggleActive: function() {
                this.isActive = !this.isActive;
            }
        }
    });
</script>

(4) 案例:图片切换

<div id="mask">
     <div class="center">
         <!-- 图片 -->
         <img :src="imgArray[index]" alt="" />
         <!-- 左箭头 -->
         <a href="javascript:;" @click="prev" class="left" v-show="index!=0">
             <img src="./img/prev.png" alt="" />
         </a>
         <!-- 右箭头 -->
         <a href="javascript:;" @click="next" class="right" v-show="index < imgArray.length-1">
             <img src="./img/next.png" alt="" />
         </a>
     </div>

 </div>
 </div>

 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
 <script>
     var app = new Vue({
         el: "#mask",
         data: {
             imgArray: [
                 "./img/0.jpg",
                 "./img/1.jpg",
                 "./img/2.jpg",
                 "./img/3.jpg",
                 "./img/4.jpg",
                 "./img/5.jpg",
             ],
             index: 0
         },
         methods: {
             // 上一张
             prev() {
                 this.index--;
             },
             // 下一张
             next() {
                 this.index++;
             }
         }
     });
 </script>

结果演示:
Vue基础入门(Vue指令篇)_第7张图片
Vue基础入门(Vue指令篇)_第8张图片
Vue基础入门(Vue指令篇)_第9张图片

1.5 列表循环,表单元素(双向)绑定(v-for | v-model)

(1) v-for

v-for指令的作用是:根据数据生成列表结构。
数组经常和v-for结合使用。
语法是(item,index) in 数组
item 和 index 可以结合其他指令一起使用。

<div id="app">
   <input type="button" value="添加数据" @click="add">
    <input type="button" value="移除数据" @click="remove">

    <ul>
        <li v-for="(item,index) in arr">{{index+1}}-wxy-{{item}}</li>
    </ul>
    <h2 v-for="item in vegetable" v-bind:title="item.name">{{item.name}}</h2>
</div>

<script src=" https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
<script>
    var app = new Vue({
        el: "#app ",
        data: {
            arr: ["北京", "上海", "广州", "深圳"],
            vegetable: [{
                name: "番茄炒鸡蛋"
            }, {
                name: "鸡蛋炒番茄"
            }]
        },
        methods: {
            add: function() {
                this.vegetable.push({
                    name: "韭菜炒蛋"
                })
            },
            remove: function() {
                this.vegetable.shift(); //移除最左边的元素
            }
        }
    });
</script>

结果演示:
Vue基础入门(Vue指令篇)_第10张图片

(2) v-model

作用:便捷的获取和设置表单元素的值。
绑定的数据会和表单元素的相关联。
绑定的数据与表单元素的值是双向绑定
底层实现原理:< input v-bind:value=“msg” v-on:input=“msg=$event.target.value”>

<div id="app">
    <input type="text" v-model="message" @keyup.enter="getM">
    <!-- 查看同步更新的内容 -->
    <h2>{{message}}</h2>
    <input type="button" value="修改message" @click="setM">
</div>

<script src=" https://cdn.jsdelivr.net/npm/vue/dist/vue.js "></script>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "wxy"
        },
        methods: {
            getM: function() {
                alert(this.message);
            },
            setM: function() {
                this.message = "小姐姐";
            }
        },
    });
</script>

结果演示:
Vue基础入门(Vue指令篇)_第11张图片
Vue基础入门(Vue指令篇)_第12张图片
(3) MVVM 设计思想
① M(model)
② V(view)
③ VM(View-Model)
Vue基础入门(Vue指令篇)_第13张图片

(4) 案例:小黑记事本

① 新增:

  1. 生成列表结构(v-for 数组)。
<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>
  1. 获取用户输入(v-model) 。
  2. 回车,新增数据(@keyup.enter 新增数据)。
<input autofocus="autofocus" autocomplete="off" placeholder="请输入任务" class="new-todo" v-model="inputValue" @keyup.enter="add" />
<script>
   var app = new Vue({
        el: "#todoapp",
        data: {
            list: ["写代码", "吃饭", "睡觉"],
            inputValue: "好好学习"
        },
        methods: {
            add: function() {
                this.list.push(this.inputValue);
            }
        }
    });
</script>

结果演示:
Vue基础入门(Vue指令篇)_第14张图片
② 删除:

  1. 点击删除指定内容(@click 和 splice)。
<button class="destroy" @click="remove(index)"></button>
 remove: function(index) {
     // 删除数组元素(从哪里开始删除,删除几个)
     this.list.splice(index, 1);
 }

③ 统计:

  1. 统计信息个数(v-text或{{}} 和 length)。
<span class="todo-count"><strong>{{list.length}}</strong> 条数据
</span>

结果演示:
Vue基础入门(Vue指令篇)_第15张图片
④ 清空:

1.点击清除所有信息(v-on 清空数组)。

<button class="clear-completed" @click="clear">Clear</button>
 clear: function() {
   this.list = [];
 }

结果演示:
Vue基础入门(Vue指令篇)_第16张图片⑤ 隐藏:

1.没有数据时,隐藏元素(v-show 或 v-if 数组非空)。

<!-- 统计和清空 -->
<footer class="footer">
    <span class="todo-count" v-show="list.length!=0"><strong>{{list.length}}</strong> 条数据
    </span>
    <button class="clear-completed" @click="clear" v-if="list.length!=0">Clear</button>
</footer>

结果演示:
Vue基础入门(Vue指令篇)_第17张图片
点击 Clear 清除所有信息后,隐藏共几条信息 和 Clear 。
Vue基础入门(Vue指令篇)_第18张图片

1.6 案例:tab选项卡

三、网络应用

1. axios基本使用

功能强大的网络请求库。

1)步骤:

axios必须先导入才可以使用。

<!-- 官网提供的 axios 在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

② 使用getpost方法即可发送对应的请求。
then方法的回调函数会在请求成功或失败时触发。
④ 通过回调函数的形参可以获取相应内容,或错误信息。

axios.get(地址?key=value & key2=value2).then(function(response){},function(err){})
axios.post(地址,参数对象).then(function(response){},function(err){})

2)案例:

<input type="button" value="get请求" class="get">
<input type="button" value="post请求" class="post">
<!-- 官网提供的 axios 在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    /*
        接口1:随机笑话
        请求地址:https://autumnfish.cn/api/joke/list
        请求方法:get
        请求参数:num(笑话条数,数字)
        响应内容:随机笑话
    */
    document.querySelector(".get").onclick = function() {
        axios.get("https://autumnfish.cn/api/joke/list?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: "wxy123"
        }).then(function(response) {
            console.log(response);
        }, function(err) {
            console.log(err);

        })
    }
</script>

结果演示:
Vue基础入门(Vue指令篇)_第19张图片

2. axios+vue

axios回调函数中的this已经改变,无法访问到data中数据。
this保存起来,回调函数中直接使用保存的this即可。
和本地应用的最大区别就是改变了数据来源

<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/dist/vue.js"></script>
<script>
    /*
        接口:随机获取一条笑话
        请求地址:https://autumnfish.cn/api/joke
        请求方法:get
        请求参数:无
        响应内容:随机笑话
    */
    var app = new Vue({
        el: "#app",
        data: {
            joke: "很好笑的笑话"
        },
        methods: {
            getJoke: function() {
                var that = this;
                axios.get("https://autumnfish.cn/api/joke").then(function(response) {
                    that.joke = response.data;
                }, function(err) {
                    console.log(err);

                })
            }
        },
    })
</script>

结果演示:
Vue基础入门(Vue指令篇)_第20张图片

3. 案例:天气预报查询

(1) 回车查询:

应用的逻辑代码使用单独的js文件编写。
axios回调函数中this指向改变了,需要额外的保存一份。
服务器返回的数据比较复杂,获取的时候需要注意层级结构

①按下回车键(v-on .enter)
②查询数据(axios 接口 x-model)

<input type="text" v-model="city" @keyup.enter="searchWeather" class="input_txt" placeholder="请输入查询的天气" />

③渲染数据

<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>
(2) 点击查询:

①点击城市(v-on 自定义参数)
②查询数据(axios 接口 x-model)
③渲染数据

<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>
/*
  请求地址: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;
            // 调用接口
            axios.get("http://wthrcdn.etouch.cn/weather_mini?city=" + this.city).then(function(response) {
                that.weatherList = response.data.data.forecast;
                console.log(response.data.data.forecast);
            }, function(err) {
                console.log(err);
            })
        },
        changeCity: function(city) {
            this.city = city;
            this.searchWeather();
        }
    },
})
(3) 结果演示:

Vue基础入门(Vue指令篇)_第21张图片

四、综合应用

1. 歌曲搜索

① 服务器返回的数据比较复杂时,获取的时候需要注意层级结构。
② 通过审查元素快速定位到需要操纵的元素。

2. 歌曲播放

① 点击播放(v-on 自定义参数)。
② 歌曲地址获取(接口 歌曲id)。
③ 歌曲地址设置(v-bind)。

3. 歌曲封面

① 点击播放(增加逻辑)。
② 歌曲封面获取(接口 歌曲id)。
③ 歌曲封面设置(v-bind)。

4. 歌曲评论

① 点击播放(增加逻辑)。
② 歌曲评论获取(接口 歌曲id)。
③ 歌曲评论渲染(v-for)。

5. 播放动画

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

6. 播放mv

① mv图标显示(v-if)。
② mv地址获取(接口 mvid)。
③ 遮罩层(v-show v-on)。
④ mv地址设置(v-bind)。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>悦听</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:isPlaying}">
                    <img src="images/player_bar.png" class="play_bar" />
                    <!-- 黑胶碟片 -->
                    <img src="images/disc.png" class="disc autoRotate" />
                    <img class="cover autoRotate" :src="picUrl" />
                </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" v-show="isShow" style="display: none;">
                <video controls="controls" :src="mvUrl"></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/main.js"></script>
</body>

</html>
/*
  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: "",
        //封面地址
        picUrl: "",
        //歌曲评论
        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) {
                console.log(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;
            }, function(err) {
                console.log(err);
            })

            //歌曲封面获取
            axios.get("https://autumnfish.cn/song/detail?ids=" + musicId).then(function(response) {
                that.picUrl = response.data.songs[0].al.picUrl;
                console.log(response.data.songs[0].al.picUrl);

            }, function(err) {
                console.log(err);
            })

            //歌曲评论获取
            axios.get("https://autumnfish.cn/comment/hot?type=0&id=" + musicId).then(function(response) {
                that.hotComments = response.data.hotComments;
                console.log(that.hotComments);

            }, function(err) {
                console.log(err);
            })

        },
        //歌曲播放
        play: function() {
            this.isPlaying = true;
            console.log("play");
        },
        //歌曲暂停
        pause: function() {
            this.isPlaying = false;
            console.log("pause");
        },
        //播放mv
        playMv: function(mvid) {
            var that = this;
            axios.get("https://autumnfish.cn/mv/url?id=" + mvid).then(function(response) {
                that.isShow = true;
                that.mvUrl = response.data.data.url;
            }, function(err) {
                console.log(err);
            })
        },
        //隐藏
        hide: function() {
            this.isShow = false;
            this.mvUrl = "";
        }
    }
})

7. 结果演示

Vue基础入门(Vue指令篇)_第22张图片
Vue基础入门(Vue指令篇)_第23张图片
Vue基础入门(Vue指令篇)_第24张图片

你可能感兴趣的:(vue)