速成版-带您一天学完vue2框架

news2024/11/15 13:39:56

vue是一个前端js框架,可以简化Dom操作,实现响应式数据驱动。前面全是废话,哈哈,接下来一起学习吧。

目录

一、vue基础

1.1、vue简介

1.2、第一个Vue程序

1.3、vue基础-el挂载点

1.4、data数据对象

二、本地应用-指令篇

2.1、v-text指令

2.2、v-html指令

 2.3、v-on指令

2.4、计数器

2.5、v-show指令

 2.6、v-if指令

 2.7、v-bind指令

2.8、图片切换

 2.9、v-for指令

 2.10、v-model指令

三、本地应用-案例篇

3.1、记事本案例介绍

3.2、案例示意

四、网络应用

4.1基本介绍

4.2、axios的基本使用

4.3、axios+vue的使用

4.4、网络应用案例

五、综合应用

5.1、应用介绍

 5.2、应用实现


vue2官网:介绍 — Vue.js

一、vue基础

1.1、vue简介

vue是一个js框架,可以简化Dom操作,实现响应式数据驱动。

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

1.2、第一个Vue程序

3个步骤:1、导入vue;2、创建vue实例对象,设置相关属性。 3、使用模板语法把数据渲染到页面。

<!DOCTYPE html>
<html>
    <head>
        <meta charest="utf-8">
        <title>vue基础</title>
    </head>
    <body>
        <!--导入vue.js-->
        <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

         <!--使用简洁的模板语法把数据渲染到页面上-->
         <div id = "app">
            {{message}}
        </div>

         <!--创建vue实例对象,设置el属性和data属性-->
        <script>
        var app = new Vue({
            el: "#app",
            data: {
                message: "第一个vue程序!"
            }
        }) 
    </script>
    </body>
</html>

开发工具用的vscode,使用live server插件,实现左边代码右边浏览器实时分屏。

1.3、vue基础-el挂载点

el是用来设置vue实例挂载的,vue框架中会看到el挂在点,那么使用el挂载点,有哪些需要注意的问题呢,这里面主要考虑档额问题。

1、vue实例的作用范围:vue会管理el选项命中的元素机器内部的后代元素。

2、是否可以使用其它的选择:首先可以肯定的vue支撑其它选择器,但是建议使用id选择器。

3、是否可以设置其它Dom元素:可以使用其它的双标签不能使用HTML或body。

1.4、data数据对象

vue重用到的数据定义再data中,data中可以写复杂类型的数据,渲染复杂类型数据,遵循js的语法即可。

下面我们看一下例子吧,data中定义了复杂对象类型和数组类型,然后使用id选择器定义并渲染。

 

<!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>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
         {{message}}
         <h2>{{university.name}} {{university.postcode}}</h2>
         <li>{{address[0]}}</li>
         <li>{{address[1]}}</li>
         <li>{{address[2]}}</li>
     </div>

      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
             message: "第一个vue程序!",
             university:{
                name: "江西理工大学",
                postcode:"330000"
             },
             address:["南昌校区","三江校区","红旗校区"]
         }
     }) 
 </script>
</body>
</html>

二、本地应用-指令篇

2.1、v-text指令

v-text指令的作用是设置标签的内容,这个指令会替换全部的内容,使用插值表达式{{}}可以替换全部的内容。

<!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>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
        <!--v-text命令设置标签的内容,默认替换所有-->
         <h2 v-text = "message"> 此处的被替换掉了 </h2>
         <h2 v-text = "university.name">此处的被替换掉了</h2>
         <h2>{{message}} 此处的没有被替换掉</h2>
         
     </div>

      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
             message: "第一个vue程序!",
             university:{
                name: "江西理工大学",
                postcode:"330000"
             },
             address:["南昌校区","三江校区","红旗校区"]
         }
     }) 
 </script>
</body>
</html>

2.2、v-html指令

v-html的指令是设置元素的innerhtml,内容中有html就会被解析为标签,v-text内容无论是什么,都只会被解析为文本。

<!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>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
        <!--v-text命令设置标签的内容,默认替换所有-->
         <h2 v-text = "content">  </h2>
         <h2 v-html = "content"></h2>
     </div>

      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
            content:"<a href = 'http://www.baidu.com'>百度一下,你就知道</a>"
         }
     }) 
 </script>
