Vue学习笔记

Vue

文章目录

Vue基础

el:挂载点

  1. el是用来设置Vue实例挂载(管理)的元素.
  2. Vue会管理el选项命中的元素及其内部的后代元素(Vue实例的作用范围)
  3. 可以使用其他的选择器,但是建议使用ID选择器
  4. 可以使用其他的双标签,不能使用HTMLBODY

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    {{message}}
    <div id="app" class="app">
        {{message}}
        <span> {{message}}</span>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            // el: ".app",
            // el: "div",
            data: {
                message: "易烊千玺"
            }
        })
    </script>
</body>

</html>

data:数据对象

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

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        {{message}}
        <h2>{{school.name}} {{school.mobile}}</h2>
        <ul>
            <li>{{campus[0]}}</li>
            <li>{{campus[1]}}</li>
            <li>{{campus[2]}}</li>
            <li>{{campus[3]}}</li>
        </ul>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                message: "你好,易烊千玺!",
                school: {
                    name: "易烊千玺",
                    mobile: "15575566765"
                },
                campus: ["北京", "上海", "广州", "深圳"]
            }
        })
    </script>
</body>

</html>

const的使用

注意:

  1. 一旦给const修饰的标识符被赋值后,不能修改
  2. 在使用const定义标识符,必须进行赋值
  3. 常量的含义是指向的对象不能修改,但是可以改变对象内部的属性

建议:在ES6开发中,优先使用const,只有需要改变某一个标识符的时候才使用let.

插值操作

Mustache语法(也就是双大括号)

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <h2>{{message}}</h2>
  <h2>{{message}},易烊千玺</h2>
  <h2>{{firstName + lastName}}</h2>
  <h2>{{firstName +' '+lastName}}</h2>
  <h2>{{firstName}} {{lastName}}</h2>
  <h2>{{Counter * 2}}</h2>

</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:'你好啊',
      firstName:'Kobe',
      lastName:'Amy',
      Counter:100
    }
  })
</script>
</body>
</html>

v-once

  • 该指令后面不需要任何表达式(比如之前的v-for后面是由跟表达式的)
  • 该指令表示元素和组件(组件后面才会学习)只渲染一次,不会随着数据的改变而改变

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <div>{{message}}</div>
  <div v-once>{{message}}</div>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    }
  })
</script>
</body>
</html>

v-html

设置标签的innerHTML

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

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <p v-html="content"></p>
        <p v-text="content"></p>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                // content: "易烊千玺"
                content: "<a href='#'>yyqx</a>"
            }
        })
    </script>
</body>

</html>

v-text

设置标签的文本值(textContent)

  1. v-text指令的作用是:设置标签的内容(textContent)
  2. 默认写法会替换全部部分,使用差值表达式{{}} 可以替换指定内容
  3. 内部支持写表达式

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h2 v-text="message +'!'">深圳</h2>
        <h2 v-text="info +'!'">深圳</h2>
        <h2>{{message +'!'}}深圳</h2>
    </div>

    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                message: "易烊千玺!!",
                info: "前端开发"
            }
        })
    </script>
</body>

</html>

v-pre

v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
示例:
<p>{{ message }}</p> 输出:Hello World
<p v-pre>{{ message }}</p> 输出:{{ message }}
message='Hello World'

v-cloak

  • 在某些情况下,我们浏览器可能会直接显示出未编译的Mustache标签(防止显示)
  • cloak: 斗篷

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    [v-cloak]{
        display: none;
    }
  </style>
</head>
<body>

<div id="app" v-cloak>
  {{message}}
</div>

<script src="vue.js"></script>
<script>
  //在vue解析之前,div中有一个属性v-cloak
  //在vue解析之后,div中没有一个属性v-cloak
  setTimeout(function () {
    const app = new Vue({
      el: '#app',
      data: {
        message:"你好啊"
      }
    })
  },1000)
</script>

</body>
</html>

动态绑定属性

v-bind

v-bind的基本使用

设置元素的属性(比如:src,title,class

  1. v-bind指令的作用是:为元素绑定属性
  2. 完整的写法是v-bind:属性名
  3. 简写的话可以直接省略v-bind,只保留 :属性名
  4. 需要动态的增删class建议使用对象的方法

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .active {
            border: 1px solid red;
        }
    </style>
</head>

<body>
    <div id="app">
        <img v-bind:src="imgSrc" alt="">
        <br>
        <!-- 简写 -->
        <img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class="isActive?'active':''" @click="toggleActive">
        <br>
        <img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class={active:isActive} @click="toggleActive">
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                imgSrc: "images/yyqx1.jpg",
                imgTitle: "易烊千玺",
                isActive: false
            },
            methods: {
                toggleActive: function () {
                    this.isActive = !this.isActive;
                }
            }
        })
    </script>
</body>

</html>

v-bind动态绑定class(对象语法)

代码笔记:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .active {
            color: red;
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- <h2 class="active">{{massage}}</h2>
        <h2 :class="active">{{massage}}</h2> -->

        <!-- <h2 v-bind:class="{类名1:true,类名2:boolean}"></h2> -->
        <!-- <h2 v-bind:class="{active:true,line:false}">{{massage}}</h2> -->
        <!--类名会合并-->
        <h2 class="title" v-bind:class="{active:isActive,line:isLine}">{{massage}}</h2>

        <h2 v-bind:class="getClasses()">{{massage}}</h2>
        <button @click="btnClick">按钮</button>
    </div>

    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                massage: 'yyqx',
                isActive: true,
                isLine: true
            },
            methods: {
                btnClick: function () {
                    this.isActive = !this.isActive;
                },
                getClasses: function () {
                    return { active: this.isActive, line: this.isLine }
                }
            }
        })
    </script>
</body>

</html>

v-bind动态绑定class(数组语法)

  • 用的比较少

代码笔记:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h2 class="title" :class="[active,line]">{{massage}}</h2>
        <h2 class="title" :class="['active','line']">{{massage}}</h2>   <!--加单引号是本身-->
        <h2 class="title" :class="[getClasses()]">{{massage}}</h2>
    </div>

    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                massage: 'ni',
                active: 'aaaa',
                line: 'bbbb'
            },
            methods: {
                getClasses: function () {
                    return [this.active, this.line]
                }
            }
        }) 
    </script>
</body>

</html>

v-bind动态绑定style(对象语法)

代码笔记:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- <h2 :class="{类名:value}">{{massage}}</h2> -->
        <!-- <h2 :style="{key(css属性名):value(属性值)}">{{massage}}</h2> -->

        <!-- '50px' 必须加上单引号,否则是当作一个变量去解析 -->
        <!-- <h2 :style="{fontSize:'50px'}">{{massage}}</h2> -->

        <!-- finalSize当作一个变量使用 -->
        <!-- <h2 :style="{fontSize:finalSize}">{{massage}}</h2> -->
        
        <h2 :style="getStyles()">{{massage}}</h2>
    </div>

    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                massage: 'ni',
                // finalSize: '100px'
                finalSize: 100,
                finalColor: 'red'
            },
            methods: {
                getStyles: function () {
                    return { fontSize: this.finalSize + 'px', backgroundColor: this.finalColor }
                }
            }
        }) 
    </script>
</body>

</html>

v-bind动态绑定style(数组语法)

代码笔记:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h2 :style="[baseStyle,baseStyle1]">{{massage}}</h2>
    </div>

    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                massage: 'ni',
                baseStyle: { backgroundColor: 'red' },
                baseStyle1: { fontSize: '100px' }
            }
        }) 
    </script>
</body>

</html>

计算属性

计算属性的基本使用

代码笔记:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h2>{{firstName + ' ' + lastName}}</h2>
        <h2>{{firstName}} {{lastName}}</h2>
        
        <h2>{{getFullName()}}</h2>
        
        <h2>{{fullName}}</h2>    <!--不用写括号-->
        
    </div>

    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                firstName: 'Amy',
                lastName: 'Andy'
            },
            //computed: 计算属性()
            computed: {
                fullName: function () {
                    return this.firstName + ' ' + this.lastName
                }
            },
            methods: {
                getFullName() {
                    return this.firstName + ' ' + this.lastName
                }
            }
        }) 
    </script>
</body>

</html>

计算属性的复杂使用

代码笔记:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h2>总价格: {{totalPrice}}</h2>
    </div>

    <script src="vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                books: [
                    { id: 110, name: '背影', price: 119 },
                    { id: 111, name: '背影1', price: 114 },
                    { id: 112, name: '背影2', price: 113 },
                    { id: 113, name: '背影3', price: 111 }
                ]
            },
            //computed: 计算属性()
            computed: {
                totalPrice: function () {
                    let result = 0;
                    for (let i = 0; i < this.books.length; i++) {
                        result += this.books[i].price
                    }
                    return result;
                }
            }
        }) 
    </script>
</body>

</html>

