黑马 Vue 快速入门 笔记

news2024/11/29 18:20:11

黑马 Vue 快速入门 笔记

  • 0 VUE相关了解
    • 0.1 概述
    • 0.2 MVVM
    • 0.3 JavaScript框架
    • 0.4 七大属性
    • 0.5 el:挂载点
  • 1 VUE基础
    • 1.0 第一个vue代码:Hello,vue
    • 1.1 v-bind 设置元素的属性 简写 :
    • 1.2 v-if , v-else , v-else-if
      • v-if , v-else
      • v-else-if
      • v-for结合v-if
    • 1.3 v-for 根据数据生成列表结构
    • 1.4 v-on 监听事件 简写@
    • 1.5 v-text 标签文本值
    • 1.6 v-html
    • 1.7 v-show 元素的显示与隐藏
    • 1.8 v-model 获取&设置 表单元素的数值,双向绑定
    • 案例:计数器
    • 案例:图片切换
    • 案例:小黑记事本
      • 知识点:绑定class属性
  • 2 表单双向绑定,组件
    • 2.1 什么是双向数据绑定
    • 2.2 在表单中使用双向数据绑定
      • 单行文本
      • 多行文本
      • 单复选框
      • 多复选框
      • 单选按钮
      • 下拉框
    • 知识点 v-bind 和 v-model 区分
  • 3 Axios
    • 介绍
    • 3.1 第一个Axios应用程序
    • 案例: axios + vue
  • 案例:网络应用[天知道]
    • 黑马代码(接口已报废)
    • 我的代码(接口可用)
  • 案例:音乐播放器


0 VUE相关了解

0.1 概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eoZjRpqU-1677055291257)(…/…/images/image-20220716152842582.png)]

  • 只关心视图层,自底向上.遵守SOC关注点分离原则(术有专攻,只关注一点)

  • HTML + CSS + JS : 视图 : 给用户看,刷新后台给的数据

  • MVVM,是Model-View-ViewModel的简写,是M-V-VM三部分组成。它本质上就是MVC 的改进版。采用双向数据绑定,MVVM 就是将其中的View 的状态和行为抽象化,其中ViewModel将视图 UI 和业务逻辑分开,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。


0.2 MVVM

MVVM是什么?

MVVM(Model-View-ViewModel)是一种软件设计模式,由微软WPF(用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight(类似于Java Applet,简单点说就是在浏览器上运行WPF)的架构师Ken Cooper和Ted Peters开发,是一种简化用户界面的事件驱动编程方式。由John Gossman(同样也是WPF和Sliverlight的架构师)与2005年在他的博客上发表。

MVVM源自于经典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用。其作用如下:

  • 该层向上与视图层进行双向数据绑定
  • 向下与Model层通过接口请求进行数据交互

在这里插入图片描述

MVVM已经相当成熟了,主要运用但不仅仅在网络应用程序开发中。当下流行的MVVM框架有Vue.jsAnfular JS

  • Model 层: 对应数据层的域模型,它主要做域模型的同步。通过 Ajax/fetch 等 API 完成客户端和服务端业务 Model 的同 步。在层间关系⾥,它主要⽤于抽象出 ViewModel 中视图的 Model 。

  • View 层: 作为视图模板存在,在 MVVM ⾥,整个 View 是⼀个动态模板。除了定义结构、布局外,它展示的是 ViewModel 层的数据和状态。 View 层不负责处理状态, View 层做的是 数据绑定的声明、 指令的声明、 事件绑定的声明。

  • ViewModel 层: 把 View 需要的层数据暴露,并对 View 层的 数据绑定声明、 指令声明、 事件绑定声明 负责,也就是处理 View 层的具体业务逻辑。 ViewModel 底层会做好绑定属性的监听。当 ViewModel 中数据变化, View 层会得到更 新;⽽当 View 中声明了数据的双向绑定(通常是表单元素),框架也会监听 View 层(表单)值的变化。⼀旦值变 化,View 层绑定的 ViewModel 中的数据也会得到⾃动更新。

MVVM 的优缺点 ?

优点:

  1. 分离视图(View)和模型( Model ) , 降低代码耦合,提⾼视图或者逻辑的重⽤性 : ⽐如视图(View)可以独⽴于 Model变化和修改,⼀个 ViewModel 可以绑定不同的 “View” 上,当 View 变化的时候 Model 不可以不变,当 Model 变化 的时候View 也可以不变。你可以把⼀些视图逻辑放在⼀个 ViewModel ⾥⾯,让很多 view 重⽤这段视图逻辑。
  2. 提⾼可测试性 : ViewModel 的存在可以帮助开发者更好地编写测试代码。
  3. ⾃动更新 dom: 利⽤双向绑定 , 数据更新后视图⾃动更新 , 让开发者从繁琐的⼿动 dom 中解放。

缺点:

  1. Bug 很难被调试 : 因为使⽤双向绑定的模式,当你看到界⾯异常了,有可能是你 View 的代码有 Bug ,也可能是 Model 的代码有问题。数据绑定使得⼀个位置的Bug 被快速传递到别的位置,要定位原始出问题的地⽅就变得不那么容易 了。另外,数据绑定的声明是指令式地写在View 的模版当中的,这些内容是没办法去打断点 debug 的。
  2. ⼀个⼤的模块中 model 也会很⼤,虽然使⽤⽅便了也很容易保证了数据的⼀致性,当时⻓期持有,不释放内存就造 成了花费更多的内存。
  3. 对于⼤型的图形应⽤程序,视图状态较多, ViewModel 的构建和维护的成本都会⽐较⾼。

MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大好处

  • 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 可复用:你可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。
  • 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewMode),设计人员可以专注于页面设计。
  • 可测试:界面素来是比较难以测试的,而现在测试可以针对ViewModel来写。