</body>
</html>

 2.3、v-on指令

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

<!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>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
        <input type="button" value="点击事件1" v-on:click="f1" >
        <input type="button" value="点击事件2" @click = "f1">
        <input type="button" value="双击事件" @dblclick = "f1">
        <h2 @click = "f2">{{food}}</h2>
     </div>

      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
            food: "黄焖鸡米饭"
         },
         methods:{
            f1:function(){
                alert("好好学习") ;
            },
            f2:function(){
                this.food += "味道好啊"
            }
         }
     }) 
 </script>
</body>
</html>

事件绑定的方法写成函数调用的形式,可以传入自定义参数,通过形参来定义,传递实参,事件后面跟上.修饰符可以对事件进行修饰,比如.enter是回车事件。

文档:API — Vue.js

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue基础</title>
    <link rel="stylesheet" href="./out/css/index.css">
</head>

<body>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

    
      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
        <input type="button" value="点击事件" @click = "f1(1,2)">
        <input type = "text" @keyup.enter = "f2">
     </div>
      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
         },
         methods:{
            f1:function(p1,p2){
             alert(p1+ p2) ;
            },
           f2:function(){
            alert("come on!!!") ;
            }
         }
     }) 
 </script>
</body>
</html>

2.4、计数器

下面使用之前学习的绑定监听事件的方法做个计数器的功能,创建vue:el是挂载点,data是数据,methods是方法,v-on指令绑定事件,可以直接简写成@,通过this关键子在方法中获取data的数据,v-text设置元素的文本值,v-html设置innerhtml。

 

<!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>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
        <!--计数器功能区-->
        <div class="input-num">
            <button @click = "sub">
                -
            </button>
            <span>{{num}}</span>
            <button @click = "add">
                +
            </button>
        </div>
     </div>
      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
            num: 1
         },
         methods:{
            add:function(){
               if(this.num < 10){
                this.num ++ ;
               }else{
                alert("超过最大值了!!!") ;
               }
            },
            sub:function(){
                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">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue基础</title>
</head>
<body>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
        <input type="button" value="改变图片显示状态" @click = "change">
       <img v-show = "isShow" src="./out/img/pk.jpg">
     </div>
      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
            isShow : true
         },
         methods:{
            change:function(){
              this.isShow = !this.isShow ;
            }
         }
     }) 
 </script>
</body>
</html>

 2.6、v-if指令

v-if指令的作用是根据表达式的真假切换元素的显示状态,本质是操作dom元素来切换显示状态,表达式为true,保留元素在dom树,表达式为false,将元素从dom树移除。

<!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>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
        <input type="button" value="改变图片显示状态" @click = "change">
       <img v-if = "isShow" src="./out/img/pk.jpg">
     </div>
      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
            isShow : false
         },
         methods:{
            change:function(){
              this.isShow = !this.isShow ;
            }
         }
     }) 
 </script>
</body>
</html>

 2.7、v-bind指令

v-bind指令是为元素绑定属性,完整的写法是v-bind:属性名,可以简写省略v-bind,直接保留:属性名。

 

<!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>
<style>
    .active{
        border: 1px solid red;
    }
</style>
<body>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

      
      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
        <img v-bind:src = "images" >
        <br>
        <img v-bind:src = "images"  v-bind:title = "titles" 
        v-bind:class = "{active:isActive}"
        @click = "change">
     </div>
      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
            images: "./out/img/pk.jpg" ,
            titles:"北京大学",
            isActive: false
         },
         methods:{
            change:function(){
              this.isActive = !this.isActive ;
            }
         }
     }) 
 </script>
</body>
</html>

2.8、图片切换

定义data中包含数组图片,以及数组下标,通过监控methods中的切换页面的方法,显示相应的页面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue基础</title>
    <link rel="stylesheet" href="./out/css/index.css">
</head>

<body>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
     
    
      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "mask">
       <div class="center">
        <img :src = "images[index]" >
        <a href="javascript:void(0)" class="left" @click = "pre" v-show = "index != 0">
            <img src = "./out/img/left.jpg" >
        </a>
        <a href="javascript:void(0)" class="right" @click = "next" v-show = "index < images.length-1">
            <img src = "./out/img/right.jpg" >
        </a>
       </div>
     </div>
      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#mask",
         data: {
           // 数组保存多组数据
            images: ["./out/img/nj.jpg",
            "./out/img/pk.jpg",
            "./out/img/ts.jpg"],
            index: 0
         },
         methods:{
            pre:function(){
              this.index -- ;
            },
            next:function(){
                this.index ++ ;
            }
         }
     }) 
 </script>