计算属性的setter和getter

  • 每个计算属性都包含一个getter和一个setter
  • 在上面的例子中,我们只是使用getter来获取
  • 在某些情况下,你也可以提供一个setter方法(不常用)

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
<!--  不要加小括号-->
  <h2>{{fullName}}</h2>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      firstName:'yyqx',
      lastName:'yyds'
    },
    computed:{
      // fullName:function () {
      //   return this.firstName + ' ' +this.lastName
      // }
      // fullName:{
        // set:function () {
        //
        // },
        //计算属性一般是没有set方法,只读属性
      //   get:function () {
      //     return this.firstName + ' ' +this.lastName
      //   }
      // },


      fullName:function () {
          return this.firstName + ' ' +this.lastName
      }

    }
  })
</script>

</body>
</html>

计算属性和methods的对比

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <!-- 1.直接拼接:语法过于繁琐 -->
  <h2>{{firstName + ' ' + lastName}}</h2>

  <!-- 2.通过定义methods -->
<!--  <h2>{{getFullName()}}</h2>-->
<!--  <h2>{{getFullName()}}</h2>-->
<!--  <h2>{{getFullName()}}</h2>-->
<!--  <h2>{{getFullName()}}</h2>-->
<!--  <h2>{{getFullName()}}</h2>-->

  <!-- 3.通过computed -->
  <h2>{{fullName}}</h2>
  <h2>{{fullName}}</h2>
  <h2>{{fullName}}</h2>
  <h2>{{fullName}}</h2>
  <h2>{{fullName}}</h2>

</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      firstName:'yyqx',
      lastName:'yyds'
    },
    methods: {
      getFullName() {
        console.log('getFullName');//打印5次
        return this.firstName + ' ' + this.lastName
      }
    },
    computed: {
      fullName: function () {
        console.log('fullName');//打印1次
        return this.firstName + ' ' + this.lastName
      }
    }
  })
</script>

</body>
</html>

事件监听

v-on的基本使用

为元素绑定事件

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

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="button" value="v-on指令" v-on:click="doIt">
        <input type="button" value="v-on简写" @click="doIt">
        <input type="button" value="双击事件" @dblclick="doIt">
        <h2 @click="changeFood">{{food}}</h2>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                food: "番茄炒蛋"
            },
            methods: {
                doIt: function () {
                    alert("做IT");
                },
                changeFood: function () {
                    this.food += "好好吃!"
                }
            },
        })
    </script>
</body>

</html>

v-on参数传递问题

  1. 事件绑定的方法写成函数调用的形式,可以传入自定义参数
  2. 定义方法时需要定义形参来接受传入的实参
  3. 事件的后面跟上 .修饰符 可以对事件进行限制
  4. .enter 可以限制触发的按键为回车
  5. 事件修饰符有多种
  6. 在事件定义时,写函数时省略了小括号,但是方法本身是需要一个参数的

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="button" value="点击" @click="doIt(666,'真帅')">
        <input type="text" @keyup.enter="sayHi">
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            methods: {
                doIt: function (p1, p2) {
                    console.log('易烊千玺');
                    console.log(p1);
                    console.log(p2);
                },
                sayHi: function () {
                    alert('吃了没');
                }
            },
        })
    </script>
</body>

</html>

v-on修饰符

Vue提供了修饰符来帮助我们方便的处理一些事件:

  • .stop — 调用event.stopPropagation()。阻止事件冒泡

  • .prevent — 调用event.preventDefault()。阻止默认事件

  • .once — 只触发一次回调。

  • .enter — 可以限制触发的按键为回车

条件判断

v-if的使用

  1. v-if指令的作用是:根据表达式的真假切换元素的显示状态(操作dom元素)
  2. 本质是通过操纵dom元素来切换显示状态
  3. 表达式的值为true,元素存在与dom树中,为false,从dom树中移除
  4. 频繁的切换v-show,反之使用v-if,前者的切换消耗小

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="button" value="切换显示" @click="toggleIsShow">
        <p v-if="isShow">易烊千玺</p>
        <p v-show="isShow">易烊千玺-v-show修饰</p>
        <h2 v-if="temperature>=35">热si了</h2>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                isShow: false,
                temperature: 20
            },
            methods: {
                toggleIsShow: function () {
                    this.isShow = !this.isShow;
                }
            }
        })
    </script>
</body>

</html>

v-if和v-else的使用

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <h2 v-if="isShow">
    <div>123</div>
    <div>123</div>
    <div>123</div>
    <div>123</div>
    {{message}}
  </h2>
  <h1 v-else>isShow为false时,显示我</h1>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊",
      isShow:true
    }
  })
</script>

</body>
</html>

v-if和v-else-if和v-else的使用

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <h2 v-if="score>=90">优秀</h2>
  <h2 v-else-if="score>=80">良好</h2>
  <h2 v-else-if="score>=60">及格</h2>
  <h2 v-else>不及格</h2>

  <h1>{{result}}</h1>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      score:99
    },
    //推荐使用
    computed:{
      result(){
        let showMessage = '';
        if (this.score>=90){
          showMessage = '优秀'
        } else if (this.score >=80){
          showMessage = '良好'
        }
        //...
        return showMessage
      }
    }
  })
</script>

</body>
</html>

用户登录切换的案例

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <span v-if="isUser">
    <label for="username">用户账号</label>
    <input type="text" id="username" placeholder="用户账号" key="username">
  </span>
  <span v-else>
    <label for="email">用户邮箱</label>
    <input type="text" id="email" placeholder="用户邮箱" key="email">
  </span>
  <button @click="isUser = !isUser">切换类型</button>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      isUser:true
    },
    methods:{

    }
  })
</script>

</body>
</html>

v-show

  1. v-show指令的作用是:根据真假切换元素的显示状态
  2. 原理是修改元素的display,实现显示隐藏
  3. 指令后面的内容,最终都会解析为布尔值
  4. 值为true元素显示,值为false元素隐藏
  5. 数据改变之后,对应元素的显示状态会同步更新
  6. 频繁的切换v-show,反之使用v-if,前者的切换消耗小

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="button" value="切换显示状态" @click="changeIsShow">
        <input type="button" value="累加年龄" @click="addAge">
        <br>
        <img v-show="isShow" src="images/yyqx.jpg" alt="">
        <img v-show="age>=18" src="images/yyqx.jpg" alt="">
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                isShow: false,
                age: 17
            },
            methods: {
                changeIsShow: function () {
                    this.isShow = !this.isShow;
                },
                addAge: function () {
                    this.age++;
                }
            }
        })
    </script>
</body>

</html>

循环遍历

v-for

  1. v-for指令的作用是:根据数据生成列表结构
  2. 数组经常和v-for结合使用
  3. 语法是 (item.index) in 数据
  4. item和index可以结合其他指令一起使用
  5. 数组长度的更新会同步到页面上,是响应式的

v-for遍历数组

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
<!--  1.在遍历的过程中,没有使用索引值(下标值)-->
  <ul>
    <li v-for="item in names">{{item}}</li>
  </ul>
<!--  2.在遍历的过程中,获取索引值-->
  <ul>
    <li v-for="(item,index) in names">
      {{index+1}}.{{item}}
    </li>
  </ul>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      names:['yyqx1','yyqx2','yyxq3','yyxq4','yyxq5']
    }
  })
</script>

</body>
</html>

v-for遍历对象

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
<!--  1.在遍历对象的过程中,如果只是获取一个值,那么获取到的是value-->
  <ul>
    <li v-for="item in info">{{item}}</li>
  </ul>
  
<!--  2.获取 key 和 value -> 格式:(value,key)-->
  <ul>
    <li v-for="(value,key) in info">{{value}}-{{key}}</li>
  </ul>
  
<!--  3.获取 key 和 value 和 index -> 格式:(value,key,index)  用的很少-->
  <ul>
    <li v-for="(value,key,index) in info">{{value}}-{{key}}-{{index}}</li>
  </ul>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      info:{
        name:'yyqx',
        age: 19,
        sex: '男'
      }
    }
  })
</script>

</body>
</html>

v-for使用过程添加key属性

key属性

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <ul>
    <li v-for="item in letters" :key="item">{{item}}</li>
  </ul>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      letters:['a','b','c','d','e']
    }
  })
</script>

</body>
</html>