(1)View

View是视图层, 也就是用户界面。前端主要由HTH L和csS来构建, 为了更方便地展现vi eu to del或者Hodel层的数据, 已经产生了各种各样的前后端模板语言, 比如FreeMarker,Thyme leaf等等, 各大MV VM框架如Vue.js.Angular JS, EJS等也都有自己用来构建用户界面的内置模板语言。

(2)Model

Model是指数据模型, 泛指后端进行的各种业务逻辑处理和数据操控, 主要围绕数据库系统展开。这里的难点主要在于需要和前端约定统一的接口规则

(3)ViewModel

ViewModel是由前端开发人员组织生成和维护的视图数据层。在这一层, 前端开发者对从后端获取的Model数据进行转换处理, 做二次封装, 以生成符合View层使用预期的视图数据模型。
  需要注意的是View Model所封装出来的数据模型包括视图的状态和行为两部分, 而Model层的数据模型是只包含状态的


0.3 JavaScript框架

  • JQuery:大家熟知的JavaScript库,优点就是简化了DOM操作,缺点就是DOM操作太频繁,影响前端性能;在前端眼里使用它仅仅是为了兼容IE6,7,8;
  • Angular:Google收购的前端框架,由一群Java程序员开发,其特点是将后台的MVC模式搬到了前端并增加了模块化开发的理念,与微软合作,采用了TypeScript语法开发;对后台程序员友好,对前端程序员不太友好;最大的缺点是版本迭代不合理(如1代–>2 代,除了名字,基本就是两个东西;截止发表博客时已推出了Angular6)
  • React:Facebook 出品,一款高性能的JS前端框架;特点是提出了新概念 【虚拟DOM】用于减少真实 DOM 操作,在内存中模拟 DOM操作,有效的提升了前端渲染效率;缺点是使用复杂,因为需要额外学习一门【JSX】语言;
  • Vue:一款渐进式 JavaScript 框架,所谓渐进式就是逐步实现新特性的意思,如实现模块化开发、路由、状态管理等新特性。其特点是综合了 Angular(模块化)和React(虚拟 DOM) 的优点;
  • Axios:前端通信框架;因为 Vue 的边界很明确,就是为了处理 DOM,所以并不具备通信能力,此时就需要额外使用一个通信框架与服务器交互;当然也可以直接选择使用jQuery 提供的AJAX 通信功能;

0.4 七大属性

  • el属性
    • 用来指示Vue编译器从什么地方开始解析Vue的语法,可以说是一个占位符。
  • data属性
    • 用来组织从view中抽象出来的属性,可以说将视图的数据抽象出来存放在data中。
  • methods属性
    • 放置页面中的业务逻辑,js方法一般都放置在methods中
  • template属性
    • 用来设置模板,会替换页面元素,包括占位符。
  • render属性
    • 创建真正的virtual Dom 用js来渲染组件
  • computed属性
    • 用来计算
  • watch属性
    • watch:funtion(new,old){}
    • 监听data中的数据的变化
    • 两个参数,一个返回新值,一个返回旧值

0.5 el:挂载点

  1. el挂载点的范围:命中元素及其子元素
  2. 可以id选择器"#“,可以类选择器”."
  3. 只能使用于双标签之上,不可以用于body,html标签。

1 VUE基础

1.0 第一个vue代码:Hello,vue

使用方法

1. 导入Vue.js 依赖  
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
2. new 一个Vue对象
3. 绑定一个元素,    id对应#      class对应..........
4. data属性存放数据
5. 从模板里取出数据

第一个代码实例(菜鸟教育):

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    <!--引入VUE-->
    <script src="https://cdn.staticfile.org/vue/2.7.0/vue.min.js"></script>
</head>

<body>
    <div id="app">   	// 绑定元素,
        <p>{{ message }}</p>
    </div>

    <script>
        new Vue({
            el: '#app',     // 这里对应上面绑定的元素
            data: {			// 里面存放数据
                message: 'Hello Vue.js!'
            }
        })
    </script>
</body>

</html>

第一个代码实例(狂神)

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>

<body>

    <!--view层,模板-->
    <div id="app">
        {{message}}
        {{message1}}
    </div>

    <!-- 1. 导入Vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>

    <!-- 2. 创建VUE实例 -->
    <script type="text/javascript">
        var vm = new Vue({
            // 绑定元素的ID,el=Element
            el: "#app",
            /*Model:数据*/
            data: {
                message: "hello,vue!",
                message1:"123"
            }
        });
    </script>
</body>

</html>
  1. 获取元素时候在控制台vm.message=123即可。因为data是个方法,取值赋值时候不需要

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3oSo9thg-1677055291259)(…/…/images/image-20220721161623011.png)]

  1. 只需要在绑定的元素中使用双花括号将Vue创建的名为message属性包裹起来, 即可实现数据绑定功能, 也就实现了View Model层所需的效果, 是不是和EL表达式非常像?

1.1 v-bind 设置元素的属性 简写 :

你看到的v-bind等被称为指令。指令带有前缀v以表示它们是Vue提供的特殊特性

该指令的意思是:“将这个元素节点的title特性和Vue实例的message属性保持一致”。

