2020.7.2:Vue基本语法、axios的使用、axios+vue 案例

今日学习内容:

# Vue.js:

## el 挂载点

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

  - Vue 会管理 el 选项 命中的元素 及其内部的 后代元素

  - 可以使用其他的选择器(el:".app" 或 el:"div"),但是建议使用 ID 选择器 (el:"#app")

  - 可以使用其他的双标签,但是不能使用 HTML 和 BODY 

示范:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                arr: ["北京", "上海", "广州", "深圳"]
            }
        })
    </script>
el 挂载点

## data 数据对象

   - Vue 中用到的数据定义在 data 中

  - data 中可以写 复杂类型 的数据

  - 渲染复杂类型数据时,遵守 js 的语法即可

示范:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                arr: ["北京", "上海", "广州", "深圳"]
            }
        })
    </script>
data 数据对象

## 本地应用

### 内容绑定,事件绑定(v-text、 v-html、 v-on基础)

1. v-text
  - v-text 指令的作用是:设置标签的内容(textContent)

  - 默认写法会替换全部内容,使用 差值表达式 {{}} 可以替换指定内容

  - 内部支持写表达式

2. v-html
  - v-html 指令的作用是:设置元素的 innerHTML

  - 内容有 html 结构会被解析为 标签

  - v-text 指令无论内容是什么,只会解析为 文本

  - 解析文本使用 v-text,需要解析 html 结构使用 v-html

3. v-on
  - v-on 指令的作用是:为元素绑定事件

  - 事件名不需要写 on

  - 指令可以简写为 @

  - 绑定的方法定义在 methods 属性中

4. 总结:
  - 创建 Vue 实例时,(el 挂载点)、(data 数据)、(methods 方法)

  - v-on 指令的作用是绑定事件,简写为 @

  - 方法中通过 this ,关键字获取 data 中的数据

  - v-text 指令的作用是:设置元素的 文本值,简写为{{}}

  - v-html 指令的作用是:设置元素的 innerHTML

示范:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>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="https://cdn.jsdelivr.net/npm/vue/dist/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 > 1) {
                        this.num--;
                    } else {
                        alert("已经加到顶部了");
                    }

                }
            },
        })
    </script>
</body>

</html>
v-test、v-html、v-on基础 定义

### 显示切换,属性绑定(v-show、 v-if、 v-bind)

1. v-show

  - v-show 指令的作用是:根据真假切换元素的显示状态

  - 原理是修改元素的 display ,实现显示隐藏

  - 指令后面的内容,最终都会解析为布尔值

  - 值为 true 元素显示,值为 false 元素隐藏

2. v-if

  - v-if 指令的作用是:根据表达式的真假切换元素的显示状态

  - 本质是通过操纵 dom 元素来切换显示状态

  - 表达式的值为 ture,元素存在于 dom 树中;值为 false,从 dom 树中移除

  - 频繁地切换用 v-show,反之使用 v-if,前者的切换消耗小

3. v-bind 

  - v-bind 指令的作用是:为元素绑定属性

  - 完整写法是 v-bind:属性名

  - 简写的话可以直接省略 v-bind,只保留 :属性名

  - 需要动态的增删 class 建议使用对象的方式

4. 总结
        
  - 列表数据使用 数组 保存

  - v-bind 指令可以设置元素属性,比如 src

  - v-show 和 v-if 都可以切换元素的显示状态,频繁切换用 v-show

示范:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>v-bind指令</title>
    <style>
        .left {
            position: absolute;
            left: 20px;
            top: 200px;
        }

        .right {
            position: absolute;
            left: 450px;
            top: 200px;
        }

        .clearfix {
            content: "";
            display: block;
            clear: both;
        }

        .backGround {
            width: 500px;
            height: 500px;
        }
    </style>
</head>

<body>
    <div id="mask">
        <div class="center clearfix">
            <h2 class="title">
                <img src="" alt="">
                深圳创维校区环境
            </h2>
            <img :src="imgArr[index]" alt="" class="backGround">
            <a href="#" class="left" @click="prev" v-show="index!=0">
                <img src="./images/pre.jpg" alt="">
            </a>
            <a href="#" class="right" @click="next" v-show="index<imgArr.length-1">
                <img src="./images/next.jpg" alt="">
            </a>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el: "#mask",
            data: {
                imgArr: [
                    "./images/img01.jpg",
                    "./images/img02.jpg",
                    "./images/img03.jpg",
                    "./images/img04.jpg",
                    "./images/img05.jpg",
                    "./images/img06.jpg",
                    "./images/img07.jpg",
                    "./images/img08.jpg",
                    "./images/img09.jpg",
                    "./images/img10.jpg",
                ],
                index: 0
            },
            methods: {
                prev: function () {
                    this.index--;
                },
                next: function () {
                    this.index++;
                }
            }
        })
    </script>