哪些数组的方法是响应式的

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <ul>
    <li v-for="item in letters">{{item}}</li>
  </ul>
  <button @click="btnClick">按钮</button>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      letters:['a','b','c','d','e']
    },
    methods:{
      btnClick(){
        //1.push方法(可以添加多个)
        // this.letters.push('aaa');
        // this.letters.push('aaaa','bbbb','cccc');

        //2.pop():删除数组中的最后一个元素
        // this.letters.pop();

        //3.shift():删除数组中的第一个元素
        // this.letters.shift();

        //4.unshift():在数组最前面添加元素(可以添加多个)
        // this.letters.unshift('aaa');
        // this.letters.unshift('aaaa','bbbb','cccc');

        //5.splice()
        //splice作用:删除元素/插入元素/替换元素
        //删除元素:第二个参数传入你要删除几个元素(如果没有传,就删除后面所有元素)
        //替换元素:第二个参数,表示我们要替换几个元素,后面是用来替换前面的元素
        //插入元素:第二个参数,传入0,并且后面跟上要插入的元素
        //splice(start)
        // this.letters.splice(1,2);
        // this.letters.splice(1,3,'m','n','l');
        // this.letters.splice(1,0,'x','y','z');

        //6.sort():排序
        // this.letters.sort();

        //7.reverse():反转
        // this.letters.reverse();

        //注意:通过索引值修改数组中的元素(不是响应式的)
        // this.letters[0] = 'bbb';

        // this.letters.splice(0,1,'bbbbbb');

        //set(要修改的值,索引值,修改后的值)
        Vue.set(this.letters,0,'bbbbb');
      }
    }
  })
</script>

</body>
</html>

书籍购物车案例

代码示例:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

<div id="app">
  <div v-if="books.length">
    <table>
      <thead>
      <tr>
        <th></th>
        <th>书籍名称</th>
        <th>出版日期</th>
        <th>价格</th>
        <th>购买数量</th>
        <th>操作</th>
      </tr>
      </thead>
      <tbody>
      <tr v-for="(item, index) in books">
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
        <td>{{item.data}}</td>
        <td>{{item.price | showPrice}}</td>
        <td>
          <button @click="decrement(index)" v-bind:disabled="item.count <= 1">-</button>
          {{item.count}}
          <button @click="increment(index)">+</button>
        </td>
        <td><button @click="removeHandle(index)">移除</button></td>
      </tr>
      </tbody>
    </table>
    <h2>总价格:{{totalPrice | showPrice}}</h2>
  </div>
  <h2 v-else>购物车为空</h2>
</div>

<script src="../vue.js"></script>
<script src="main.js"></script>

</body>
</html>

style.css

table {
    border: 1px solid #e9e9e9;
    border-collapse: collapse;
    border-spacing: 0;
}

th,td {
    padding: 8px 16px;
    border: 1px solid #e9e9e9;
    text-align: left;
}

th {
    background-color: #f7f7f7;
    color: #5c6b77;
    font-weight: 600;
}

main.js

const app = new Vue({
  el:'#app',
  data:{
    books:[
      {
        id:1,
        name:'《c语言》',
        data:'2021-1',
        price:85.00,
        count:1
      },
      {
        id:2,
        name:'《c++语言》',
        data:'2021-2',
        price:99.00,
        count:1
      },
      {
        id:3,
        name:'《java语言》',
        data:'2021-3',
        price:105.00,
        count:1
      },
      {
        id:4,
        name:'《c#语言》',
        data:'2021-4',
        price:89.00,
        count:1
      },
    ]
  },
  methods:{
    // getFinalPrice(price){
    //   return '¥' + price.toFixed(2)
    // }

    increment(index){
      // console.log('increment',index);
      this.books[index].count++
    },
    decrement(index){
      // console.log('decrement',index);
      this.books[index].count--
    },
    removeHandle(index){
      this.books.splice(index, 1)
    }
  },
  computed:{
    totalPrice() {
      //1.普通的for循环
      // let totalPrice = 0;
      // for(let i = 0;i < this.books.length;i++){
      //   totalPrice +=this.books[i].count * this.books[i].price;
      // }
      // return totalPrice;

      //2.for(let i in this.books)
      // let totalPrice = 0;
      // for (let i in this.books){
      //   totalPrice +=this.books[i].count * this.books[i].price;
      // }
      // return totalPrice;

      //3.for(let i of this.books)
      // let totalPrice = 0;
      // for (let item of this.books){
      //   totalPrice += item.price * item.count;
      // }
      // return totalPrice;

      //4. reduce
      return this.books.reduce(function (preValue,book) {
        return preValue + book.price * book.count
      },0)
    }
  },
  filters:{
    showPrice(price) {
      return '¥' + price.toFixed(2)
    }
  }
})

js高阶函数的使用

filter/ map/ reduce

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">

</div>

<script src="vue.js"></script>
<script>

  // js高阶函数的使用
  const nums = [10,20,111,222,333,444,30,50,60]

  // let total = nums.filter(n => n < 100).map(n => n * 2).reduce((pre, n) => pre + n);
  // console.log(total);

  let total = nums.filter(function (n) {
    return n < 100
  }).map(function (n) {
    return n * 2
  }).reduce(function (preValue,n) {
    return preValue + n
  },0)
  console.log(total);

  //1.filter函数的使用
  //filter中回调函数有一个要求:必须返回一个boolean值
  //true:当返回true时,函数内部会自动将这次回调的n加入到新的数组中
  //false:当返回false时,函数内部会过滤调这次的n
  
  // const nums = [10,20,111,222,333,444,30,50,60]
  // //10,20,30,50,60
  // let newNums = nums.filter(function (n) {
  //   return n < 100;
  // })
  // console.log(newNums);
  //
  // //2.map函数的使用
  // let new2Nums = newNums.map(function (n) {
  //   return n * 2;
  // })
  // console.log(new2Nums);
  //
  // //3.reduce函数的使用
  // //reduce作用对数组中所有的内容进行汇总
  // let total = new2Nums.reduce(function (preValue,n) {
  //   return preValue + n
  // },0)
  // console.log(total);
  //
  //第一次:preValue 0 n 20
  //第一次:preValue 20 n 40
  //第一次:preValue 60 n 60
  //第一次:preValue 120 n 100
  //第一次:preValue 220 n 120
  //340

</script>

</body>
</html>

v-model

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

  1. v-model指令的作用是便捷的设置和获取表单元素的值
  2. 绑定的数据会和表单元素的相关联
  3. 绑定的数据 <-------> 表单元素的值 (双向绑定)

v-model的基本使用

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
<!--  <input type="text" v-model="message">-->
<!--等同于-->
  <input type="text" v-bind:value="message" v-on:input="message = $event.target.value">
  
  {{message}}
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    }
  })
</script>

</body>
</html>

v-model原理

v-model其实是一个语法糖,它的背后本质上是包含两个操作:

  1. v-bind 绑定一个 value 属性
  2. v-on 指令给当前元素绑定 input 事件
<input type="text" v-model="message">
<!--等同于-->
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">

v-model结合radio类型使用(单选)

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <label for="male">
    <input type="radio" id="male" value="" v-model="sex"></label>
  <label for="female">
    <input type="radio" id="female" value="" v-model="sex"></label>
  <h2>您选择的性别是:{{sex}}</h2>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊",
      sex:'女'
    }
  })
</script>

</body>
</html>

v-model结合checkbox类型使用(单选框/多选框)

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
<!--  1.checkbox单选框-->
<!--  <label for="agree">-->
<!--    <input type="checkbox" id="agree" v-model="agree">同意协议-->
<!--  </label>-->
<!--  <h2>您选择的是:{{isAgree}}</h2>-->
<!--  <button :disabled="!isAgree">下一步</button>-->

<!--  2.checkbox多选框-->
  <label for="">
    <input type="checkbox" value="篮球" v-model="hobbies">篮球
    <input type="checkbox" value="足球" v-model="hobbies">足球
    <input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
    <input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
  </label>
  <h2>您的爱好是:{{hobbies}}</h2>
  
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊",
      isAgree:false, //单选框
      hobbies:[] //多选框
    }
  })
</script>

</body>
</html>

v-model结合select类型使用

  • 和 checkbox 一样,select 也分单选和多选两种情况。

select类型
代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <!--  1.选择一个-->
  <select name="abc" v-model="fruit">
    <option value="易烊千玺帅" >易烊千玺帅</option>
    <option value="易烊千玺帅帅">易烊千玺帅帅</option>
    <option value="易烊千玺帅帅帅">易烊千玺帅帅帅</option>
    <option value="易烊千玺帅帅帅帅">易烊千玺帅帅帅帅</option>
  </select>
  <h2>您选择的是:{{fruit}}</h2>

  <!--  1.选择多个 (按Ctrl 多选)-->
  <select name="abc" v-model="fruits" multiple>
    <option value="易烊千玺帅" >易烊千玺帅</option>
    <option value="易烊千玺帅帅">易烊千玺帅帅</option>
    <option value="易烊千玺帅帅帅">易烊千玺帅帅帅</option>
    <option value="易烊千玺帅帅帅帅">易烊千玺帅帅帅帅</option>
  </select>
  <h2>您选择的是:{{fruits}}</h2>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊",
      fruit:'易烊千玺帅',
      fruits:[]
    }
  })
</script>

</body>
</html>

input中的值绑定

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
<!--  1.checkbox单选框-->
<!--  <label for="agree">-->
<!--    <input type="checkbox" id="agree" v-model="agree">同意协议-->
<!--  </label>-->
<!--  <h2>您选择的是:{{isAgree}}</h2>-->
<!--  <button :disabled="!isAgree">下一步</button>-->