如果你再次打开浏览器的JavaScript控制台, 输入app.message=‘新消息’,就会再一次看到这个绑定了title特性的HTML已经进行了更新。

简写:符号

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<style>
    .class1 {
        border: 3px solid red;
        width: 10%;
        height:10%
    }
</style>

<body>

    <!--view层,模板-->
    <div id="app">
        <!--vue绑定-->
        <span v-bind:title="message">
            鼠标悬停几秒钟查看此处动态绑定的提示信息!
        </span>
        <br />
        <span title="1111111111">
            测试span标签,效果是悬停时候会提示title属性的内容55q
        </span>
        <br />
        <span :title="message+'------'">
            鼠标悬停几秒钟查看此处动态绑定的提示信息!
        </span>

        <br /> <br /> <br />

        <p>v-bind img</p>
        <img :src="imgUrl" width="10%" height="10%">
        <p>class 属性修改 img    {{num}}</p>
        使用两种方法修改class属性
        1. 直接三元运算符
        2. 使用兑现方式实现
        <img :src="imgUrl" alt="" @click="fun1" :class="num?'class1':'' " width="10%" height="10%">
        <img :src="imgUrl" alt="" @click="fun1" :class="{class1:num}" width="10%" height="10%">
    </div>

    <!--1.导入Vue.js-->
    <script src="https://cdn.staticfile.org/vue/2.7.0/vue.min.js"></script>

    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            /*Model:数据*/
            data: {
                message: '页面加载于 ' + new Date().toLocaleString(),
                imgUrl: './1.jpg',
                num: false
            },
            methods: {
                fun1: function () {
                    this.num = !this.num;
                }
            }
        });
    </script>
</body>

</html>

1.2 v-if , v-else , v-else-if

v-if , v-else

根据表达式真假切换元素显示状态

本质是操作dom元素

true使得元素存在于元素树,反之从dom树中移除

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
    <!--view层,模板,开始数据绑定,v-if标签绑定data1-->
    <div id="div1">
        <button @click="fun1">点击按钮切换judge属性</button>
        <h1 v-if="judge">Yes</h1>
        <h1 v-else>No</h1>

    </div>

    <!--1.导入Vue.js-->
    <script src="https://cdn.staticfile.org/vue/2.7.0/vue.min.js"></script>

    <script type="text/javascript">
        var vm = new Vue({
            el: "#div1",
            /*Model:数据*/
            data: {
                judge: true
            },
            methods: {
                fun1:function(){
                    this.judge=!this.judge;
                }
            },
        });
    </script>
</body>

</html>

v-else-if

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
    <!--view层,模板-->
    <div id="app">
        <h2 v-if="type==='A'">AAA</h2>
        <h2 v-else-if="type==='B'">BBB</h2>
        <h2 v-else-if="type==='C'">CCC</h2>
        <h2 v-else>DDD</h2>
    </div>

    <!--1.导入Vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            /*Model:数据*/
            data: {
                //这里的type代表通用的意思,不是DOM的ID绑定
                type: 'A'
            }
        });
    </script>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aGreIkED-1677055291260)(…/…/images/image-20220721164028775.png)]

v-for结合v-if

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
    <!--view层,模板-->
    <div id="app">
        <li v-for="(item,index) in items">
            {{item.message}}---{{index}}
            
            <h5 v-if="index==0">11111</h5>
            <h5 v-else-if="item.message==='狂神说运维'">这是第三项内容</h5>
            <h5 v-else>这啥也不是</h5>
        </li>

    </div>

    <!--1.导入Vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            /*Model:数据*/
            data: {
                items: [
                    {message: '狂神说Java'},
                    {message: '狂神说前端'},
                    {message: '狂神说运维'}
                ]
            }
        });
    </script>
</body>

</html>

1.3 v-for 根据数据生成列表结构

格式:

<div id="app">
    <!--从index里面便利(item,index)-->
    <li v-for="(item,index) in items">
        {{item.message}}---{{index}}
    </li>
</div>

代码:

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
    <!--view层,模板-->
    <div id="app">
        <li v-for="(item,index) in items">
            {{item.message}}---{{index}}
            index是角标,从0开始,item才是每一项内容
        </li>
        ----------------------
        <p @click="fun1">添加</p> 
        <p @click="fun2">移除</p> 
        <li v-for="obj in arr">
            某一项{{obj}} - 全部{{arr}}
        </li>
        -----------------------
        <li v-for="obj1 in list">
            {{obj1}} - {{obj1.name}} - {{obj1.age}}
        </li>


    </div>

    <!--1.导入Vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            /*Model:数据*/
            data: {
                items: [{
                        message: '狂神说Java'
                    },
                    {
                        message: '狂神说前端'
                    },
                    {
                        message: '狂神说运维'
                    }
                ],
                arr: ["java", "linux", "sql", "vue"],
                list: [{
                    name: "name1",
                    age: "age1"
                }, {
                    name: "name2",
                    age: "age2"
                }]
            },
            methods:{
                //添加方法
                fun1:function(){
                    this.arr.push("111");
                    this.arr.push("222");
                },
                //移除方法
                fun2:function(){
                    this.arr.shift(this.arr[0]);
                }
            }
        });
    </script>
</body>

</html>

测试:在控制台输入vm.items.push({message:'狂神说运维'}),尝试追加一条数据,你会发现浏览器中显示的内容会增加一条狂神说运维.

1.4 v-on 监听事件 简写@