</body>

</html>
v-show、v-if、v-bind 定义

### 列表循环,表单元素绑定(v-for、 v-on补充、 v-model)

 1. v-for

  - v-for 指令的作用是:根据数据生成列表结构

  - 数组经常和 v-for 结合使用

  - 语法是 (item,index) in 数据

  - item 和 index 可以结合其他指令一起使用

  - 数组长度的更新会同步到页面上,是响应式的

 2. v-on 补充

  - 事件绑定的方法写成 函数调用 的形式,可以传入自定义参数

  - 定义方法时需要定义 形参 来接收传入的实参

  - 事件的后面跟上 .修饰符 可以对事件进行限制

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

  - 事件修饰符有多种:{ 文档传送门:https://cn.vuejs.org/v2/api/#v-on }

 3. v-model

  - v-model 指令的作用是便捷的设置和获取表单元素的值

  - 绑定的 数据 会和表单元素的 值 相关联

  - 绑定的数据 <——> 表单元素的值
v-for、v-on 补充、v-model 定义

### 本地应用模板:

1. 增加

  - v-for 根据数组形成列表结构

  - v-model 双向绑定数据,可以把表单元素的内容盒和绑定的数据关联起来

  - v-on 可以绑定时间,@ketyp.enter="";

2. 删除

  - 数据改变,和数据绑定的元素 同步 改变

  - 事件的 自定义参数

  - splice(index,position) 方法的作用

3. 统计

  - 基于数据的开发方式 (list.length)

  - v-text 指令的作用   ——   {{}}差值表达式

4. 清空

  - 基于数据的开发方式 (list : [])

5. 隐藏

  - 没有数据时,隐藏元素 (v-show   v-if)

总结:

  - 列表结构可以通过 v-for 指令结合数据生成

  - v-on 结合事件修饰符可以对事件进行限制,比如 .enter

  - v-on 在绑定时间时可以传递自定义参数

  - 通过 v-model 可以快速的设置和获取表单元素的值

  - 基于数据的开发方式
本地应用模板

## 网络应用

### axios 的使用

 格式:
    - axios.get("url?num=x").then(function(response){},function(err){})
    - axios.post("url",{username:"jack").them(function(response){},function(err){})
  - axios必须先导入才可以使用

  - 使用 get 或 post 方法即可发送对应的请求 

 // 接口1:随机笑话
        // 请求地址:https://autumnfish.cn/api/joke/list
        // 请求方法:get
        // 请求参数:num (笑话条数,数字)
        // 响应内容:随机笑话

    get:  axios.get("https://autumnfish.cn/api/joke/list?num=6")

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

        // 接口2:用户注册
        // 请求地址:https://autumnfish.cn/api/user/reg
        // 请求方法:post
        // 请求参数:username(用户名,字符串)
        // 响应内容:注册成功或失败

    post:  axios.post("https://autumnfish.cn/api/user/reg", { username: "jack" })

                        .then(function (response) {
                            console.log(response);
                        },function(err){
                            console.log(err);
                        })
  - then 方法中的回调函数会在请求成功或失败时触发

  - 通过回调函数的形参可以获取 响应内容 或 错误信息

文档传送门:https://github.com/axios/axios  或   http://www.axios-js.com/zh-cn/docs/
axios 的使用

### 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>axios+vue</title>
</head>

<body>
    <div id="app">
        <input type="button" value="获取笑话" @click="getJoke">
        <p>{{joke}}</p>
    </div>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>

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

        var app = new Vue({
            el: "#app",
            data: {
                joke: "很好笑的笑话"
            },
            methods: {
                getJoke: function () {
                    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>
axios + vue 的使用

 ### 天气系统范例

  - 应用的逻辑代码建议和页面分离,使用 单独 的 js 文件编写

  - axios 回调函数中 this 指向改变了,需要额外的保存一份

  - 服务器返回的数据比较复杂时,获取的时候需要注意 层级 结构

  - 自定义参数可以让代码的 复用性 更高

  - methods 中定义的方法内部,可以通过 this 关键字点出其他的方法

示范:

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

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

<body>
    <div class="wrap" id="app">
        <div class="search_form">
            <div class="logo">
                <img src="./images/logo.jpg" alt="logo">
            </div>
            <div class="form_group">
                <input type="text" v-model="city" @keyup.enter="searchWeather" class="input_text"
                    placeholder="请输入查询的天气">
                <button class="input_sub">
                    搜索
                </button>
            </div>
            <div class="hotkey">
                <a href="#" @click="changeCity('北京')">北京</a>
                <a href="#" @click="changeCity('上海')">上海</a>
                <a href="#" @click="changeCity('广州')">广州</a>
                <a href="#" @click="changeCity('深圳')">深圳</a>
            </div>
        </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_data">
                    <span>
                        {{item.date}}
                    </span>
                </div>
            </li>
        </ul>
    </div>

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="./js/main.js"></script>
</body>

</html>

//JavaScript 代码
/*
        请求地址: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("天气查询");
            // console.log(this.city);
            // 调用接口
            // 保存this
            var that = this;
            axios.get("http://wthrcdn.etouch.cn/weather_mini?city=" + this.city)
                .then(function (response) {
                    // console.log(response);
                    console.log(response.data.data.forecast);
                    that.weatherList = response.data.data.forecast;
                })
                .catch(function (err) { })
        },
        changeCity: function (city) {
            this.city = city;
            this.searchWeather();
        }
    }
})
天气系统范例

 ### 音乐播放器范例

1. 歌曲搜索 (思路:1. 按下回车(v-on.enter)、 2. 查询数据(axios 接口  v-model)、3. 渲染数据(v-for 数组 that))

  - 服务器返回的数据比较复杂时,获取的时候需要注意 层级 结构

  - 通过 审查元素 快速定位到需要操纵的元素

2. 歌曲播放 (思路:1. 点击播放(v-on 自定义参数)、2. 歌曲地址获取(接口  歌曲id )、3. 歌曲地址设置(v-bind))

  - 歌曲id 依赖 歌曲搜索 的结果,对于不用的数据也需要关注

3. 歌曲封面 (思路:1. 点击播放(增加逻辑)、 2. 歌曲封面获取 (接口 歌曲id )、歌曲封面设置(v-bind))

  - 在 vue  中通过 v-bind 操纵属性

  - 本地无法获取的数据,基本都会有对应的 接口 

4. 歌曲评论 (思路: 1. 点击播放 (增加逻辑)、 2. 歌曲评论获取(接口 歌曲id)、 3. 歌曲评论渲染(v-for))

  - 在 vue 中通过 v-for 生成列表

5. 播放动画 (思路: 1. 监听音乐播放(v-on play)、 2. 监听音乐暂停(v-on pause) 、 3. 操纵类名(v-bind 对象))

  - audio 标签的 play 事件会在音频播放的时候触发

  - audio 标签的 pause 事件会在音频暂停的时候触发

  - 通过 对象 的方式设置类名,类名生效与否取决于后面值的 真假

6. mv 播放 (思路: 1. mv 图标显示(v-if)、2. mv 地址获取(接口 mvid)、3. 遮罩层(v-show  v-on)、4. mv地址设置(v-bind))

  - 不同的接口需要的数据是 不同 的,文档的阅读需要 仔细

  - 页面结构复杂之后,通过 审查元素 的方式去 快速定位 相关元素

  - 响应式的数据都需要定义在 data 中定义

示范:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>悦听player</title>
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    <style>
        .left {
            float: left;
        }

        .right {
            float: right;
        }

        .clearfix {
            content: "";
            display: block;
            clear: both;
        }

        .center_con {
            position: relative;
        }

        .wrap {
            width: 1500px;
        }

        .song_list li a {
            width: 50px;
            height: 50px;
        }

        .play_wrap {
            position: relative;
        }

        .player_con {
            position: fixed;
            top: 200px;
            left: 200px;
        }

        .player_con .play_bar {
            position: fixed;
            top: 200px;
            left: 200px;
            width: 600px;
            height: 600px;
            border-radius: 50%;
            background-color: red;
        }

        .player_con .cover {
            position: fixed;
            top: 309px;
            left: 300px;
            width: 390px;
            height: 380px;
            border-radius: 50%;
        }

        .comment_wrapper {
            width: 500px;
            position: absolute;
            top: 30px;
            right: 180px;
            height: 800px;
        }

        .comment_wrapper .comment_list img {
            width: 50px;
            height: 50px;
            border-radius: 50%;
            left: 20px;
        }

        .comment_wrapper .comment_list .dl {
            margin-top: 10px;
        }

        .comment_wrapper .comment_list .name {
            width: 300px;
        }

        .comment_wrapper .comment_list .detail {
            width: 300px;
        }

        .playing {
            animation: rotate 5s linear infinite;
        }

        @keyframes rotate {
            0% {
                rotate: 90%;
            }

            50% {
                rotate: 180%;
            }

            100% {
                rotate: 360%;
            }
        }

        .fo {
            width: 10px;
            height: 10px;
            background-color: red;
            border-radius: 50%;
            cursor: pointer;
        }
    </style>
</head>

<body>
    <div class="wrap">
        <!-- 播放器主体区域 -->
        <div class="play_wrap" id="player">
            <div class="search_bar">
                <img src="" 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="#" @click="playMusic(item.id)">icon</a>
                            <b>{{item.name}}</b>
                            <span v-if="item.mvid!=0" @click="playMV(item.mvid)"><i class="fo">图标</i></span>
                        </li>
                    </ul>
                    <img src="" class="switch_btn" alt="">
                </div>
                <!-- 歌曲信息容器 -->
                <div class="player_con" :class="{playing:isPlaying}">
                    <img src="./images/bar.jpg" class="play_bar" alt="">
                    <!-- 黑胶碟片 -->
                    <img src="#" class="disc autoRotate" alt="">
                    <img :src="musicCover" class="cover autoRotate" alt="">
                </div>
            </div>
            <div class="comment_wrapper">
                <h5 class="title">热门留言</h5>
                <div class="comment_list">
                    <dl v-for="item in hotComments" class="dl">
                        <dt>
                            <img :src="item.user.avatarUrl" alt="">
                        </dt>
                        <dd class="name">{{item.user.nickname}}</dd>
                        <dd class="detail">{{item.content}}</dd>
                    </dl>
                </div>
            </div>
            <div class="audio_con">
                <audio :src="musicUrl" @play="play" @pause="pause" ref="audio" controls autoplay loop
                    class="my_audio"></audio>
            </div>
            <video src="" style="display: none;" class="video_con" v-show="isShow">
                <video :src="mvUrl" controls></video>
                <div class="mask" @click="hide"></div>
            </video>
        </div>
    </div>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="./js/yue_ting_main.js"></script>
</body>
</body>

</html>


/*
    歌曲搜索接口
    请求地址:https://autumnfish.cn/search
    请求方法:get
    请求参数:keywords(查询关键字)
    响应内容:歌曲搜索结果

    歌曲 url 获取
    请求地址:https://autumnfish.cn/song/url
    请求方法:get
    请求参数:id(歌曲 id)
    响应内容:歌曲的 url 地址

    歌曲详情获取
    请求地址:https://autumnfish.cn/song/detail
    请求方法:get
    请求参数:ids(歌曲id)
    响应内容:歌曲详情,包含封面信息

    热门评论获取
    请求地址:https://autumnfish.cn/comment/hot?type=0
    请求方法:get
    请求参数:id(歌曲 id , type 固定为0)
    响应内容:歌曲的热门评论

    mv地址获取
    请求地址:https://autumnfish.cn/mv/url
    请求方法:get
    请求参数:id(mvid,为 0 说明没有mv)
    响应内容:mv 的地址
*/

var app = new Vue({
    el: "#player",
    data: {
        // 查询关键字
        query: "",
        // 歌曲数组
        musicList: [],
        // 歌曲地址
        musicUrl: "",
        // 歌曲封面
        musicCover: "",
        // 歌曲评论
        hotComments: [],
        // 动画播放状态
        isPlaying: false,
        // 遮罩层的显示状态
        isShow: false,
        // mv地址
        mvUrl: ""
    },
    methods: {
        // 歌曲搜索
        searchMusic: function () {
            var that = this;
            axios.get("https://autumnfish.cn/search?keywords=" + this.query)
                .then(function (response) {
                    // console.log(response);
                    that.musicList = response.data.result.songs;
                    console.log(response.data.result.songs);
                }, function (err) { })
        },
        // 歌曲播放
        playMusic: function (musicId) {
            // console.log(musicId);
            var that = this;
            // 获取歌曲地址
            axios.get("https://autumnfish.cn/song/url?id=" + musicId)
                .then(function (response) {
                    // console.log(response);
                    // console.log(response.data.data[0].url);
                    that.musicUrl = response.data.data[0].url;
                }, function (err) { })

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

            // 歌曲评论获取
            axios.get("https://autumnfish.cn/comment/hot?type=0&id=" + musicId)
                .then(function (response) {
                    // console.log(response);
                    // console.log(response.data.hotComments);
                    that.hotComments = response.data.hotComments;
                }, function (err) { })
        },
        // 歌曲播放
        play: function () {
            // console.log("play");
            this.isPlaying = true;
        },
        // 歌曲暂停
        pause: function () {
            // console.log("pause");
            this.isPlaying = false;
        },
        // 播放mv
        playMV: function (mvid) {
            var that = this;
            axios.get("https://autumnfish.cn/mv/url?id=" + mvid)
                .then(function (response) {
                    // console.log(response);
                    // console.log(response.data.data.url);
                    that.isShow = true;
                    that.mvUrl = response.data.data.url;
                }, function (err) { })
        },
        // 隐藏
        hide: function () {
            this.isShow = false;
        }
    }
})
音乐播放器范例

 

posted @ 2020-07-02 13:08  青山绿水ccc  阅读(235)  评论(0)    收藏  举报