<!--  2.checkbox多选框-->
  <label for="">
    <input type="checkbox" value="篮球" v-model="hobbies">篮球
    <input type="checkbox" value="足球" v-model="hobbies">足球
    <input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
    <input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
  </label>
  <h2>您的爱好是:{{hobbies}}</h2>

<!--  值绑定-->
  <label v-for="item in originHobbies" :for="item">
    <input type="checkbox" :value="item" :id="item" v-model="hobbies">{{item}}
  </label>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊",
      isAgree:false, //单选框
      hobbies:[], //多选框
      originHobbies:['篮球','足球','羽毛球','乒乓球','排球']
    }
  })
</script>

</body>
</html>

v-model修饰符的使用

修饰符
代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <!--  1.修饰符:lazy-->
  <input type="text" v-model.lazy="message">
  <h2>{{message}}</h2>

  <!--  2.修饰符:number-->
  <input type="text" v-model.number="age">
  <h2>{{age}}-{{typeof age}}</h2>

  <!--  3.修饰符:trim(去掉空格)-->
  <input type="text" v-model.number.trim="name">
  <h2>您输入的名字是:{{name}}</h2>
</div>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊",
      age:0,
      name:''
    }
  })
</script>

</body>
</html>

组件化开发

组件的使用分为三个步骤:

  • 创建组件构造器
  • 注册组件
  • 使用组件

组件

组件化的基本使用

组件化使用
代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
<!--  3.使用组件-->
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
</div>

<script src="vue.js"></script>
<script>
  // ES6


  //1.创建组件构造器对象
  const cpnC = Vue.extend({
    template:`
      <div>
        <h2>我是标题</h2>
        <p>我是内容111</p>
        <p>我是内容222</p>
      </div>`
  })

  //2.注册组件
  Vue.component('my-cpn',cpnC)
  
  const app = 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">
  <cpn></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

<div id="app2">
  <cpn></cpn>
</div>

<script src="vue.js"></script>
<script>
  //1.创建组件构造器对象
  const cpnC = Vue.extend({
    template:`
      <div>
        <h2>我是标题</h2>
        <p>我是内容111</p>
        <p>我是内容222</p>
      </div>`
  })

  //2.注册组件(全局组件,意味着可以在多个Vue的实例下面使用)
  // Vue.component('my-cpn',cpnC)

  // 疑问:怎么注册的组件才是局部组件?

  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    },
    //局部组件
    components:{
      //cpn使用组件时的标签名
      cpn:cpnC
    }
  })

  const app2 = new Vue({
    el: '#app2'
  })
</script>

</body>
</html>

父组件和子组件

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn2></cpn2>
</div>

<script src="vue.js"></script>
<script>
  // 1.创建第一个组件构造器(子组件)
  const cpnC1 = Vue.extend({
    template:`
      <div>
        <h2>易烊千玺</h2>
        <p>帅帅帅</p>
      </div>>
    `
  })

  // 2.创建第二个组件构造器(父组件)
  const cpnC2 = Vue.extend({
    template:`
      <div>
        <h2>易烊千玺呀</h2>
        <p>帅帅帅帅</p>
        <cpn1></cpn1>
      </div>>
    `,
    components:{
      cpn1: cpnC1
    }
  })

  // root组件
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    },
    components: {
      cpn2: cpnC2
    }
  })
</script>

</body>
</html>

注册组件的语法糖写法

主要是省去了调用Vue.extend()的步骤,而是可以直接使用一个对象来代替。

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn1></cpn1>
  <cpn2></cpn2>
</div>

<script src="vue.js"></script>
<script>
  // 1.全局组件注册的语法糖
  //1.创建组件构造器对象
  // const cpn1 = Vue.extend()

  //2.注册组件
  Vue.component('cpn1',{
    template:`
      <div>
        <h2>我是标题</h2>
        <p>我是内容111</p>
      </div>`
  })

  // 2.注册局部组件的语法糖
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    },
    components:{
      'cpn2':{
        template:`
          <div>
            <h2>我是标题</h2>
            <p>我是内容222</p>
          </div>`
      }
    }
  })
</script>

</body>
</html>

组件模板的分离写法

  1. 使用 < script > 标签
  2. 使用 < template >标签

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

<!--1.script标签, 注意: 类型必须是text/x-template -->
<!--<script type="text/x-template" id="cpn">-->
<!--<div>-->
<!--  <h2>易烊千玺</h2>-->
<!--  <p>帅帅帅帅帅</p>-->
<!--</div>-->
<!--</script>-->

<!--2.template标签-->
<template id="cpn">
  <div>
    <h2>易烊千玺</h2>
    <p>帅帅帅帅帅</p>
  </div>
</template>

<script src="vue.js"></script>
<script>
  //1.注册一个全局组件
  Vue.component('cpn',{
    template:'#cpn'
  })
  
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    }
  })
</script>

</body>
</html>

组件数据的存放

  • 组件对象也有一个data属性(也可以有methods等属性)
  • 只是这个data属性必须是一个函数
  • 而且这个函数返回一个对象,对象内部保存着数据

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

<!--1.script标签, 注意: 类型必须是text/x-template -->
<!--<script type="text/x-template" id="cpn">-->
<!--<div>-->
<!--  <h2>易烊千玺</h2>-->
<!--  <p>帅帅帅帅帅</p>-->
<!--</div>-->
<!--</script>-->

<!--2.template标签-->
<template id="cpn">
  <div>
    <h2>{{title}}</h2>
    <p>帅帅帅帅帅</p>
  </div>
</template>

<script src="vue.js"></script>
<script>
  //1.注册一个全局组件
  Vue.component('cpn',{
    template:'#cpn',
    data() {
      return {
        title: '易烊千玺'  //数据存放
      }
    }
  })

  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊",
      title:'是易烊千玺呀'
    }
  })
</script>

</body>
</html>

组件中的data为什么是函数

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h2>当前计数:{{counter}}</h2>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>
<script src="vue.js"></script>
<script>
  //1.注册组件
  const obj = {
    counter: 0
  }
  Vue.component('cpn',{
    template:'#cpn',
    data() {
      return obj
    },
    methods:{
      increment() {
        this.counter++
      },
      decrement() {
        this.counter--
      }
    }
  })

  const app = 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">
  <cpn :cmovies="movies" :cmessage="message"></cpn>
</div>

<template id="cpn">
  <div>
    <ul>
      <li v-for="item in cmovies">{{item}}</li>
    </ul>
    <h2>{{cmessage}}</h2>
  </div>
</template>

<script src="vue.js"></script>
<script>
  //父传子:props
  const cpn = {
    template:'#cpn',
    
    // props:['cmovies','cmessage'],
    
    props:{
      // 1.类型限制
      // cmovies: Array,
      // cmessage: String,

      //2.提供一些默认值,以及一些必传值
      cmessage: {
        type:String,
        default: '易烊千玺',
        required: true
      },
      //类型是对象或者数组时,默认值必须是一个函数
      cmovies: {
        type: Array,
        default() {
          return []
        }
      }
    },
    data() {
      return{}
    },
    methods: {

    }
  }

  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊",
      movies: ['中国医生','送你一朵小红花','少年的你']
    },
    components: {
      cpn
    }
  })
</script>

</body>
</html>

父传子(props中的驼峰标识)

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
<!--  如果用驼峰: 加-   -->
  <cpn :c-info="info"></cpn>
</div>

<template id="cpn">
  <h2>{{cInfo}}</h2>
</template>

<script src="vue.js"></script>
<script>

  const cpn = {
    template:'#cpn',
    props:{
      cInfo: {
        type: Object,
        default() {
          return {}
        }
      }
    }
  }

  const app = new Vue({
    el: '#app',
    data: {
      info: {
        name: '易烊千玺',
        age: 100,
        height: 1.88
      }
    },
    components: {
      cpn
    }
  })
</script>

</body>
</html>

子传父(自定义事件)

什么时候需要自定义事件?

  • 当子组件需要向父组件传递数据时,就要用到自定义事件了。
  • 我们之前学习的v-on不仅仅可以用于监听DOM事件,也可以用于组件间的自定义事件。

自定义事件的流程:

  • 在子组件中,通过 $emit() 来触发事件
  • 在父组件中,通过v-on来监听子组件事件

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<!--父组件模板-->
<div id="app">
  <cpn v-on:itemclick="cpnClick"></cpn>
</div>

<!--子组件模板-->
<template id="cpn">
  <div>
    <button v-for="item in categories" @click="btnClick(item)">
      {{item.name}}
    </button>
  </div>
</template>