v-on监听事件,事件有Vue的事件、和前端页面本身的一些事件!我们这里的click是vue的事件,可以绑定到Vue中的methods中的方法事件!

点击事件: v-on:click="方法名"
右键事件: v-on:monseenter="方法名"
双击事件: v-on:dblclick="方法名"
		 @dblclick="方法名"
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

    <div id="app">
        <button v-on:click="sayHi">点我</button>
    </div>

    -------------------

    <div id="name1">
        <button v-on:dblclick="fun1">点我1</button>
        <button @dblclick="fun1">点我2</button>
        <button @click="fun2">改变msg1</button>
        <p>{{msg1}}</p>
    </div>


    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            data: {
                message: 'Hello World'
            },
            //所有vue方法必须放在methods里面
            methods: {
                //方法名是sayHi,参数event不添加也可以。
                sayHi: function (event) {
                    //'this'在方法里面指向当前Vue实例
                    alert(this.message);
                }
            }
        });

        var vm1=new Vue({
            el: "#name1",
            data: {
                msg1: "this is msg1"
            },
            methods: {
                fun1: function(event){
                    alert("this.msg1");
                },
                fun2: function(){
                    this.msg1="我不是黄蓉"
                }
            }

        })
    </script>
</body>

</html>

事件绑定方法写成函数调用的方式,需要传入自定义的参数

定义方法想要接受参数必须传入实参

事件修饰符可以对事件进行限制,比如限制输入的按键。

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
    <!--view层,模板-->
    <div id="app">
        <input type="button" value="无参数" @click="fun1">
        <input type="button" value="有参数" @click="fun2(111,222)">
        <br/>
        <input type="text" value="对照组">
        <input type="text" value="什么都会触发" @keyup="fun1">
        <input type="text" value="仅回车键触发" @keyup.enter="fun1">


    </div>

    <!--1.导入Vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            /*Model:数据*/
            data: {

            },
            methods:{
                fun1:function(){
                    console.log("方法已触发");
                },
                //定义形式参数
                fun2:function(num1,num2){
                    console.log(num1,num2);
                },
                fun3:function(num1,num2){
                    console.log();
                },

            }
        });
    </script>
</body>

</html>

1.5 v-text 标签文本值

  1. 单引号与双引号都可用
  2. v-text是整体替换,{{}}是局部替换
  3. 标签优先级比局部替换{{}}要高,以标签优先。
  4. 里面可以用表达式
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    <!--引入VUE-->
    <script src="https://cdn.staticfile.org/vue/2.7.0/vue.js"></script>
</head>

<body>
    <!-- 绑定元素 -->
    <div id="name1"> 
        <p v-text="msg1"></p>
        <p v-text="msg1 + '1' "></p>
        --------------------
        <p>{{ msg1 }}</p>
        --------------------
        <p>{{ msg1 + '1' }}</p>
        --------------------
        <p>{{ msg1 + "1" }}</p>
    </div>


    <script>
        var app = new Vue({
            el: '#name1', // 这里对应上面绑定的元素
            data: { // 里面存放数据+
                msg1: ' 111 '
            }
        })
    </script>
</body>

</html>

1.6 v-html

v-text标签只会解析成文本

v-html会被解析为标签

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    <!--引入VUE-->
    <script src="https://cdn.staticfile.org/vue/2.7.0/vue.js"></script>
</head>

<body>
    <!-- 绑定元素 -->
    <div id="name1"> 
        <p v-text="msg2"></p>
        <p v-html="msg2"></p>

    </div>


    <script>
        var app = new Vue({
            el: '#name1', // 这里对应上面绑定的元素
            data: { // 里面存放数据+
                msg1: ' 111 ',
                msg2: '<a href="https://www.baidu.com" >百度</a>'
            }
        })
    </script>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wLG8pYBE-1677055291261)(…/…/images/image-20230215155418190.png)]

1.7 v-show 元素的显示与隐藏

根据指令内容,修改display属性来实现效果

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

    <div id="div1">
        <button @click="fun1"> 切换文字效果1 </button>
        <button @click="fun2"> 切换文字效果2 </button>
        <button @click="fun3"> 点击按钮更换v-show条件 </button>
        <p v-show="judge">{{str1}}</p>
        <p v-show="num%2==1">{{str1}}</p>
    </div>





    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript">
        var vue = new Vue({
            el: "#div1",
            data: {
                judge: true,
                str1: "我是文字",
                num: 1
            },
            methods: {
                fun1: function () {
                    this.judge = !this.judge;
                },
                fun2: function () {
                    if (this.str1 == '我是文字') {
                        this.str1 = '我不是';
                    } else {
                        this.str1 = '我是文字';
                    }
                },
                fun3: function () {
                    this.num++;
                }
            }
        })
    </script>
</body>

</html>

1.8 v-model 获取&设置 表单元素的数值,双向绑定

双向绑定,页面改变数据也会改变。

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
    <!--view层,模板-->
    <div id="app">
        <input type="text" v-model="msg1"> msg1的数值:   {{msg1}}
        <p @click="fun1">点我可修改msg1的数值</p>
    </div>

    <!--1.导入Vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            /*Model:数据*/
            data: {
                msg1:0,
            },
            methods:{
                fun1:function(){
                    this.msg1="我是皮卡丘"
                }

            }
        });
    </script>
</body>

</html>

