目录
Vue基础
el:挂载点
vue实例的作用范围是什么?
vue会管理el选项命中的元素,及其内部的后代元素
是否可以使用其他的选择器?
可以,但是建议用id选择器。如class用el:".xxx",div可以用el:"div"。
是否可以设置其他的dom元素?
可以使用其他双标签,但是不能用html和body标签。
data:数据对象
vue中用到的数据定义在data中,data中可以写复杂类型的数据,对象用school.name,数组用hobby[0]的形式。渲染复杂类型数据时,遵守js的语法即可。
<body> <div id="app"> {{ message }} <h3>{{school.name}} {{school.mobile}}</h3> <ul> <li>{{hobby[0]}}</li> <li>{{hobby[1]}}</li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "Hello Vue!", school:{ name:"白白", mobile:"77777" }, hobby:["swim","dance"] } }) </script> </body>
本地应用
v-text
设置标签的文本值:
默认写法会替换全部内容,使用差值表达式{{}}可以替换指定内容。
<body> <div id="app"> <h2 v-text="message">123</h2> <h2 v-text="info">123</h2> <!-- 注意: 如果要进行部分替换,使用两个大括号的语法来写。v-text方法无效 --> <h2>{{message}}123</h2> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app=new Vue({ el:"#app", data:{ message:"hello text", info:"good day" } }) </script> </body>
效果:
v-html
设置标签的innnerHTML:
v-html和v-text使用差异对比:
当不使用html标签时,两者无区别,区别就在于v-html可以渲染出数据中的/html标签。
<body> <div id="app"> <p v-html="content"></p> <p v-text="content"></p> <p v-html="content1"></p> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app=new Vue({ el:"#app", data:{ content:"good night", content1:"<a href='http://www.baidu.com'>百度</a>" } }) </script> </body>
效果:
v-on
为元素绑定事件
click鼠标单击,monseenter鼠标移入事件,dblclick鼠标双击。
v-on:可以替换成@,效果完全相同
<body> <div id="app"> <h2 @click="changefood">{{food}}</h2> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", data:{ food:"西兰花炒蛋" }, methods: { changefood:function(){ // 通过this对象获得food值 this.food+="好好吃!" } } }) </script> </body>
计数器:
<body> <div id="app"> <button @click="sub">-</button> <span>{{num}}</span> <button @click="add">+</button> </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>0){ this.num--; }else{ alert("数值达到最小,无法再减小"); } } } }) </script> </body>
v-show
根据表达值的真假,切换元素的显示和隐藏。true是显示,false是隐藏。
原理是修改元素的display,实现显示隐藏。指令后面的内容,最终都会解析为布尔值。
<body> <div id="app"> <input type="button" value="切换显示状态" @click="changeIsShow"> <input type="button" value="年龄+1" @click="addAge"> <img v-show="isShow" src="./img/ayh.jpg" alt=""> <img v-show="age>=18" src="./img/ayh.jpg" alt=""> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/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++; console.log(this.age); } }, }) </script> </body>
v-if
根据表达值的真假,切换元素的显示和隐藏。
本质是操纵dom元素,表达式值为true,元素存在于dom树中,为false,从dom树中移除。
v-show的标签一直在, 只是改变display的状态;v-if是直接不显示这个标签。所以频繁切换的元素用v-show,反之用v-if就行。
v-bind
设置元素的属性(比如src,title,class)
v-bind:属性名=表达式
v-bind指令的作用是为元素绑定属性,完整写法是v-bind:属性名,简写的话可以直接省略v-bind,只保留:属性名。
<!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 :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class="{active:isActive}" @click="toggleIsShow"> <!-- 或者写成: --> <img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class="isActive?'active':''" @click="toggleIsShow"> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { imgSrc:"./img/ayh.jpg", imgTitle:"ayh", isActive:false }, methods: { toggleIsShow: function () { this.isActive =! this.isActive; } }, }) </script> </body> </html>
图片切换案例
分析一波:图片数据使用数组的索引的方式来切换;本质是图片的src被修改了,属性用v-bind指令;a标签在点击时需要逻辑,事件绑定用v-on指令;在第一张和最后一张时要隐藏某一个标签,使用v-show。
<!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"> <a href="#" @click="prev" v-show="index>0">上一张</a> <img :src="imgArr[index]"> <a href="#" @click="next" v-show="index<imgArr.length-1">下一张</a> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { imgArr:[ "./img/ayh.jpg", "./img/ayh.jpg", "./img/ayh.jpg", ], index:0 }, methods: { prev:function(){ this.index--; }, next:function(){ this.index++; } }, }) </script> </body> </html>
列表数据使用数组保存;v-bind指令可以设置元素属性,比如src;v-show和v-if都可以切换元素的显示状态,频繁切换用v-show。
v-for
根据数据生成列表结构,数组经常和v-for结合使用
语法是(item,index) in 数据,item为每一项、index代表索引。item和index可以结合其他指令一起使用,数组长度的更新会同步到页面上,是响应式的。
<body> <div id="app"> <ul> <li v-for="item in arr"> how was your day? {{item}} </li> </ul> <ul> <li v-for="(it,index) in arr"> {{index+1}} how was your day? {{item}} </li> </ul> <h2 v-for="item in food" v-bind:title="item.name"> {{item.name}} </h2> <input type="button" name="" id="" value="加菜" @click="add"> <input type="button" name="" id="" value="减菜" @click="remove"> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { arr:["nice","good","lucky"], food:[ {name:"apple"}, {name:"meat"}, {name:"egg"}, {name:"potato"} ] }, methods: { add:function(){ this.food.push({name:"fish"}); }, remove:function(){ this.food.shift(); } }, }) </script> </body>
效果:
v-on补充
<body> <div id="app"> <input type="button" value="点击" @click="doIt(666)"> <input type="text" @keyup.enter="sayHi"> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", methods: { doIt:function(p1){ console.log("做it"); console.log(p1); }, sayHi:function(){ alert("吃了没?"); } }, }) </script> </body>
事件绑定的方法写成函数调用的形式,可以传入自定义参数。
定义方法时需要定义形参来接收传入的实参
事件的后面跟上.修饰符可以对事件进行限制
.enter可以限制触发的按键为回车
v-model
获取和设置表单元素的值(双向数据绑定)
V-model指令的作用是边界的设置和获取表单元素的值,绑定的数据会和表单元素值相关联,绑定的数据<-->表单元素的值。
记事本案例
功能包括:新增、删除、统计、清空、隐藏。
1.新增:生成列表结构(v-for 数组),获取用户输入(v-model),回车新增数据(v-on .enter 添加数据)
2.删除:点击删除指定内容(v-on splice 索引)。
数据改变和数据绑定的元素同步改变,事件的定义参数,splice方法的作用。
3.统计:统计信息个数(v-text length)
基于数据的开发方式,v-text指令的作用
4.清空:点击清除所有信息(v-on 清空数组)
5.隐藏:没有数据时,隐藏元素(v-show v-if 数组没空)
<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <title>小黑记事本</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta name="robots" content="noindex, nofollow" /> <meta name="googlebot" content="noindex, nofollow" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" type="text/css" href="./css/index.css" /> </head> <body> <!-- 主体区域 --> <section id="todoapp"> <!-- 输入框 --> <header class="header"> <h1>小黑记事本</h1> <input v-model="inputValue" @keyup.enter="add" autofocus="autofocus" autocomplete="off" placeholder="请输入任务" class="new-todo" /> </header> <!-- 列表区域 --> <section class="main"> <ul class="todo-list"> <li class="todo" v-for="(item,index) in list"> <div class="view"> <span class="index">{{ index+1 }}.</span> <label>{{ item }}</label> <button class="destroy" @click="remove(index)"></button> </div> </li> </ul> </section> <!-- 统计和清空 --> <footer class="footer" v-show="list.length!=0"> <span class="todo-count" v-if="list.length!=0"> <strong>{{ list.length }}</strong> items left </span> <button v-show="list.length!=0" class="clear-completed" @click="clear"> Clear </button> </footer> </section> <!-- 底部 --> <footer class="info"> <p> <a href="http://www.itheima.com/"><img src="./img/black.png" alt="" /></a> </p> </footer> <!-- 开发环境版本,包含了有帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var app = new Vue({ el: "#todoapp", data: { list: ["写代码", "吃饭饭", "睡觉觉"], inputValue: "好好学习,天天向上" }, methods: { add: function () { this.list.push(this.inputValue); }, remove: function (index) { console.log("删除"); console.log(index); this.list.splice(index, 1); }, clear: function () { this.list = []; } }, }) </script> </body> </html>
网络应用
vue结合网络数据开发应用
axios
功能强大的网络请求库
<body> <input type="button" value="get请求" class="get"> <input type="button" value="post请求" class="post"> <!-- 官网提供的 axios 在线地址 --> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script> /* 接口1:随机笑话 请求地址:https://autumnfish.cn/api/joke/list 请求方法:get 请求参数:num(笑话条数,数字) 响应内容:随机笑话 */ 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:用户注册 请求地址:https://autumnfish.cn/api/user/reg 请求方法:post 请求参数:username(用户名,字符串) 响应内容:注册成功或失败 */ document.querySelector(".post").onclick = function () { axios.post("https://autumnfish.cn/api/user/reg",{username:"盐焗西兰花"}) .then(function(response){ console.log(response); console.log(this.skill); },function (err) { console.log(err); }) } </script> </body>
axios必须先导入才可以使用,使用get或post方法即可发送对应的请求,then方法中的回调函数会在请求成功或失败时触发,通过回调函数的形参可以获取响应内容或者错误信息。
axios+vue
axios如何结合vue开发网络应用
<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="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>
axios回调函数中的this已经改变,无法访问到data中数据,把this保存起来,回调函数中直接使用保存的this即可,和本地应用的最大区别就是改变了数据来源。
天知道案例
查询天气的应用
1.回车查询 -> 按下回车(v-on .enter)、查询数据(axios 接口 v-model)、渲染数据(v-for 数组 that)
应用的逻辑代码建议和页面分离,使用单独的js文件编写,axios回调函数中this指向改变了,需要额外的保存一份,服务器返回的数据比较复杂时,获取的时候需注意层级结构。
2.点击查询 -> 点击城市(v-on 自定义参数)、查询数据(this.方法())、渲染数据
自定义参数可以让代码的复用性更高,methods中定义的方法内部,可以通过this关键字点出其他的方法。
<!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>天知道</title> <link rel="stylesheet" href="css/reset.css" /> <link rel="stylesheet" href="css/index.css" /> </head> <body> <div class="wrap" id="app"> <div class="search_form"> <div class="logo"><img src="img/logo.png" alt="logo" /></div> <div class="form_group"> <input type="text" v-model="city" @keyup.enter="searchWeather" class="input_txt" placeholder="请输入查询的天气"/> <button class="input_sub"> 搜 索 </button> </div> <div class="hotkey"> <a href="javascript:;">北京</a> <a href="javascript:;">上海</a> <a href="javascript:;">广州</a> <a href="javascript:;">深圳</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_date"><span>{{ item.date }}</span></div> </li> </ul> </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> <!-- 自己的js --> <script src="main.js"></script> </body> </html>
综合运用
悦听player
歌曲搜索、歌曲播放、歌曲封面、歌曲评论、播放动画、mv播放
1.歌曲搜索 -> 按下回车(v-on .enter)、查询数据(axios 接口 v-model)、渲染数据(v-for 数组 that)
服务器返回的数据比较复杂时,获取的时候需要注意层级结构。
2.歌曲播放 -> 点击播放(v-on 自定义参数)、歌曲地址获取(接口 歌曲id)、歌曲地址设置(v-bind)
3.歌曲封面 -> 点击播放(增加逻辑)、歌曲封面获取(接口 歌曲id)、歌曲封面设置(v-bind)