<script src="vue.js"></script>
<script>
  //1.子组件
  const cpn = {
    template:'#cpn',
    data() {
      return {
        categories: [
          {id:'aaa', name:'热门推荐'},
          {id:'bbb', name:'手机数码'},
          {id:'ccc', name:'家用家电'},
          {id:'ddd', name:'电脑办公'},
        ]
      }
    },
    methods: {
      btnClick(item) {
        //发射事件:自定义事件
        this.$emit('itemclick', item)
      }
    }
  }

  //2.父组件
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    },
    components: {
      cpn
    },
    methods: {
      cpnClick(item) {
        console.log('cpnClick', item);
      }
    }
  })
</script>

</body>
</html>

父子组件通信案例

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn :number1="num1"
       :number2="num2"
       @num1change="num1change"
       @num2change="num2change">
  </cpn>
</div>

<template id="cpn">
  <div>
    <h2>props:{{number1}}</h2>
    <h2>data:{{dnumber1}}</h2>
<!--    <input type="text" v-model="dnumber1">-->
    <input type="text" :value="dnumber1" @input="num1Input">
    <h2>props:{{number2}}</h2>
    <h2>data:{{dnumber2}}</h2>
<!--    <input type="text" v-model="dnumber2">-->
    <input type="text" :value="dnumber2" @input="num2Input">
  </div>
</template>
<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      num1: 1,
      num2: 0
    },
    methods: {
      num1change(value) {
        this.num1 = parseFloat(value)
      },
      num2change(value) {
        this.num2 = parseFloat(value)
      }
    },
    components: {
      cpn: {
        template:'#cpn',
        props: {
          number1: Number,
          number2: Number
        },
        data() {
          return {
            dnumber1: this.number1,
            dnumber2: this.number2
          }
        },
        methods: {
          num1Input(event) {
            //1.将input中的value赋值到dnumber中
            this.dnumber1 = event.target.value;

            //2.为了让父组件可以修改值,发出一个事件
            this.$emit('num1change', this.dnumber1);

            //3.同时修改dnumber2的值
            this.dnumber2 = this.dnumber1 * 100;
            this.$emit('num2change', this.dnumber2)
          },
          num2Input(event) {
            this.dnumber2 = event.target.value;
            this.$emit('num2change', this.dnumber2);

            //3.同时修改dnumber2的值
            this.dnumber1 = this.dnumber2 / 100;
            this.$emit('num1change', this.dnumber1)
          }
        }
      }
    }
  })
</script>

</body>
</html>

父子组件的访问

父访问子-children-refs

  • 父组件访问子组件: 使用 $children 或者 $refs

  • this.$children是一个数组类型,它包括所有的子组件对象

  • $refs => 对象类型, 默认是一个空的对象

refs
代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <cpn ref="aaa"></cpn>
  <button @click="btnClick">按钮</button>
</div>
<template id="cpn">
  <div>我是子组件</div>
</template>
<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    },
    methods: {
      btnClick() {
        // 1.$children
        // console.log(this.$children);
        // for (let c of this.$children) {
        //   console.log(c.name);
        //   c.showMessage();
        // }
        // console.log(this.$children[2].name);

        // 2.$refs => 对象类型, 默认是一个空的对象  必须加 ref='bbb'
        console.log(this.$refs.aaa.name);
      }
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            name: '我是子组件的name'
          }
        },
        methods: {
          showMessage() {
            console.log('showMessage');
          }
        }
      },
    }
  })
</script>

</body>
</html>

子访问父-parent-root

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <h2>我是cpn组件</h2>
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <ccpn></ccpn>
  </div>
</template>

<template id="ccpn">
  <div>
    <h2>我是子组件</h2>
    <button @click="btnClick">按钮</button>
  </div>
</template>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            name:'我是cpn组件的name'
          }
        },
        components: {
          ccpn: {
            template: '#ccpn',
            methods:{
              btnClick() {
                //1.访问父组件$parent
                console.log(this.$parent);
                console.log(this.$parent.name);

                //2.访问根组件$root
                console.log(this.$root);
                console.log(this.$root.message);
              }
            },
          }
        }
      }
    }
  })
</script>

</body>
</html>

组件化高级

slot-插槽的基本使用

组件的插槽:

  • 组件的插槽也是为了让我们封装的组件更加具有扩展性
  • 让使用者可以决定组件内部的一些内容到底展示什么

例子
在这里插入图片描述

  1. 插槽的基本使用 < slot>< /slot>
  2. 插槽的默认值 < slot>< button>< /button>< /slot>
  3. 如果有多个值,同时放入到组件进行替换时,一起作为替换元素

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<!--1.插槽的基本使用 <slot></slot>-->
<!--2.插槽的默认值 <slot><button></button></slot>-->
<!--3.如果有多个值,同时放入到组件进行替换时,一起作为替换元素-->

<div id="app">
  <cpn><button>按钮</button></cpn>
  <cpn><span>hhh</span></cpn>
  <cpn>
    <i>啦啦啦</i>
    <div>我是div元素</div>
    <p>我是p元素</p>
  </cpn>
  <cpn><button>按钮</button></cpn>
  <cpn></cpn>
  <cpn></cpn>
  <cpn></cpn>
</div>

<template id="cpn">
  <div>
    <h2>我是组件</h2>
    <p>我是组件,略略略</p>
<!--    <button>按钮</button>-->
    <slot><button>按钮</button></slot>
  </div>
</template>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    },
    components: {
      cpn: {
        template: '#cpn'
      }
    }
  })
</script>

</body>
</html>

slot-具名插槽的使用

slot-具名插槽的使用: 非常简单,只要给slot元素一个name属性即可。

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn><span slot="center">标题</span></cpn>
  <cpn><button slot="left">返回</button></cpn>
</div>

<template id="cpn">
  <div>
    <slot name="left"><span>左边</span></slot>
    <slot name="center"><span>中间</span></slot>
    <slot name="right"><span>右边</span></slot>

  </div>
</template>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    },
    components: {
      cpn: {
        template: '#cpn'
      }
    }
  })
</script>

</body>
</html>

什么是编译的作用域

父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
<!--  v指令  都会去Vue实例里,不会去组件里   在自己作用域中查找-->
  <cpn v-show="isShow"></cpn>
</div>

<template id="cpn">
  <div>
    <h2>我是子组件</h2>
    <p>我是内容,啦啦啦</p>
    <button v-show="isShow">按钮</button>
  </div>
</template>

<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊",
      isShow: true
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            isShow: false
          }
        }
      }
    }
  })
</script>

</body>
</html>

作用域插槽的案例

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<div id="app">
  <cpn></cpn>
  <cpn>
<!--    目的是获取子组件中的pLanguages-->
    <template slot-scope="slot">
<!--      <span v-for="item in slot.data">{{item}} - </span>-->
      <span>{{slot.data.join(' - ')}}</span>
    </template>
  </cpn>

  <cpn>
    <!--    目的是获取子组件中的pLanguages-->
    <template slot-scope="slot">
<!--      <span v-for="item in slot.data">{{item}} * </span>-->
      <span>{{slot.data.join(' * ')}}</span>
    </template>
  </cpn>

</div>

<template id="cpn">
  <div>
<!--    不一定取名data-->
    <slot :data="pLanguages">
      <ul>
        <li v-for="item in pLanguages">{{item}}</li>
      </ul>
    </slot>
  </div>
</template>
<script src="vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      message:"你好啊"
    },
    components: {
      cpn: {
        template: '#cpn',
        data() {
          return {
            pLanguages: ['html','css','js','jquery','ajax','vue','mysql']
          }
        },
        created() {
          this.pLanguages.join(' - ')
        }
      }
    }
  })
</script>

</body>
</html>

ES6的模块化实现

代码笔记:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>


<script src="aaa.js" type="module"></script>
<script src="bbb.js" type="module"></script>
<script src="mmm.js" type="module"></script>
</body>
</html>

aaa.js

var name = '小明'
var age = 18
var flag = true

function sum(num1,num2) {
  return num1 + num2
}

if(flag) {
  console.log(sum(20,30));
}

//1.导出方式一:
export {
  flag, sum
}

//2.导出方式二:
export var num1 = 1000;
export var height = 1.88

//3.导出函数/类
export function mul(num1, num2) {
  return num1 * num2
}

export class Person {
  run() {
    console.log('六六六');
  }
}

//4.export default 注意:export default 在同一个模块中,不允许同时存在多个
//某些情况下,一个模块中包含某个功能,我们并不希望给这个功能命名,而且让导入者可以自己来命名
//这个时候就可以使用 export default

// const address = '长沙市'
// export {
//   address
// }

// export const address = '长沙市'

// const address = '长沙市'
// export default address

export default function (argument) {
  console.log(argument);
}

bbb.js

import {sum} from './aaa.js'

var name = '小红'
var age = 18
var flag = false

console.log(sum(100, 200));

mmm.js


//1.导入的对象{}中定义的变量
import {flag, sum} from "./aaa.js";


if (flag) {
  console.log('小明是天才,哈哈哈');
  console.log(sum(20, 30));
}

//2.直接导入export定义的变量
import {num1,height} from "./aaa.js";

console.log(num1);
console.log(height);