案例:计数器

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

    <div id="div1">
        <button @click="fun1"> + </button>
        <p>{{num}}</p>
        <button @click="fun2"> - </button>
    </div>





    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript">
        var vue = new Vue({
            el: "#div1",
            data: {
                num: 0
            },
            methods: {
                fun1: function () {
                    if(this.num<10)
                    this.num++;
                },
                fun2: function () {
                    if(this.num>0)
                    this.num--;
                }
            }
        })
    </script>
</body>

</html>

案例:图片切换

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<style>
    .class1 {
        border: 3px solid red;
        width: 20px;
        height: 20px;
    }
</style>

<body>

    <!--view层,模板-->
    <div id="app">
        
        <p>{{index}}</p>
        <p @click="fun1" v-show="index!=0">上一张</p>
        <img :src="imgArr[index]" :class=" 'class1' ">
        或者 <img :src="imgArr[index]" :class="{class1:true}">
        <p @click="fun2" v-show="index!=2">下一张</p>
    </div>

    <!--1.导入Vue.js-->
    <script src="https://cdn.staticfile.org/vue/2.7.0/vue.js"></script>

    <script type="text/javascript">
        var myVue = new Vue({
            el: "#app",
            data: {
                //定义图片数组
                imgArr: ["1.jpg", "2.jpg", "3.jpg"],
                //数组角标
                index: 0
            },
            methods: {
                fun1: function () {
                    if (this.index > 0) {
                        this.index--;
                    }

                },
                fun2: function () {
                    if (this.index < 2) {
                        this.index++;
                    }
                }

            }
        })
    </script>
</body>

</html>

案例:小黑记事本

v-for 实现数据展示
input type=’text‘ 实现输入
v-model 实现数据双向绑定
arr数组用来存储数据
v-show / v-if实现
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    .class1{
        border: red solid 6px ;
        width: 500px;
    }
</style>

<body>
    <!--view层,模板-->
    <div id="app">
        <h3>小黑记事本</h3>

        <br/>

        <div class="class1">
            <input type="text" v-model="msg" width="490px" background="blue" @keyup.enter="fun1">
            <li v-for="(item,index) in arr"  >
                {{index}} ||  {{item}}  || <img src="./1.jpg" width="60px" height="60px" v-on:click="fun2(index)">
            </li>
            <br/>
            数据总数:{{arr.length}} 
            <br/>
            <input type="button" value="删除全部点我" @click="fun3">
            <p v-show="arr.length!=0">当没有数据时候,此行文字会隐藏</p>
            <p v-if="arr.length!=0">当没有数据时候,此行文字会隐藏</p>
        </div>
    </div>

    <!--1.导入Vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            //记事本数据
            data: {
                arr:["7:00早起"],
                msg:""
            },
            methods:{
                //添加方法
                fun1:function(){
                    this.arr.push(this.msg);
                    console.log("已添加msg");
                },
                //删除方法
                fun2:function(index){
                    console.log("要删除的是:"+index)
                    this.arr.splice(index,1);
                },
                //全部删除方法
                fun3:function(){
                    console.log("要删除的是:"+this.deleteName)
                    this.arr=[];
                }
            }
        });
    </script>
</body>

</html>

知识点:绑定class属性

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">

<style>
    .class1 {
        border: 3px solid red;
        width: 20px;
        height: 20px;
    }
</style>

<body>

    <!--view层,模板-->
    <div id="app">
        

        1. :class标签内容 clas1需要单引号包起来
        <img :src="imgArr[index]" :class=" 'class1' ">
        2. 使用对象方式
        <img :src="imgArr[index]" :class="{class1:true}">
        3. 使用三元运算符
        <img :src="imgArr[index]" class="布尔值?'class1':'class2' ">

    </div>

    <!--1.导入Vue.js-->
    <script src="https://cdn.staticfile.org/vue/2.7.0/vue.js"></script>

    <script type="text/javascript">
        var myVue = new Vue({
            el: "#app"
            }
        })
    </script>
</body>

</html>

2 表单双向绑定,组件

2.1 什么是双向数据绑定

​ Vue.js是一个MVVM框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会跟着同步变化。这也算是Vue.js的精髓之处了。
  值得注意的是,我们所说的数据双向绑定,一定是对于UI控件来说的非UI控件不会涉及到数据双向绑定。单向数据绑定是使用状态管理工具的前提。如果我们使用vuex,那么数据流也是单项的,这时就会和双向数据绑定有冲突。

(1)为什么要实现数据的双向绑定

Vue.js中,如果使用vuex, 实际上数据还是单向的, 之所以说是数据双向绑定,这是用的UI控件来说, 对于我们处理表单, Vue.js的双向数据绑定用起来就特别舒服了。即两者并不互斥,在全局性数据流使用单项,方便跟踪;局部性数据流使用双向,简单易操作。

2.2 在表单中使用双向数据绑定

你可以用v-model 指令在表单<input> ,<textarea><select>元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇, 但v-model本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
  注意:v-model会忽略所有表单元素的valuecheckedselected特性的初始值而总是将Vue实例的数据作为数据来源。你应该通过JavaScript在组件的data选项中声明初始值!

单行文本

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
    <div id="app">
        输入的文本:<input type="text" v-model="message" value="hello">{{message}}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            data: {
                message: ""
            }
        });
    </script>
</body>

</html>

多行文本

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
 
<body>
    <div id="app">
        输入的文本:<input type="text" v-model="message1" value="hello">{{message1}}
        <br/>
        多行文本:<textarea v-model="message2"></textarea>多行文本是:{{message2}}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            data: {
                message1: "1",
                message2: "2"
            }
        });
    </script>