</body>
</html>

 2.9、v-for指令

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

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue基础</title>
    <link rel="stylesheet" href="./out/css/index.css">
</head>

<body>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

    
      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
        <input type="button" value="新增选项" @click = "update">
        <input type="button" value="删除选项" @click = "remove">
       <ul>
        <li v-for= "(item, index) in arrays">
            {{index+1}} 四邮:{{item}}
        </li>
       </ul>
       <h2 v-for = "item in objects" >{{item.name}} </h2>
     </div>
      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
            arrays:["北京邮电大学","南京邮电大学","重庆邮电大学","西安邮电大学"],
            objects:[
            {name:"电子科技大学"},
            {name:"西安电子科技大学"},
            {name:"杭州电子科技大学"},
            {name:"桂林电子科技大学"}]
         },
         methods:{
            update:function(){
              this.objects.push({name:"北京大学"}) ;
            },
            remove:function(){
                this.objects.shift() ;
            }
         }
     }) 
 </script>
</body>
</html>

 2.10、v-model指令

v-model指令的作用是便捷设置和获取表单元素的值, 绑定的元素和表单元素双向关联。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue基础</title>
    <link rel="stylesheet" href="./out/css/index.css">
</head>

<body>
      <!--导入vue.js-->
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

    
      <!--使用简洁的模板语法把数据渲染到页面上-->
      <div id = "app">
        <input type="button" value="点击事件" @click = "setMessage">
        <input type = "text" v-model = "message" @keyup.enter = "getMessage">
     </div>
      <!--创建vue实例对象,设置el属性和data属性-->
     <script>
     var app = new Vue({
         el: "#app",
         data: {
            message:"北京大学"
         },
         methods:{
            getMessage:function(){
             alert(this.message) ;
            },
            setMessage:function(){
                this.message = "清华大学" ;
            }
         }
     }) 
 </script>
</body>
</html>

三、本地应用-案例篇

3.1、记事本案例介绍

该记事本共包含新增、删除、统计、清空、隐藏等功能,应用上面学习过的vue基础实现。

3.2、案例示意

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>vue基础</title>
    <link rel="stylesheet" href="./out/css/index.css">
</head>

<body>
    <!-- 主体区域 -->
  <section id="todoapp">
    <!-- 输入框 -->
    <header class="header">
      <h1>记事本</h1>
      <!---新增-->
      <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" v-show="list.length!=0">
      <span class="todo-count" v-if="list.length!=0">
        <strong>{{ list.length }}</strong> 条记录
      </span>
      <button v-show="list.length!=0" class="clear-completed" @click="clear">
        清空
      </button>
    </footer>
  </section>
  </footer>
  <!-- 开发环境版本,包含了有帮助的命令行警告 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    var app = new Vue({
      el: "#todoapp",
      data: {
        list: ["写bug", "吃外卖", "睡大觉"],
        inputValue: ""
      },
      methods: {
        add: function () {
          this.list.push(this.inputValue);
        },
        remove: function (index) {
          this.list.splice(index, 1);
        },
        clear: function () {
          this.list = [];
        }
      },
    })
  </script>
</body>
</html>

四、网络应用

4.1基本介绍

通过vue结合网络数据开发应用,学习axios网络请求库,结合vue一起学习。

4.2、axios的基本使用

axios必须先导入才能使用,使用get或post方法即可发送相应的请求,then方法中的回调函数会在请求成功或者失败的时候触发,通过回调函数的形参可以获得响应内容或者错误信息。

<!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>
   
  <!-- 官网提供的 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>
    document.querySelector(".get").onclick = function () {
        axios.get("https://autumnfish.cn/api/joke/list?num=6")
        .then(function (response) {
            alert(response) ;
          },function(err){
            alert(err);
          })
    }
    document.querySelector(".post").onclick = function () {
        axios.post("https://autumnfish.cn/api/user/reg",{username:"zhangsan"})
        .then(function(response){
            alert(response) ;
        },function (err) {
            alert(err);
          })
      }
  </script>
