Vue基础
Vue是什么,能干嘛?
JavaScript的框架
快速起步Vue
看一看官网(Vue官网)
所以,现在就新建一个HTML文件,并且引入一个Vue库
新建一个html文件之后,输入html就可以选择生成模板了
选中并且回车就可以创建了
运行一下
步骤总结
el:挂载点
何为el?el就是element元素的简称
选择器类型
几种选择器选一种用就可以了,默认推荐使用id选择器,因为类选择器和标签选择器容易命中多个元素
data属性:数据对象
几种数据类型,字符串、对象、数组
如何获取数据
获取字符串
获取对象的某个属性
直接{{对象.属性值}}就可以获取,想取其他属性的话就再跟一个{{对象.属性值}}就可以获取
获取数组的内容
表达式:、
<ul>
<li> {{数组名称[数组下标]}} <li>
<li> {{数组名称[数组下标]}} <li>
<li> {{数组名称[数组下标]}} <li>
<ul>
总结:
Vue指令
v-text赋值文本内容
作用:将数据设置给标签的文本内容,设置标签的文本值(textContent)
<h2 v-text="绑定对象data的key+'拼接的内容'">内部内容测试</h2>
<h2 v-text="对象.属性值"></h2>
表达式也可以进行拼接
总结:
v-html解析html代码
作用:设置标签的innerHtml,能够识别并且解析html代码,而不是html代码变成文字
<p v-html="绑定对象">这里的内容会被覆盖!</p>
<h2 v-html="绑定对象">这里的内容会被覆盖!</h2>
...诸如此类的用法
总结:
v-on为元素绑定事件
作用:为元素绑定事件
<input type="button" v-on:触发方式="函数名" value="按钮内的内容">
<input type="button" @触发方式="函数名" value="按钮内的内容"/>
效果
如何获取同一个app对象下(挂载数据)的内容呢?
this.data数据中的key就可以获取
案例:
总结:
补充
实现一个计数器
计数器长这个样子
body体里面的代码,其他头部的代码没啥用,这里不赘述了
这里改了一点点需求,加随便加,减不能减过0
<body>
<div id="app">
<button @click="add()">+</button>
<span v-text="result">{{result}}</span>
<button @click="sub()">-</button>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
result: 10,
},
methods:{
add:function(){
this.result++;
},
sub:function(){
if(this.result==0){
alert("已经为0了,不能再减!")
return 0;
}
this.result--;
}
}
})
</script>
</body>
还就那个效果拔群
总结
v-show元素显示和隐藏
表达式的真假来切换元素的显示状态标签内部的一个元素,true和false来标示元素是否能够显示
注意:频繁切换的话用v-show更好
v-show="true(显示)/false(不显示)"
定义在data中
同时也支持表达式的运算
实例:
切换显示效果的小demo
需求是按键来切换元素的显示
这里只写body体内部的代码,其他的部分写出来意义不大
单击按钮实现图片的显示
<body>
<div id="app">
<button @click="isShowEl()">"是否显示元素?"</button>
<img src="图片路径" v-show="isShow" />
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
isShow:false,
},
methods:{
isShowEl:function(){
this.isShow=!this.isShow;
}
}
})
</script>
</body>
总结:
v-if元素显示和隐藏
根据表达式的真假,切换元素的显示和隐藏
v-if是来操作不频繁切换的元素更好
注意:频繁切换的话用v-show更好
原理就是操纵dom树,加入display:none属性,不显示的时候就改为true
v-show与v-if的区别
1.手段:v-if是通过控制dom节点的存在与否来控制元素的显隐;v-show是通过设置DOM元素的display样式,block为显示,none为隐藏;
2.编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;
3.编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留;
4.性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;
语法和上面的v-show差不多
总结
v-bind操纵属性
设置元素的属性
语法:
简略写法
成功操纵样式的显示
总结
实现一个图片切换案例
长这个样子
具体思路:
老规矩,只写body里的代码
<body>
<div id="app">
<button @click="preImg()" v-show="index!=0">切换上一张</button>
<img v-bind:src=imgArray[index] />
<button @click="nextImg()" v-show="index!=imgArray.length-1">切换下一张</button>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
imgArray:[
"./img/01.png",
"./img/02.png",
"./img/03.png",
"./img/04.png",
"./img/05.png"
],
index:0,
},
methods:{
preImg:function(){
this.index--;
},
nextImg:function(){
this.index++;
}
}
})
</script>
</body>
单机按钮来切换上下张
亮点:用v-bind来动态的操作img标签内的src元素的属性是最重要的
总结:
v-for
响应式的根据数据生成列表结构
因为是要显示列表,这里回顾一下无序列表的语法
<ul>
<li>需要显示的条目内容</li>
</ul>
li:list litm的缩写:条目列表。list:列表;item:条目
语法
<ul>
<li v-for="(对象名称随便起,下标名称随便起) in 数组名">
测试v-for:{{ 上面起的对象名 }}
</li>
</ul>
总结:
v-model
作用:把表单中的值和实例中的数据关联起来(双向数据绑定)
案例
总结:
实现一个笔记便笺案例
目标功能
新增功能实现
思路:
<!-- 列表区域 -->
<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>
methods: {
add:function(){
this.list.push(this.inputValue);
},
删除功能
删除指定内容
v-on splice
remove:function(index){
this.list.shift(index);
}
统计个数
实际上就是数组的length,让使用length的数据实时同步
<span class="todo-count">
<strong>{{list.length}}</strong> items left
</span>
清空所有
思路就是
绑定清空事件
直接赋予新值清空掉
隐藏功能
都清空的时候这玩意不美观,隐藏起来!
思路:
这里采用v-show,因为v-if的性能消耗大,总是改dom树
总结
代码,还是只放body的
<body>
<!-- 主体区域 -->
<section id="todoapp">
<!-- 输入框 -->
<header class="header">
<h1>Cc记事本</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">
<strong>{{list.length}}</strong> items left
</span>
<button 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){
this.list.shift(index);
},
clear:function(){
this.list=[];
}
},
})
</script>
</body>
成品样式,css和素材文件没有加入
网络应用
axios使用
首先,axios是一个js库,所以我们要导入包,和vue的导包差不多
导包标签
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Get请求语法
axios.get(url?key=value&key2=value2).then(
function(response){
响应成功时运行的函数,response对象为结果对象
},
function(err){
响应失败时运行的函数,err对象为报错对象
}
)
Post请求语法
注意,这里对象的装载方法是{属性:值}
axios.post(url,{key:value&key2:value2}).then(
function(response){
响应成功时运行的函数,response对象为结果对象
},
function(err){
响应失败时运行的函数,err对象为报错对象
}
)
总结:
axios结合vue
示例:
<body>
<div id="app">
<button value="Get请求" @click="doGet">Get请求</button>
<p> {{ joke }} </p>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!--
接口:随机获取一条笑话
请求地址:https://autumnfish.cn/api/joke
请求方法:get
请求参数:无
响应内容:随机笑话
-->
<script>
var app = new Vue({
el: '#app',
data: {
joke:"11"
},
methods:{
doGet:function(){
var this=that;
axios.get("https://autumnfish.cn/api/joke").then(
function(response){
that.joke=response.data;
},
function(err){
alert("请求报错");
}
)
}
}
})
</script>
</body>
总结:
天气应用实现
概述
回车查询的功能
总结
点击热门城市一键查询
思路
总结
成品
<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" class="input_txt" placeholder="请输入查询的天气" v-model="city" @keyup.enter="queryWeather" />
<button class="input_sub" @click="queryWeather">
搜 索
</button>
</div>
<div class="hotkey">
<!-- <a href="javascript:;" @click="clickSearch('北京')">北京</a>
<a href="javascript:;" @click="clickSearch('上海')">上海</a>
<a href="javascript:;" @click="clickSearch('广州')">广州</a>
<a href="javascript:;" @click="clickSearch('深圳')">深圳</a> -->
<a href="javascript:;" v-for="city in hotCitys" @click="clickSearch(city)">{{ city }}</a>
</div>
</div>
<ul class="weather_list">
<li v-for="(item,index) in forecastList" :key="item.date" :style="{transitionDelay:index*100+'ms'}">
<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>
<script>
new Vue({
el: "#app",
data: {
city: "武汉",
forecastList: [],
hotCitys: ["北京", "上海", "广州", "深圳"]
},
methods: {
queryWeather() {
this.forecastList = [];
axios
.get(`http://wthrcdn.etouch.cn/weather_mini?city=${this.city}`)
.then(res => {
console.log(res);
this.forecastList = res.data.data.forecast;
})
.catch(err => {
console.log(err);
})
.finally(() => { });
},
clickSearch(city) {
this.city = city;
this.queryWeather();
}
}
});
</script>
</body>
实现一个音乐播放器(综合应用)
简介
将要完成的功能
模板
包含了所有的CSS样式
<div class="wrap">
<!-- 播放器主体区域 -->
<div class="play_wrap" id="player">
<div class="search_bar">
<img src="images/player_title.png" alt="" />
<!-- 搜索歌曲 -->
<input type="text" autocomplete="off" v-model="query" @keyup.enter="searchMusic" />
</div>
<div class="center_con">
<!-- 搜索歌曲列表 -->
<div class='song_wrapper'>
<ul class="song_list">
<li v-for="item in musicList">
<a href="javascript:;" @click="playMusic(item.id)"></a>
<b>{{ item.name }}</b>
<span v-if="item.mvid!=0" @click="playMV(item.mvid)"><i></i></span>
</li>
</ul>
<img src="images/line.png" class="switch_btn" alt="">
</div>
<!-- 歌曲信息容器 -->
<div class="player_con" :class="{playing:isPlaying}">
<img src="images/player_bar.png" class="play_bar" />
<!-- 黑胶碟片 -->
<img src="images/disc.png" class="disc autoRotate" />
<img :src="musicCover" class="cover autoRotate" />
</div>
<!-- 评论容器 -->
<div class="comment_wrapper">
<h5 class='title'>热门留言</h5>
<div class='comment_list'>
<dl v-for="item in hotComments">
<dt><img :src="item.user.avatarUrl" alt=""></dt>
<dd class="name">{{ item.nickname}}</dd>
<dd class="detail">
{{ item.content }}
</dd>
</dl>
</div>
<img src="images/line.png" class="right_line">
</div>
</div>
<div class="audio_con">
<audio ref='audio' @play="play" @pause="pause" :src="musicUrl" controls autoplay loop class="myaudio"> </audio>
</div>
<div class="video_con" v-show="isShow" style="display: none;">
<video :src="mvUrl" controls="controls"></video>
<div class="mask" @click="hide"></div>
</div>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 官网提供的 axios 在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var app = new Vue({
el: "#player",
data: {
// 查询关键字
query: "",
// 歌曲数组
musicList: [],
// 歌曲地址
musicUrl: "",
// 歌曲封面
musicCover: "",
// 歌曲评论
hotComments: [],
// 动画播放状态
isPlaying: false,
// 遮罩层的显示状态
isShow: false,
// mv地址
mvUrl: ""
},
歌曲搜索
js函数
1:歌曲搜索接口
请求地址:https://autumnfish.cn/search
请求方法:get
请求参数:keywords(查询关键字)
响应内容:歌曲搜索结果
// 歌曲搜索
searchMusic:function(){
var that=this;
axios.get("https://autumnfish.cn/search?keywords="+this.query).then(
function(response){
that.musicList=response.data.result.songs;
console.log(response);
},
function(err){}
)
歌曲播放
歌曲播放包含了获取歌曲URL,歌曲信息,热评的内容
//歌曲播放
playMusic:function(musicId){
var that=this;
// 获取歌曲地址
axios.get("https://autumnfish.cn/song/url?id="+musicId).then(
function(response){
that.musicUrl=response.data.data[0].url;
console.log(response);
},
function(err){}
)
//获取歌曲详情
axios.get("https://autumnfish.cn/song/detail?ids="+musicId).then(
function(response){
that.musicCover=response.data.songs[0].al.picUrl;
console.log(response);
},
function(err){}
)
//获取歌曲热门评论
axios.get("https://autumnfish.cn/comment/hot?type=0&id="+musicId).then(
function(response){
that.hotComments=response.data.hotComments;
console.log(response);
},
function(err){}
)
},
API信息
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的地址
歌曲播放和暂停
就是操作一下播放状态的布尔值
//歌曲播放
play:function(){
this.isPlaying=true;
},
// 歌曲暂停
pause: function() {
// console.log("pause");
this.isPlaying = false;
},
MV播放操作
对遮罩层进行操作,开启与关闭
//mv播放
playMV:function(mvid){
var that=this;
//播放
axios.get("https://autumnfish.cn/mv/url?id="+mvid).then(
function(response){
console.log(response);
that.isShow=true;
that.mvUrl = response.data.data.url;
console.log(that.mvUrl)
},
function(err){}
)
},
//隐藏遮罩层
hide:function(){
this.isShow=false;
},