</body>

</html>

单复选框

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

    <div id="app">
        单复选框:
        <input type="checkbox" id="checkbox" v-model="checked">
        <br />
        <label for="checkbox">{{checked}}</label>
<!--
    <label> 标签为 input 元素定义标签(label)。
    label 元素不会向用户呈现任何特殊的样式。不过,它为鼠标用户改善了可用性,因为如果用户点击 label 元素内的文本,则会切换到控件本身。
    <label> 标签的 for 属性应该等于相关元素的 id 元素,以便将它们捆绑起来。
-->
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            data: {
                checked: false
            }
        });
    </script>
</body>

</html>

多复选框

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

    <div id="app">
        多复选框:
        <br>
        <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
        <label for="jack">Jack</label>

        <br>
        <input type="checkbox" id="join" value="Join" v-model="checkedNames">
        <label for="join">Join</label>

        <br>
        <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
        <label for="mike">Mike</label>
        <br>
        
        <span>选中的值:{{checkedNames}}</span>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            data: {
                checkedNames: []
            }
        });
    </script>
</body>

</html>

单选按钮

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

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

    <div id="app">

        单选框:
        <br>
        <input type="radio" name="sex" value="" v-model="data1" ><br/>
        <input type="radio" name="sex" value="" v-model="data1" ><br/>
        <p>打印选中的数据:{{data1}}</p>

    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: "#app",
            data: {
                data1: ''
            }
        });
    </script>
</body>

</html>

下拉框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    下拉框:
    <select v-model="pan">
        <option value="" disabled>---请选择---</option>
        <option disabled value="">A</option>
        <option value="bbbbb">B</option>
        <option>C</option>
        <option>D</option>
    </select>
    <span>value:{{pan}}</span>
 ## disabled表示禁用字段
 ## 当option属性有value值的时候,vue获取到的数值是对应选项的value值
 ## 没有value值的时候才会是默认的变迁内部的数据

</div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el:"#app",
        data:{
            pan:"A"
        }
    });
</script>
</body>
</html>

注意:v-model表达式的初始值未能匹配任何选项,元系将被渲染为“未选中”状态。 在iOS中, 这会使用户无法选择第一个选项,因为这样的情况下,iOS不会触发change事件。因此,更推荐像上面这样提供一个值为空的禁用选项。

知识点 v-bind 和 v-model 区分

(1)v-bind是单项数据绑定,映射关系是Model->View,我们通过Model操作就可以实现视图的联动更新。

  • 格式:v-bind:(props)=“(message)”
  • props就是组件component的元素
  • message就是vm中Data对象的数据
  • 绑定一个属性<img v-bind:src="imagesrc"/>

(2)v-model是双向数据绑定,映射关系是 View接受的数据,传给model,model的数据再传给view ,用于表单控件

3 Axios

介绍

Axios是一个开源的可以用在浏览器端和Node.js异步通信框架, 她的主要作用就是实现AJAX异步通信,其功能特点如下:

  • 从浏览器中创建XMLHttpRequests
  • 从node.js创建http请求
  • 支持Promise API[JS中链式编程]
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF(跨站请求伪造)
GitHub:https://github.com/axios/axios
中文文档:http://www.axios-js.com/~~~

由于Vue.js是一个视图层框架并且作者(尤雨溪) 严格准守SoC(关注度分离原则)所以Vue.js并不包含AJAX的通信功能, 为了解决通信问题, 作者单独开发了一个名为vue-resource的插件, 不过在进入2.0版本以后停止了对该插件的维护并推荐了Axios框架。少用jQuery, 因为它操作Dom太频繁!

3.1 第一个Axios应用程序

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

-------------------------------
get请求:
axios.get(地址?key1=value&key2=values).then(function(response){},function(err){})
post请求:
axios.post(地址,{key:value,key2:value2}).then(function(response){},function(err){})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>25-网络应用- axios基本使用</title>
</head>
<body>
    <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(笑话条数,数字)
            响应内容:随机笑话
        */
        //寻找class为get的元素节点,设置点击方法
        //axios的get方法参数是请求地址,then方法里面是成功与失败时候运行的方法。
        document.querySelector(".get").onclick=function(){
            axios.get("https://autumnfish.cn/api/joke/list?num=3")
            .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:"阿香"})
            .then(function(response){
                console.log(response);
            },function(err){
                console.log(err);
            })
        }

    </script>
</body>
</html>

案例: 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>25-网络应用- axios基本使用</title>
</head>

<body>
    <div id="app">
        {{joke}}
        <input type="button" value="get请求" id="id1" @click="fun1">
        <li v-for="item in joke">
            {{item}}
        </li>
    </div>
    <!-- 官网提供的 axios 在线地址 -->
    <script src="https://unpkg.com/axios/dist/axios.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                joke: "笑话是"
            },
            methods: {
                fun1: function () {
                    var that=this;
                    axios.get("https://autumnfish.cn/api/joke/list?num=3")
                        .then(function (response) {
                            console.log(response);
                            console.log(response.data.data);
                            console.log(response.data.data[0]);
                            that.joke=response.data.data;
                        }, function (err) {
                            console.log(err);
                        })
                }
            }
        })
    </script>
</body>

</html>

案例:网络应用[天知道]

1. 按下回车(v-on .enter)
2. 查询数据(axios 接口 v-model )
3. 渲染数据(v-for 数组 that)
应用的逻辑代码建议和页面分离,使用单独的js文件编写
axios回调函数中this指向改变了,需要额外的保存一份
服务器返回的数据比较复杂时,获取的时候需要注意层级结构