</body>
</html>

4.3、axios+vue的使用

axios回调函数中的this会改变,无法访问data中的数据,可以事先把this保存起来,回调函数直接使用事先保存的this就可以啦。

 

<!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">
        <input type="button" value="获取笑话" @click="getJokes">
        <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>
    var app = new Vue({
        el:"#app",
        data: {joke: "笑话"},
        methods:{
            getJokes:function(){
                var that = this ;
                axios.get("https://autumnfish.cn/api/joke").then(function(response){
                    alert(response.data) ;
                    that.joke = response.data ;
                },function(err){
                    alert(error) ;
                })
        }
    }
    }) ;
  </script>
 
</body>
</html>

4.4、网络应用案例

注意:应用的逻辑代码建议与页面分离,使用单独的js文件,axios回调this已经改变了,需要提前保存。自定义参数可以使得代码的复用率更高,methods中定义的方法内部,可以通过this关键字调出其它方法。

 

主页面:

<!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="./out/css/index.css" />
  <link rel="stylesheet" href="./out/css/reset.css" />
</head>

<body>
  <div class="wrap" id="app">
    <div class="search_form">
      <div class="logo"><img src="./out/img/logo.png" alt="logo" /></div>
      <div class="form_group">
        <input type="text" class="input_txt" placeholder="请输入查询的天气" v-model="city" @keyup.enter="queryWeather" />
        <button class="input_sub" @click="queryWeather">
          搜 索
        </button>
      </div>
      <div class="hotkey">
        <!-- <a href="javascript:;" @click="clickSearch('北京')">北京</a>
          <a href="javascript:;" @click="clickSearch('上海')">上海</a>
          <a href="javascript:;" @click="clickSearch('广州')">广州</a>
          <a href="javascript:;" @click="clickSearch('深圳')">深圳</a> -->
        <a href="javascript:;" v-for="city in hotCitys" @click="clickSearch(city)">{{ city }}</a>
      </div>
    </div>
    <ul class="weather_list">
      <li v-for="(item,index) in forecastList" :key="item.date" :style="{transitionDelay:index*100+'ms'}">
        <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>
  <script>
    new Vue({
      el: "#app",
      data: {
        city: "武汉",
        forecastList: [],
        hotCitys: ["北京", "上海", "广州", "深圳","杭州","南京","南昌"]
      },
      methods: {
        queryWeather() {
          this.forecastList = [];
          axios
            .get(`http://wthrcdn.etouch.cn/weather_mini?city=${this.city}`)
            .then(res => {
              console.log(res);
              this.forecastList = res.data.data.forecast;
            })
            .catch(err => {
              console.log(err);
            })
            .finally(() => { });
        },
        clickSearch(city) {
          this.city = city;
          this.queryWeather();
        }
      }
    });
  </script>
</body>

</html>

五、综合应用

5.1、应用介绍

该应用主要包括搜索歌曲,音乐播放以及mv播放等功能,我没加mv播放的按钮。

 5.2、应用实现

主页面

<!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="./out/css/index.css">

</head>

<body>
  <div class="wrap">
    <!-- 播放器主体区域 -->
    <div class="play_wrap" id="player">
      <div class="search_bar">
        <img src="./out/img/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="#" >
                <img src="./out/img/play.png" @click="playMusic(item.id)" class="music-run-image">
              <b class="music-list">{{ item.name }}</b> 
              <span v-if="item.mvid!=0" @click="playMV(item.mvid)"><i></i></span>
            </a> 
            </li>
          </ul>
          <img src="images/line.png" class="switch_btn" alt="">
        </div>
        <!-- 歌曲信息容器 -->
        <div class="player_con" :class="{playing:isPlaying}">
          <img src="./out/img/player_bar.png" class="play_bar" />
          <!-- 黑胶碟片 -->
          <img src="./out/img/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.nickname}}</dd>
              <dd class="detail">
                {{ item.content }}
              </dd>
            </dl>
          </div>
          <img src="./out/img/line.png" class="right_line">
        </div>
      </div>
      <div class="audio_con">
        <audio ref='audio' @play="play" @pause="pause" :src="musicUrl" controls autoplay loop class="myaudio"></audio>
      </div>
      <div class="video_con" 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="./out/js/main.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;
      // 获取歌曲地址
      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;
    }
  }
});