//3.导入 export的function/ class
import {mul, Person} from "./aaa.js"

console.log(mul(30, 50));

const p = new Person();
p.run()

// 4.导入 export default 中的内容
import addr from "./aaa.js";

addr('你好');

//统一全部导入
import{flag, num, num, num1, height, Person, mul, sum} from "./aaa.js";//导入东西太多,不建议使用
import * as aaa from "./aaa.js"

console.log(aaa.flag);
console.log(aaa.height);

webpack的使用

安装

  • export(导出)/ import(导入)

webpack的基本使用

准备工作:

准备工作

打包: webpack ./src/main.js ./dist/bundle.js

webpack
初始化:npm init (建package.json)

npm install

将入口和出口放到一个配置文件里:

建一个webpack.config.js文件

两者一样
简写:
npm run bulid 打包相当于是使用本地webpack打包的不是全局的
简写
本地安装webpack:
npm install webpack@3.6.0 --save-dev

在终端使用的都是全局的

什么是loader

loader

css文件处理 - css-loader

css

css文件处理 - style-loader

style

less文件处理 - less - loader

less

图片文件处理 - 资源准备阶段

在这里插入图片描述

图片文件处理 - url - loader

在这里插入图片描述

图片文件处理 - file - loader

在这里插入图片描述

图片文件处理 - 修改文件名称

修改文件名称

ES6语法处理

ES6语法处理

webpack配置vue

引入vue.js: npm install vue --save

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

.vue文件封装处理

vue
示例:

在这里插入图片描述
在这里插入图片描述

App.vue (代码分离)

<template>
  <div>
    <h2 class="title">{{message}}</h2>
    <button @click="btnClick">按钮</button>
    <h2>{{name}}</h2>
  </div>
</template>

<script>
  export default {
    name: "App",
    data(){
      return {
        message: 'Hello Webpack',
        name:'yyqx'
      }
    },
    methods: {
      btnClick() {

      }
    }
  }
</script>

<style scoped>
  .title {
     color: pink;
  }
</style>

横幅plugin的使用

认识plugin

plugin

添加版权的plugin

在这里插入图片描述
结果:
在这里插入图片描述
在这里插入图片描述

打包html的plugin

在这里插入图片描述

js压缩的Plugin

在这里插入图片描述

搭建本地服务器

服务器

Vue CLI相关

什么是Vue CLI

Vue CLI

Vue CLI使用前提 - Node

node.js已安装

Vue CLI

Vue CLI使用前提 - Webpack

Webpack已安装

在这里插入图片描述

Vue CLI的使用

cli

Vue CLI2详解

 Vue CLI2详解
改Eslint

在这里插入图片描述

认识Vue CLI3

cli3
配置去哪里了
vue ui

箭头函数

箭头函数的基本使用

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>$Title$</title>
</head>
<body>

<script>
  // 箭头函数:也是一种定义函数的方式
  // 1.定义函数的方式:function
  const aaa = function () {
    
  }
  // 2.对象字面量中定义函数
  const obj = {
    bbb() {

    }
  }
  // 3.ES6中的箭头函数
  // const ccc = (参数列表) => {
  //
  // }
  const  ccc = () => {
    
  }
</script>

</body>
</html>

箭头函数参数和返回值

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>$Title$</title>
</head>
<body>

<script>
  // 1.参数问题
  // 1.1.放入两个参数
  const sum = (num1, num2) => {
    return num1 + num2
  }

  //1.2.放入一个参数
  const power = num => {
    return num * num
  }

  //2.函数中
  //2.1.函数代码块中有多行代码时
  const test = () => {
    //1.打印 Hello World
    console.log('Hello World');

    //2.打印 Hello Vuejs
    console.log('Hello Vuejs');
  }

  //2.2.函数代码块中只有一行代码
  // const mul = (num1, num2) => {
  //   return num1 * num2
  // }
  const mul = (num1, num2) => num1 * num2
  console.log(mul(20, 30));

  // const demo = () => {
  //   console.log('Hello Demo');
  // }
  const demo = () => console.log('Hello Demo');
  console.log(demo());
</script>

</body>
</html>

箭头函数中的this的使用

  • 结论: 箭头函数中的this引用的就是最近作用域中的this
  • 问题: 箭头函数中的this是如何查找的?
  • 答案: 向外层作用域中,一层层查找this,直到有this的定义

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>$Title$</title>
</head>
<body>

<script>
  //什么时候使用箭头函数
  // setTimeout(function () {
  //   console.log(this);
  // }, 1000)
  //                              (打印的都是Window)
  // setTimeout(() => {
  //   console.log(this);
  // }, 1000)

  //结论:箭头函数中的this引用的就是最近作用域中的this
  //问题:箭头函数中的this是如何查找的?
  //答案:向外层作用域中,一层层查找this,直到有this的定义
  // const obj = {
  //   aaa() {
  //     setTimeout(function () {
  //         console.log(this); //打印Window
  //       }, 1000)
  //
  //     setTimeout(() => {
  //         console.log(this); //打印Object对象
  //       }, 1000)
  //   }
  // }

  // obj.aaa()


  const obj = {
    aaa() {
      setTimeout(function () {
        setTimeout(function () {
          console.log(this);//window
        })
        setTimeout(() => {
          console.log(this);//window
        })
      })

      setTimeout(() => {
        setTimeout(function () {
          console.log(this);//window
        })
        setTimeout(() => {
          console.log(this);//object
        })
      })
    }
  }
  
  obj.aaa()
</script>

</body>
</html>

vue-router详解

什么是路由

路由(routing) 就是通过互联的网络把信息从源地址传输到目的地址的活动。

路由

后端路由阶段

后端路由
在这里插入图片描述

改变URL让页面不刷新

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

认识vue-router

目前前端流行的三大框架,都有自己的路由实现:

  • Angular的ngRouter
  • React的ReactRouter
  • Vue的vue-router

vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。

vue-router是基于路由和组件的

  • 路由用于设定访问路径,将路径和组件映射起来
  • 在vue-router的单页面应用中,页面的路径的改变就是组件的切换

安装和使用vue-router

在这里插入图片描述

router-link

在这里插入图片描述

在这里插入图片描述

修改linkActiveClass

在这里插入图片描述

路由代码跳转

在这里插入图片描述

动态路由

在这里插入图片描述

认识路由的懒加载

在这里插入图片描述

懒加载的方式

在这里插入图片描述

嵌套默认路径

在这里插入图片描述

vue-router-参数问题

在这里插入图片描述

$ route和$router是有区别的

在这里插入图片描述

导航守卫

为什么要使用导航守卫

在这里插入图片描述

导航守卫使用

在这里插入图片描述

keep-alive遇见vue-router

在这里插入图片描述

TabBar实现思路

在这里插入图片描述
代码实现:TabBar的代码实现文件

Promise

Promise是异步编程的一种解决方案。

那什么时候我们会来处理异步事件呢?

  • 一种很常见的场景应该就是网络请求了。
  • 我们封装一个网络请求的函数,因为不能立即拿到结果,所以不能像简单的3+4=7一样将结果返回。
  • 所以往往我们会传入另外一个函数,在数据请求成功时,将数据通过传入的函数回调出去。
  • 如果只是一个简单的网络请求,那么这种方案不会给我们带来很大的麻烦。

但是,当网络请求非常复杂时,就会出现回调地狱

回调地狱

Promise的基本使用

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script>
  //1.使用setTimeout
  // setTimeout(() => {
  //   console.log('yyqx');
  // }, 1000)

  //参数 -> 函数(resolve,reject)
  //resolve,reject本身它们又是函数

  //链式编程
  // new Promise((resolve,reject) => {
  //   // 第一次网络请求的代码
  //   setTimeout(() => {
  //       resolve()
  //     }, 1000)
  // }).then(() => {
  //   // 第一次拿到结果的处理代码
  //   console.log('yyqx');
  //   console.log('yyqx');
  //   console.log('yyqx');
  //   console.log('yyqx');
  //   console.log('yyqx');
  //
  //   return new Promise((resolve,reject) =>{
  //     //第二次网络请求的代码
  //     setTimeout(() => {
  //       resolve()
  //     }, 1000)
  //   })
  // }).then(() => {
  //   //第二次处理的代码
  //   console.log('yyqx');
  //   console.log('yyqx');
  //   console.log('yyqx');
  //   console.log('yyqx');
  //   console.log('yyqx');
  //
  //   return new Promise((resolve, reject) => {
  //     //第三次网络请求的代码
  //     setTimeout(() => {
  //       resolve()
  //     }, 1000)
  //   })
  // }).then(() => {
  //   //第三次处理的代码
  //   console.log('yyqx');
  //   console.log('yyqx');
  //   console.log('yyqx');
  //   console.log('yyqx');
  //   console.log('yyqx');
  // })

  // 什么情况下会用到Promise?
  // 一般情况下是有异步操作时,使用Promise对这个异步操作进行封装
  // new -> 构造函数(1. 保存了一些状态信息 2.执行传入的函数)
  // 在执行传入回调函数时,会传入两个参数, resolve,reject本身它们又是函数
  new Promise((resolve, reject) => {
    setTimeout(() => {
      // 成功的时候调用resolve
      // resolve('Hello World')

      // 失败的时候调用reject
      reject('error message')
    }, 1000)
  }).then((data) => {
      // 1.100行的处理代码
    console.log(data);
    console.log(data);
    console.log(data);
    console.log(data);
    console.log(data);
  }).catch((err) => {
    console.log(err);
  })
