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>
## 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>
## 本地应用
### 内容绑定,事件绑定(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-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-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 指令的作用是便捷的设置和获取表单元素的值 - 绑定的 数据 会和表单元素的 值 相关联 - 绑定的数据 <——> 表单元素的值
### 本地应用模板:
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 + 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>
### 天气系统范例
- 应用的逻辑代码建议和页面分离,使用 单独 的 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; } } })

浙公网安备 33010602011771号