css修饰:

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

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

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

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

.search_bar img {
  margin-left: 23px;
}

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

.center_con {
  height: 435px;
  background-color: rgba(255, 255, 255, 0.5);
  display: flex;
  position: relative;
}

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

.song_stretch {
  width: 600px;
}

.song_list {
  width: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  height: 100%;
}
.song_list::-webkit-scrollbar {
  display: none;
}

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

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

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

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

.song_stretch .song_list li b {
  width: 200px;
}

.song_stretch .song_list li em {
  width: 150px;
}

.song_list li span {
  width: 23px;
  height: 17px;
  margin-right: 50px;
}
.song_list li span i {
  display: block;
  width: 100%;
  height: 100%;
  cursor: pointer;
  background: url("../images/table.png") left -48px no-repeat;
}

.song_list li em,
.song_list li i {
  font-style: normal;
  width: 100px;
}

.player_con {
  width: 400px;
  height: 435px;
  position: absolute;
  left: 200px;
  top: 0px;
}

.player_con2 {
  width: 400px;
  height: 435px;
  position: absolute;
  left: 200px;
  top: 0px;
}

.player_con2 video {
  position: absolute;
  left: 20px;
  top: 30px;
  width: 355px;
  height: 265px;
}

.disc {
  position: absolute;
  left: 73px;
  top: 60px;
  z-index: 9;
}
.cover {
  position: absolute;
  left: 125px;
  top: 112px;
  width: 150px;
  height: 150px;
  border-radius: 75px;
  z-index: 8;
}
.comment_wrapper {
  width: 180px;
  height: 435px;
  list-style: none;
  position: absolute;
  left: 600px;
  top: 0px;
  padding: 25px 10px;
}
.comment_wrapper .title {
  position: absolute;
  top: 0;
  margin-top: 10px;
}
.comment_wrapper .comment_list {
  overflow: auto;
  height: 410px;
}
.comment_wrapper .comment_list::-webkit-scrollbar {
  display: none;
}
.comment_wrapper dl {
  padding-top: 10px;
  padding-left: 55px;
  position: relative;
  margin-bottom: 20px;
}

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

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

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

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