</script>
</body>
</html>

Promise的另外处理形式

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script>
  //then 可以传入两个参数  可以不用写catch
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Hello World')
      // reject('error message')
    }, 1000)
  }).then(data => {
    console.log(data);
  }, err => {
    console.log(err);
  })
</script>
</body>
</html>

Promise的链式调用

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script>
  // wrapped into
  // 网络请求: aaa -> 自己处理(10行)
  // 处理: aaa111 -> 自己处理(10行)
  // 处理: aaa111222 -> 自己处理

  // new Promise((resolve, reject) => {
  //   setTimeout(() => {
  //     resolve('aaa')
  //   }, 1000)
  // }).then(res => {
  //   // 1.自己处理10行代码
  //   console.log(res, '第一层的10行处理代码');
  //
  //   // 2.对结果进行第一次处理
  //   return new Promise((resolve,reject) => {
  //     // resolve(res + '111')
  //     reject('err')
  //   })
  // }).then(res => {
  //   console.log(res, '第二层的10行处理代码');
  //
  //   return new Promise(resolve => {
  //     resolve(res + '222')
  //   })
  // }).then(res => {
  //   console.log(res, '第三层的10行处理代码')
  // }).catch(err => {
  //   console.log(err);
  // })


  // new Promise(resolve => resolve(结果)) 简写
  // new Promise((resolve, reject) => {
  //   setTimeout(() => {
  //     resolve('aaa')
  //   }, 1000)
  // }).then(res => {
  //   // 1.自己处理10行代码
  //   console.log(res, '第一层的10行处理代码');
  //
  //   // 2.对结果进行第一次处理
  //   return Promise.resolve(res + '111')
  // }).then(res => {
  //   console.log(res, '第二层的10行处理代码');
  //
  //   return Promise.resolve(res + '222')
  // }).then(res => {
  //   console.log(res, '第三层的10行处理代码')
  // })


  // 省略掉Promise.resolve
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('aaa')
    }, 1000)
  }).then(res => {
    // 1.自己处理10行代码
    console.log(res, '第一层的10行处理代码');

    // 2.对结果进行第一次处理
    // return Promise.reject('error message')
    throw 'error message'
  }).then(res => {
    console.log(res, '第二层的10行处理代码');

    return res + '222'
  }).then(res => {
    console.log(res, '第三层的10行处理代码')
  }).catch(err => {
    console.log(err);
  })
</script>
</body>
</html>

链式调用简写:

在这里插入图片描述

Promise的all方法使用

代码笔记:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script>
  // let isResult1 = false
  // let isResult2 = false
  // // 请求一:
  // $ajax({
  //   url: '',
  //   success: function () {
  //     console.log('结果1');
  //     isResult1 = true
  //     handleResult()
  //   }
  // })
  // // 请求二:
  // $ajax({
  //   url: '',
  //   success: function () {
  //     console.log('结果2');
  //     isResult2 = true
  //     handleResult()
  //   }
  // })
  //
  // function handleResult() {
  //   if (isResult1 && isResult2) {
  //   }
  // }


  Promise.all([
      // new Promise((resolve, reject) => {
      //   $ajax({
      //     url: 'url1',
      //     success: function (data) {
      //       resolve(data)
      //     }
      //   })
      // }),
      // new Promise((resolve, reject) => {
      //   $ajax({
      //     url: 'url2',
      //     success: function (data) {
      //       resolve(data)
      //     }
      //   })
      // })

    new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({name: 'yyqx', age: 100})
      }, 2000)
    }),
    new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({name: 'yyqx6', age: 120})
      }, 1000)
    })

  ]).then(results => {
    console.log(results);
  })
</script>
</body>
</html>

Vuex详解

Vuex是做什么的?

在这里插入图片描述
在这里插入图片描述

单页面的状态管理

在这里插入图片描述

Vuex核心概念

Vuex有几个比较核心的概念:

  • State
  • Getters
  • Mutation
  • Action
  • Module

State单一状态树

在这里插入图片描述

Getters基本使用

在这里插入图片描述
代码示例:

在这里插入图片描述

Getters作为参数和传递参数

在这里插入图片描述
代码示例:

在这里插入图片描述

Mutation

Mutation状态更新

在这里插入图片描述

Mutation传递参数

在这里插入图片描述
代码示例:

在这里插入图片描述

Mutation提交风格

在这里插入图片描述

代码笔记:

在这里插入图片描述
在这里插入图片描述

Mutation响应规则

在这里插入图片描述
代码笔记:

在这里插入图片描述

Mutation常量类型

概念:

在这里插入图片描述
代码示例:

在这里插入图片描述

Mutation同步函数

在这里插入图片描述

Action的基本定义

Action类似于Mutation,但是是用来代替Mutation进行异步操作的。

代码示例:
在这里插入图片描述
在这里插入图片描述

Module

module

axios

在这里插入图片描述

axios的基本使用

在这里插入图片描述
代码示例:

import Vue from 'vue'
import App from './App'

import axios from 'axios'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  render: h => h(App)
})

axios({
  url: 'http://123.207.32.32:8000/home/multidata',
  method: 'get'
}).then(res => {
  console.log(res);
})

axios({
  url: 'http://123.207.32.32:8000/home/data',
  // 专门针对get请求的参数拼接
  params: {
    type: 'pop',
    page: 1
  }
}).then(res => {
  console.log(res);
})

发送并发请求

有时候,我们可能需要同时发送两个请求

  • 使用axios.all,可以放入多个请求的数组。
  • axios.all([ ]) 返回的结果是一个数组,使用 axios.spread 可将数组 [res1, res2] 展开为 res1, res2

代码笔记:

import Vue from 'vue'
import App from './App'

import axios from 'axios'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  render: h => h(App)
})

// 1.axios的基本使用
// axios({
//   url: 'http://123.207.32.32:8000/home/multidata',
//   method: 'get'
// }).then(res => {
//   console.log(res);
// })
//
// axios({
//   url: 'http://123.207.32.32:8000/home/data',
//   // 专门针对get请求的参数拼接
//   params: {
//     type: 'pop',
//     page: 1
//   }
// }).then(res => {
//   console.log(res);
// })

// 2.axios发送并发请求
// Promise.all([axios({
//   url: 'http://123.207.32.32:8000/home/multidata'
// }), axios({
//   url: 'http://123.207.32.32:8000/home/data',
//   params: {
//     type: 'sell',
//     page: 5
//   }
// })]).then(results => {
//   console.log(results);
//   console.log(results[0]);
//   console.log(results[1]);
// })

Promise.all([axios({
  url: 'http://123.207.32.32:8000/home/multidata'
}), axios({
  url: 'http://123.207.32.32:8000/home/data',
  params: {
    type: 'sell',
    page: 5
  }
})]).then(axios.spread((res1, res2) => {
  console.log(res1);
  console.log(res2);
}))

全局配置

在上面的示例中,我们的BaseURL是固定的

  • 事实上,在开发中可能很多参数都是固定的。
  • 这个时候我们可以进行一些抽取,也可以利用axios的全局配置
// 使用全局的axios和对应的配置在进行网络请求
axios.defaults.baseURL = 'http://123.207.32.32:8000'
axios.defaults.timeout = 5000

Promise.all([axios({
  url: '/home/multidata'
}), axios({
  url: '/home/data',
  params: {
    type: 'sell',
    page: 5
  }
})]).then(axios.spread((res1, res2) => {
  console.log(res1);
  console.log(res2);
}))

常见的配置选项

配置

axios的实例

在这里插入图片描述

axios封装

在这里插入图片描述

如何使用拦截器

在这里插入图片描述

项目

项目

fastclick-解决移动端300ms延迟

fastclick-解决移动端300ms延迟:
安装:npm install fastclick --save

图片懒加载-vue-lazyload框架

安装: npm install vue-lazyload --save
代码示例:
fastclick/vue-lazyload

========================================

本地应用

内容绑定,事件绑定

v-text

设置标签的文本值(textContent)

  1. v-text指令的作用是:设置标签的内容(textContent)
  2. 默认写法会替换全部部分,使用差值表达式{{}} 可以替换指定内容
  3. 内部支持写表达式

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <h2 v-text="message +'!'">深圳</h2>
        <h2 v-text="info +'!'">深圳</h2>
        <h2>{{message +'!'}}深圳</h2>
    </div>

    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                message: "易烊千玺!!",
                info: "前端开发"
            }
        })
    </script>
