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;
        }
    }
});

Logo

前往低代码交流专区

更多推荐