.comment_wrapper .detail {
  color: #666;
  margin-top: 5px;
  line-height: 18px;
}
.audio_con {
  height: 50px;
  background-color: #f1f3f4;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
}
.myaudio {
  width: 800px;
  height: 40px;
  margin-top: 5px;
  outline: none;
  background-color: #f1f3f4;
}
/* 旋转的动画 */
@keyframes Rotate {
  from {
    transform: rotateZ(0);
  }
  to {
    transform: rotateZ(360deg);
  }
}
/* 旋转的类名 */
.autoRotate {
  animation-name: Rotate;
  animation-iteration-count: infinite;
  animation-play-state: paused;
  animation-timing-function: linear;
  animation-duration: 5s;
}
/* 是否正在播放 */
.player_con.playing .disc,
.player_con.playing .cover {
  animation-play-state: running;
}
.music-run-image {
  width: 20px;
  position: relative;
  left: -10px;
  top: 20px;
  
}
.music-list{
width: 20px;
  position: relative;
  left: 20px;
  top: -1px;
}
.play_bar {
  position: absolute;
  left: 200px;
  top: -10px;
  z-index: 10;
  transform: rotate(-25deg);
  transform-origin: 12px 12px;
  transition: 1s;
}
/* 播放杆 转回去 */
.player_con.playing .play_bar {
  transform: rotate(0);
}
/* 搜索历史列表 */
.search_history {
  position: absolute;
  width: 296px;
  overflow: hidden;
  background-color: rgba(255, 255, 255, 0.3);
  list-style: none;
  right: 23px;
  top: 50px;
  box-sizing: border-box;
  padding: 10px 20px;
  border-radius: 17px;
}
.search_history li {
  line-height: 24px;
  font-size: 12px;
  cursor: pointer;
}
.switch_btn {
  position: absolute;
  right: 0;
  top: 0;
  cursor: pointer;
}
.right_line {
  position: absolute;
  left: 0;
  top: 0;
}
.video_con video {
  position: fixed;
  width: 800px;
  height: 546px;
  left: 50%;
  top: 50%;
  margin-top: -273px;
  transform: translateX(-50%);
  z-index: 990;
}
.video_con .mask {
  position: fixed;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  z-index: 980;
  background-color: rgba(0, 0, 0, 0.8);
}
.video_con .shutoff {
  position: fixed;
  width: 40px;
  height: 40px;
  background: url("../images/shutoff.png") no-repeat;
  left: 50%;
  margin-left: 400px;
  margin-top: -273px;
  top: 50%;
  z-index: 995;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/735629.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DESCN:用于个体治疗效果估计的深度全空间交叉网络

英文题目&#xff1a;DESCN: Deep Entire Space Cross Networks for Individual Treatment Effect Estimation 翻译&#xff1a;用于个体治疗效果估计的深度全空间交叉网络 单位&#xff1a;阿里 论文链接&#xff1a; 代码&#xff1a;https://github.com/kailiang-zhong/…

由中序及后序遍历序列构建二叉树的函数参数解析

【二叉树构建函数的参数确立示意图】 ile&#xff1a;中序遍历左端点位置&#xff0c;iri&#xff1a;中序遍历右端点位置 ple&#xff1a;后序遍历左端点位置&#xff0c;pri&#xff1a;后序遍历右端点位置 【函数代码】 int build(int ile,int iri,int ple,int pri){int ro…

(文章复现)考虑微网新能源经济消纳的共享储能优化配置matlab代码

参考文献&#xff1a; [1]谢雨龙,罗逸飏,李智威等.考虑微网新能源经济消纳的共享储能优化配置[J].高电压技术,2022,48(11):4403-4413. 1.基本原理 双层规划是具有两个层次的优化问题&#xff0c;具有外层和内层两个优化目标&#xff0c;本研究的问题结构如图2所示。两层问题相…

打印机不打印故障检查步骤

第一步&#xff1a;检查打印机电源是否接通、打印机电源开关是否打开、打印机数据线的连接是否正确。 第二步&#xff1a;检查打印机进纸盒中是否有纸&#xff0c;打印机内是否卡纸&#xff0c;感光鼓组件是否有问题。 第三步&#xff1a;检查应用程序是否有问题或存在病毒。 第…

C#,数值计算——分数阶的贝塞尔函数(Bessel functions of fractional order)源代码

分数阶微积分这一重要的数学分支&#xff0c;其诞生在1695年&#xff0c;几乎和经典微积分同时出现。那一年&#xff0c;德国数学家Leibniz 和法国数学家LHopital 通信&#xff0c;探讨当导数的阶变为1/2时&#xff0c;其意义是什么&#xff1f;当时Leibniz也不知道定义与意义&…

强化学习-理解及应用:解决迷宫问题

什么是强化学习&#xff1f; 强化学习&#xff08;Reinforcement Learning, RL&#xff09;是一种机器学习方法&#xff0c;旨在让智能体&#xff08;agent&#xff09;通过与环境的交互学习如何做出最优的行动选择以获得最大的累积奖励。 7个基本概念 强化学习主要由智能体…

YApi-高效、易用、功能强大的可视化接口管理平台——(三)YApi 项目管理

YApi 项目管理 新建项目修改项目图标项目迁移项目拷贝删除项目配置环境请求配置请求参数示例返回数据示例storage工具函数异步处理&#xff08;v1.3.13支持&#xff09; token全局mock 新建项目 点击右上角的 新建项目&#xff0c;进入新建项目页面&#xff1a; 完善项目信息…

JVM理论(三)运行时数据区--PC寄存器/虚拟机栈/本地方法栈

运行时数据区(JVM内存结构) JVM内存结构 内存是非常重要的资源,是硬盘和CPU的中间桥梁,承载操作系统和应用程序的实时运行.JVM内存布局规定java在运行过程中内存申请、分配、管理的策略&#xff0c;保证JVM高效稳定运行。不同的JVM对于内存划分和管理机制存在部分差异(如J9和JR…

Nacos2.3.0源码启动报错找不到符号com.alibaba.nacos.consistency.entity

一. 源码下载编译&#xff1a;找不到符号com.alibaba.nacos.consistency.entity 如果报错找不到符号com.alibaba.nacos.consistency.entity Nacos\consistency\src\main\java\com\alibaba\nacos\consistency\entity 这个包下没有相关的java文件&#xff0c;其实是我们没有编译…

Vue.js 双向数据绑定的具体实现代码(简洁版)

1、 执行初始化&#xff0c;对data执行响应化处理 先来一个构造函数&#xff1a;执行初始化&#xff0c;对data执行响应化处理 class Vue { constructor(options) { this.$options options; this.$data options.data; // 对data选项做响应式处理 observe(this.$data);…

Linux性能优化实践——CPU上下文

CPU上下文切换 Linux是一个多任务操作系统&#xff0c;它支持远大于CPU数量的任务同时运行。这些任务不是真正意义上的并行运行&#xff0c;而是系统在短时间内&#xff0c;将CPU轮流分配给它们&#xff0c;造成任务同时运行的错觉。 CPU需要知道任务从哪里加载&#xff0c;从…

使用 OpenVINO™ 转换和优化 YOLOv8

本教程还可以作为 Jupyter Notebook 提供,可以直接从 GitHub 克隆。请参阅安装指南,了解在 Windows、Linux 或 macOS 上本地运行本教程的说明。 Ultralytics 开发的 YOLOv8 算法是一种尖端、最先进的 (SOTA) 模型,旨在快速、准确且易于使用,使其成为各种物体检测、图像分割…

Cartoon头像 InsCode Stable Diffusion 美图活动一期

一. 简单介绍和活动地址 简单介绍 试用Stable Diffusion 模型生成优质人物好图&#xff0c;更简单地炼丹。 “InsCode是一个集成了在线IDE、在线AI编程、在线算力租赁、在线项目部署以及在线SD 模型使用的综合代码开发平台。不论你是初级软件工程师&#xff0c;还是AI大模型…

【Java】删除集合元素的正确与错误做法

错误做法 一、fori正序 list.remove(num) Test public void test031(){ ArrayList<Integer> list new ArrayList<>(); list.add(1); list.add(3); list.add(3); for (int i 0; i < list.size(); i) { Integer numlist.get(i); if(num3){ list.re…

数据集 VOC转YOLO格式

一、xml转换为txt import os.path import xml.etree.ElementTree as ET import os import random # class_names [palm, stone, scissor, awesome, heartB, OK, ROCK, one, swear, thanks, heartA, # heartC, good, bad, pray, call, take_picture, salute] c…

Java:缓冲流

1.缓冲流分类 2.字节缓冲流 原理:底层自带了长度为8192的缓冲区提高性能。 1.方法&#xff1a; public BufferedInputstream( Inputstream is)&#xff1a;把基本流包装成高级流&#xff0c;提高读取数据的性能。public BufferedOutputStream(OutputStream os)把基本流包装成…

【Java|基础篇】面向对象三大特性之继承(上)

文章目录 1. 前言2. 问题提出3. 什么是继承4. 继承的特点 1. 前言 继承是面向对象三大特性之一. Java的继承也是很复杂. 本篇文章先帮助大家理解继承的概念 2. 问题提出 先来看这两个类: Student类: public class Student {private String name;private int age;private S…

【技能实训】DMS数据挖掘项目-Day02

文章目录 任务3【任务3.1】实现日志实体类【任务3.2】创建日志业务类&#xff0c;实现日志信息的采集及打印输出【任务3.3】创建日志测试类&#xff0c;测试任务3.2中的程序&#xff0c;演示日志信息的采集及打印输出 任务4【任务4.1】物流实体信息类【任务4.2】创建物流业务类…

Slicer学习笔记(六十四) 关于3DSlicer的python脚本和编程

Slicer学习笔记(六十四) 关于3DSlicer的python脚本和编程 目标1. 软件结构2. 在Slicer中使用python控制台 简单的脚本模块示例3. 单独编写简单的脚本模块目标 1. 软件结构 Slicer应用程序架构 模块类型:c++可加载 模块类型:脚本加载 模块类型:CLI Slicer数据模型 MRML

SendGrid 无法注册,Create Account 按钮灰色无法点击

问题描述&#xff1a; 注册SendGrid的时候&#xff0c;账号密码都输好了&#xff0c;就是没办法点【Create Account】。 解释思路&#xff1a; 其实空白处有一个reCAPTCHA 验证码&#xff0c;但是被隐去了。所以我们的思路是如何让网页中的reCAPTCHA 验证码顺利显示出来。 问…