</body>

</html>

v-html

设置标签的innerHTML

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

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <p v-html="content"></p>
        <p v-text="content"></p>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                // content: "易烊千玺"
                content: "<a href='#'>yyqx</a>"
            }
        })
    </script>
</body>

</html>

v-on基础

为元素绑定事件

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

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="button" value="v-on指令" v-on:click="doIt">
        <input type="button" value="v-on简写" @click="doIt">
        <input type="button" value="双击事件" @dblclick="doIt">
        <h2 @click="changeFood">{{food}}</h2>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                food: "番茄炒蛋"
            },
            methods: {
                doIt: function () {
                    alert("做IT");
                },
                changeFood: function () {
                    this.food += "好好吃!"
                }
            },
        })
    </script>
</body>

</html>

本地应用-计数器

代码笔记:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <div class="input-num">
            <button @click="sub">-</button>
            <span>{{num}}</span>
            <button @click="add">+</button>
        </div>
    </div>
    <script src="vue.js"></script>
    <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>

显示切换,属性绑定

v-show

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

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="button" value="切换显示状态" @click="changeIsShow">
        <input type="button" value="累加年龄" @click="addAge">
        <br>
        <img v-show="isShow" src="images/yyqx.jpg" alt="">
        <img v-show="age>=18" src="images/yyqx.jpg" alt="">
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                isShow: false,
                age: 17
            },
            methods: {
                changeIsShow: function () {
                    this.isShow = !this.isShow;
                },
                addAge: function () {
                    this.age++;
                }
            }
        })
    </script>
</body>

</html>

v-if

  1. v-if指令的作用是:根据表达式的真假切换元素的显示状态(操作dom元素)
  2. 本质是通过操纵dom元素来切换显示状态
  3. 表达式的值为true,元素存在与dom树中,为false,从dom树中移除
  4. 频繁的切换v-show,反之使用v-if,前者的切换消耗小

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="button" value="切换显示" @click="toggleIsShow">
        <p v-if="isShow">易烊千玺</p>
        <p v-show="isShow">易烊千玺-v-show修饰</p>
        <h2 v-if="temperature>=35">热si了</h2>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                isShow: false,
                temperature: 20
            },
            methods: {
                toggleIsShow: function () {
                    this.isShow = !this.isShow;
                }
            }
        })
    </script>
</body>

</html>

v-bind

设置元素的属性(比如:src,title,class

  1. v-bind指令的作用是:为元素绑定属性
  2. 完整的写法是v-bind:属性名
  3. 简写的话可以直接省略v-bind,只保留 :属性名
  4. 需要动态的增删class建议使用对象的方法

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .active {
            border: 1px solid red;
        }
    </style>
</head>

<body>
    <div id="app">
        <img v-bind:src="imgSrc" alt="">
        <br>
        <!-- 简写 -->
        <img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class="isActive?'active':''" @click="toggleActive">
        <br>
        <img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class={active:isActive} @click="toggleActive">
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                imgSrc: "images/yyqx1.jpg",
                imgTitle: "易烊千玺",
                isActive: false
            },
            methods: {
                toggleActive: function () {
                    this.isActive = !this.isActive;
                }
            }
        })
    </script>
</body>

</html>

本地应用-图片切换(轮播图)

代码笔记:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="mask">
        <div class="center">
            <h2 class="title">
                <!-- <img src="images/yyqx1.jpg" alt=""> -->
            </h2>
            <!-- 图片 -->
            <img :src="imgArr[index]" alt="" class="y1">
            <!-- 左箭头 -->
            <a href="javascript:void(0)" v-show="index!=0" @click="prev" class="left">
                <img src="images/jiantou.png" alt="">
            </a>
            <!-- 右箭头 -->
            <a href="javascript:void(0)" v-show="index<imgArr.length-1" @click="next" class="right">
                <img src="images/jiantou.png" alt="">
            </a>
        </div>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#mask",
            data: {
                imgArr: ["images/yyqx1.jpg", "images/yyqx2.jpg", "images/yyqx3.jpg", "images/yyqx4.jpg", "images/yyqx5.jpg"],
                index: 0
            },
            methods: {
                prev: function () {
                    this.index--;
                },
                next: function () {
                    this.index++;
                }
            }
        })
    </script>
</body>

</html>

列表循环,表单元素绑定

v-for

  1. v-for指令的作用是:根据数据生成列表结构
  2. 数组经常和v-for结合使用
  3. 语法是 (item.index) in 数据
  4. item和index可以结合其他指令一起使用
  5. 数组长度的更新会同步到页面上,是响应式的

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="botton" value="添加数据" @click="add">
        <input type="botton" value="移除数据" @click="remove">
        <ul>
            <li v-for="(item,index) in arr">
                {{index + 1}}易烊千玺易烊千玺{{item}}
            </li>
        </ul>
        <h2 v-for="item in vegetables" v-bind:title="item.name">
            {{item.name}}
        </h2>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                arr: ["哈哈", "零零", "星星", "取取"],
                vegetables: [
                    { name: "西兰花炒蛋" },
                    { name: "蛋炒西兰花" }
                ]
            },
            methods: {
                add: function () {
                    this.vegetables.push({ name: "花菜炒蛋" })
                },
                remove: function () {
                    this.vegetables.shift();
                }
            },
        })
    </script>
</body>

</html>

v-on补充

  1. 事件绑定的方法写成函数调用的形式,可以传入自定义参数
  2. 定义方法时需要定义形参来接受传入的实参
  3. 事件的后面跟上 .修饰符 可以对事件进行限制
  4. .enter 可以限制触发的按键为回车
  5. 事件修饰符有多种

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="button" value="点击" @click="doIt(666,'真帅')">
        <input type="text" @keyup.enter="sayHi">
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            methods: {
                doIt: function (p1, p2) {
                    console.log('易烊千玺');
                    console.log(p1);
                    console.log(p2);
                },
                sayHi: function () {
                    alert('吃了没');
                }
            },
        })
    </script>
</body>

</html>

v-model

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

  1. v-model指令的作用是便捷的设置和获取表单元素的值
  2. 绑定的数据会和表单元素的相关联
  3. 绑定的数据 <-------> 表单元素的值 (双向绑定)

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="button" value="修改message" @click="setM">
        <input type="text" v-model="message" @keyup.enter="getM">
        <h2>{{ message }}</h2>
    </div>
    <script src="vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                message: "易烊千玺"
            },
            methods: {
                getM: function () {
                    alert(this.message);
                },
                setM: function () {
                    this.message = "zbc";
                }
            },
        })
    </script>
</body>

</html>

v-pre

v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
示例:
<p>{{ message }}</p> 输出:Hello World
<p v-pre>{{ message }}</p> 输出:{{ message }}
message='Hello World'

网络应用

axios基本使用

  1. axios必须先导入才可以使用
  2. 使用 getpost 方法即可发送对应的请求
  3. then方法中的回调函数会在请求成功或失败时触发
  4. 通过回调函数的形参可以获取响应内容,或错误信息

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <input type="button" value="get请求" class="get">
    <input type="button" value="post请求" class="post">
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        // 接口1:随机笑话
        document.querySelector(".get").onclick = function () {
            axios.get("https://autumnfish.cn/api/joke/list?num=6")
                // axios.get("https://autumnfish.cn/api/joke/list1234?num=6")
                .then(function (response) {
                    console.log(response);
                }, function (err) {
                    console.log(err);
                })
        }

        // 接口2:用户注册
        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

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

代码示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <input type="button" value="获取笑话" @click="getJoke">
        <p>{{ joke }}</p>
    </div>

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

    <script>
        // 接口:随机获取一条笑话
        // 请求地址:https://autumnfish.cn/api/joke
        // 请求方法:get
        // 请求参数:无
        // 响应内容:随机笑话

        var app = new Vue({
            el: "#app",
            data: {
                joke: "很好笑的笑话"
            },
            methods: {
                getJoke: function () {
                    // console.log(this.joke);
                    var that = this;
                    axios.get("https://autumnfish.cn/api/joke").then
                        (function (response) {
                            // console.log(response);
                            console.log(response.data);
                            // console.log(this.joke);
                            that.joke = response.data;
                        }, function (err) { })
                }
            }
        })
    </script>
</body>

</html>

综合应用

音乐播放器:
在这里插入图片描述
模板.html

<!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="./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.user.nickname}}</dd>
              <dd class="detail">
                {{item.content}}
              </dd>
            </dl>
          </div>
          <img src="images/line.png" class="right_line">
        </div>
      </div>
      <div class="audio_con">
        <audio ref='audio' @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/main0.js"></script>
</body>

</html>

main0.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)
                // axios.get("https://v1.alapi.cn/api/music/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) {
            var that = this;
            // console.log(musicId);
            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;
            this.mvUrl = "";
        }
    }
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值