黑马代码(接口已报废)

main.js
--------------------------------
//查询天气
/*
    请求地址:http://wthrcdn.etouch.cn/weather_mini
    请求方法:get
    请求参数:city(城市名)
    响应内容:天气信息
    1.点击回车
    2.查询数据
    3.渲染数据
*/
var app = new Vue({
    el: "#app",
    data: {
        city: '',
        weatherList: []
    },
    methods: {
        searchWeather: function () {
            // console.log('天气查询');
            // 调用接口
            // 保存this
            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);
                })
                .catch(function (err) {

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

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div class="wrap" id="app">
        <div class="search_form">
            <!-- <div class="logo"><img src="img/logo.png" alt="logo"></div> -->
            <div class="form_group">
                <input type="text" v-model="city" @keyup.enter="searchWeather" class="input_txt" placeholder="请输入查询的天气">
                <button class="input_sub">
                    搜索
                </button>
            </div>
        </div>
        <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>
        <ul class="weather_list">
            <li v-for="item in weatherList">
                <div class="info_type"><span class="iconfont">{{ item.type }}</span></div>
                <div class="info_temp">
                    <b>{{ item.low }}</b>
                    ~
                    <b>{{ item.high }}</b>
                </div>
                <div class="info_date"><span>{{ item.date }}</span></div>
            </li>
        </ul>
    </div>
    <!-- 官网提供的 axios 在线地址 -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <!-- 自己的js -->
    <script src="./js/main.js"></script>
</body>

</html>

我的代码(接口可用)

http://t.weather.itboy.net/api/weather/city/城市代码
101220201
但是TMD,跨域问题我解决不了,干

案例:音乐播放器

按下回车(v-on .enter)
查询数据(axios 接口 v-model)
渲染数据(v-for 数组 that)
	服务器返回的数据比较复杂时,获取的时候需要注意层级结构
	通过审查元素快速定位到需要操纵的元素
---
点击播放(v-on 自定义参数)
歌曲地址获取(接口 歌曲id)
歌曲地址设置(v-bind)
---
点击播放(增加逻辑)
歌曲封面获取(接口 歌曲id)
歌曲封面设置(v-bind)
	在vue中通过v-bind操纵属性
	本地无法获取的数据,基本都会有对应的接口
---
按下回车(v-on .enter)
查询数据(axios 接口 v-model)
渲染数据(v-for 数组 that)
---
点击播放(增加逻辑)
歌曲评论获取(接口 歌曲id)
歌曲评论渲染(v-for---
监听音乐播放(v-on play)
监听音乐暂停(v-on pause)
操纵类名(v-bind 对象)
	audio标签的play事件会在音频播放的时候触发
	audio标签的pause事件会在音频暂停的时候触发
	通过对象的方式设置类名,类名生效与否取决于后面值的真假
---
mv图标显示(v-if)
mv地址获取(接口 mvid)
遮罩层(v-show v-on)
mv地址设置(v-bind)
    不同的接口需要的数据是不同的,文档的阅读需要仔细
    页面结构复杂之后,通过审查元素的方式去,快速定位相关元素
    响应式的数据都需要定义在data中
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" conte -nt="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <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 :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="images/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="./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: "",
        // 歌曲封面
        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?id=" + 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;
        }
    }
});

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

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

相关文章

【Npde.js】express以及nodemon

express初始Express什么是Express不使用Express可以创建web服务器吗&#xff1f;Express能做什么安装Express监听GET请求和post请求获取URL中携带的查询参数获取URL中携带的动态参数托管静态资源nodemon为什么使用nodemon初始Express 什么是Express 官方给出的概念&#xff0…

ctf pwn基础-1

在心中做了无数次决定&#xff0c;我终于还是准备学pwn了&#xff0c;为了继承学长的衣钵&#xff0c;更别说自己已经下定决心学习 c了&#xff0c;废话不多说下面正式开始。 目录 基础 实列讲解 基础 很多人一上来就叫你什么汇编啊、c啊什么的&#xff0c;让人往而却步&…

分布式任务调度处理方案(无代码)

业务涉及到&#xff0c;需要向数据库、redis、elasticsearch、MinIO写四份数据&#xff0c;这里存在分布式事务问题。如何解决问题&#xff0c;先分析cap&#xff0c;是要保证可用性&#xff0c;还是保证一致性。如何选择是CP还是AP&#xff1f;分析业务场景CP的场景&#xff1…

canvas样式与颜色,字体,图片,状态,形变

色彩 fillStyle color 设置图形的填充颜色。 strokeStyle color 设置图形轮廓的颜色。 备注&#xff1a; 一旦您设置了 strokeStyle 或者 fillStyle 的值&#xff0c;那么这个新值就会成为新绘制的图形的默认值。如果你要给每个图形上不同的颜色&#xff0c;你需要重新设置…

Java Scanner 类,超详细整理,适合新手入门

目录 一、什么是 Java Scanner 类&#xff1f; 二、引用数据类型 1、引用数据类型的定义 三、Scanner 类有哪些常用方法&#xff1f; hasNext()用法 四、next() 与 nextLine() 区别 next(): nextLine()&#xff1a; 五、使用 next 方法 五、使用 nextLine方法 一、什…

SkyWalking仪表盘使用

Skywalking仪表盘使用 1 仪表盘 作用&#xff1a;查看被监控服务的运行状态。 1)监控面板 1.1 APM APM&#xff1a;应用性能管理&#xff0c;通过各种探针采集数据&#xff0c;收集关键指标&#xff0c;同时搭配数据呈现以实现对应用程序性能管理和故障管理的系统化解决方案…

机器学习主要内容的思维导图

机器学习 机器学习&#xff1a; 定义&#xff1a;能够从经验中学习从而能够 把事情不断做好的计算机程序 人工智能的一个分支和 实现方式 理论基础&#xff1a;概率论 数理统计 线性代数 数学分析 数值逼近 最优化理论 计算复杂理论 核心要素&#xff1a;数据 算法 模型 机器…

【极海APM32替代笔记】HAL库外部定时器、系统定时器阻塞、非阻塞延时

【极海APM32替代笔记】HAL库外部定时器、系统定时器阻塞、非阻塞延时 外部定时器 采用定时器做延时使用时 需要计算好分频和计数 另外还要配置为不进行自动重载 对于50MHz的工作频率 分频为50-1也就是50M/501M 一次计数为1us 分频为50000-1也就是1k 一次计数为1ms 我配置的是…

论文解读 | [AAAI2020] 你所需要的是边界:走向任意形状的文本定位

目录 1、研究背景 2、研究的目的 3、方法论 3.1 Boundary Point Detection Network(BPDN) 3.2 Recognition Network 3.3 Loss Functions 4、实验及结果 论文连接&#xff1a;https://ojs.aaai.org/index.php/AAAI/article/view/6896 1、研究背景 最近&#xff0c;旨在…

2023美赛C题Wordle二三问分布预测和难度分类预测

文章目录前言题目介绍人数分布预测首先建立字母词典&#xff0c;加上时间特征数据预处理训练和预测函数保存模型函数位置编码模型及其参数设置模型训练以及训练曲线可视化预测人数分布难度分类预测总结前言 2023美赛选了C题&#xff0c;应该很多人会选&#xff0c;一看就好做&…

电动汽车充放电的优化调度(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

深度学习无监督磁共振重建方法调研(二)

深度学习无监督磁共振重建方法调研&#xff08;二&#xff09;Self-supervised learning of physics-guided reconstruction neural networks without fully sampled reference data&#xff08;Magnetic Resonance in Medicine 2020&#xff09;模型设计实验结果PARCEL: Physi…

如何保证数据的安全?对称和非对称加密,身份认证,摘要算法,数字证书等傻傻分不清?波哥图解带你彻底掌握

支付安全 1.基础概念 明文&#xff1a;加密前的消息叫“明文”&#xff08;plain text&#xff09; 密文&#xff1a;加密后的文本叫“密文”&#xff08;cipher text&#xff09; 密钥&#xff1a;只有掌握特殊“钥匙”的人&#xff0c;才能对加密的文本进行解密&#xff0c;…

功能测试三年,是时候做出改变了

前言 测试行业3年多经验&#xff0c;学历大专自考本科&#xff0c;主要测试方向web&#xff0c;PC端&#xff0c;wap站&#xff0c;小程序公众号都测试过&#xff0c;app也测过一些&#xff0c;C端B端都有&#xff0c;除功能外&#xff0c;接口性能也有涉猎&#xff0c;但是不…

day32 多线程(上)

文章目录相关概念codeThreadTest01ThreadTest02 编写一个类&#xff0c;直接继承java.lang.Thread&#xff0c;重写run方法ThreadTest03 实现线程的第二种方法ThreadTest04 采用匿名内部类的方式ThreadTest05 获取线程名字ThreadTest06 sleep方法sleep面试题ThreadTest08 终止线…

不同路径-力扣62-java 动态规划

一、题目描述一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。问总共有多少条不同的路径&#xff1f…

H12-831题库(有详细的解析)

1.&#xff08;单选&#xff09;某工程师利用2台路由器进行IPv6业务测试,通过运行BGP4模拟总部与分支的互联互通。如图所示,某工程师抓包查看R1发出的update报文。关于该报文信息的描述,以下哪个说法是正确的? A.该报文描述的路由的下一跳地址为:2001:db8::2345:1::1 B.该报文…

基于Pytorch,从头开始实现Transformer(编码器部分)

Transformer理论部分参考知乎上的这篇文章 Transformer的Attention和Masked Attention部分参考知乎上的这篇文章 Transformer代码实现参考这篇文章&#xff0c;不过这篇文章多头注意力实现部分是错误的&#xff0c;需要注意。 完整代码放到github上了&#xff0c;链接 Trans…

ASE50N06-ASEMI低压MOS管ASE50N06

编辑-Z ASE50N06在TO-252-2L封装里的静态漏极源导通电阻&#xff08;RDS(ON)&#xff09;为15mΩ&#xff0c;是一款N沟道低压MOS管。ASE50N06的最大脉冲正向电流ISM为200A&#xff0c;零栅极电压漏极电流(IDSS)为1uA&#xff0c;其工作时耐温度范围为-55~175摄氏度。ASE50N06…

2年手动测试,裸辞后找不到工作怎么办?

我们可以从以下几个方面来具体分析下&#xff0c;想通了&#xff0c;理解透了&#xff0c;才能更好的利用资源提升自己。一、我会什么&#xff1f;先说第一个我会什么&#xff1f;第一反应&#xff1a;我只会功能测试&#xff0c;在之前的4年的中我只做了功能测试。内心存在一种…