Vue
Vue之前看过一点点,现在重看Vue,
学习时间2021.12.24下午到晚上8.50
1、第一个Vue程序
Vue官网:https://cn.vuejs.org/
文档:https://cn.vuejs.org/v2/guide/
使用VsCode开发,插件使用Live Server,打开文件夹,然后启动Live Server,
在http://127.0.0.1:5500/Untitled-1.html
可以实时更新前端
第一个Vue程序:
导包-app-message绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document123</title>
</head>
<body>
<div id="app">
{{ message }}
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Lxw-Vue!'
}
})
</script>
</body>
</html>
2、Vue基础
2.1、el挂载点
<div id="app" class="app1">
el: '#app', 这是代表id选择器【一般我们就使用id选择器】
el: '.app1', 这是代表class选择器
不要将vue挂载到body和html上,一般挂载到div上
2.2、data数据对象
<body>
<div id="app">
{{ message }} <br>
<span>姓名:{{ school.name }} 手机:{{ school.mobile }}</span>
<ul>
<li>{{ ydd[0] }}</li>
<li>{{ ydd[1] }}</li>
<li>{{ ydd[2] }}</li>
</ul>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: '这就是之谦',
school:{
name:"刘学伟",
mobile:"19862516287"
},
ydd:["ydd1","ydd2","ydd3"]
}
})
</script>
</body>
</html>
3、Vue本地应用
创建vue实例,el挂载点,data数据,methods方法
3.1、v-text文本{{}}
设置标签内容(textContent)
默认写法v-text=""
会替换全部内容,使用差值表达式{{}}
可以替换指定内容
<div id="app">
<!-- v-text会替换原有内容 -->
<h2 v-text="message+'!'">标题</h2>
<h2>{{ message +'!'}}标题</h2>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: '这就是之谦',
info:"6666"
}
})
</script>
3.2、v-html文本
设置标签的innerHTML,会解析渲染html文本内容
v-text与v-html对于html语言前者不解析,后者解析渲染
<div id="app">
{{message}}
<p v-text="message"></p>
<p v-html="message"></p>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
message:"<a href='http://badwei.xyz'>这就是之谦</a>"
}
})
</script>
3.3、v-on绑定事件和参数@
绑定事件,函数
鼠标单击v-on:click="事件"
与@click
等价
鼠标移入事件v-on:monseenter="事件"
与@monseenter
等价
鼠标双击v-on:dblclick="事件"
与@dblclick
等价
<div id="app">
<input type="button" value="v-on指令1" v-on:click="lxwfun">
<!-- 使用@代替v-on:简写 -->
<input type="button" value="v-on指令2" @click="lxwfun">
<input type="button" value="双击事件" @dblclick="lxwfun">
<h2 @click="changeFood">{{food}}</h2>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
food:"西瓜"
},
methods:{
lxwfun:function(){
alert("这才是之谦");
},
changeFood:function(){
console.log(this.food);
this.food+="2";
}
}
})
</script>
v-on绑定事件参数
<div id="app">
<input type="button" value="lxw" @click="lxwFun(666,777)">
<!-- v-model可以实现双向绑定 -->
<input type="text" v-model="sayWhat" @keyup.enter="sayHi(sayWhat)">
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
sayWhat:""
},
methods:{
lxwFun:function(p1,p2){
alert("lxw"+p1+p2);
},
sayHi:function(p1){
alert("hello"+p1)
}
}
})
</script>
(1)demo-计数器
<div id="app">
<!-- 绑定减法函数函数 -->
<input type="button" value="-" @click="sub">
{{num}}
<!-- 绑定加法函数函数 -->
<input type="button" value="+" @click="add">
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
num:1
},
methods:{
//加法函数
add:function(){
this.num++;
},
//减法函数
sub:function(){
this.num--;
}
}
})
</script>
3.4、v-show显示
切换元素的显示和隐藏
本质是切换元素的display
指令后的值都会被解析为bool值
<div id="app">
<a v-show="true">默认 {{message}} </a>
<input type="button" value="点击显示隐藏" @click="chageShow">
<a v-show="isShow" > {{message}} </a>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
isShow:false,
message:"lxw"
},
methods:{
//改变显示状态
chageShow:function(){
this.isShow = !this.isShow
}
}
})
</script>
3.5、v-if显示
与v-show相同的功能
原理是直接删除dom树的结构
对于频繁切换的话,建议使用v-show
<div id="app">
<input type="button" value="切换" @click="changeShow">
<p v-if="isShow">{{message}}</p>
<p v-show="isShow">{{message}}</p>
<h2 v-if="t>30">{{t}}摄氏度热死了热</h2>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
isShow:true,
message:"lxw",
t:35
},
methods:{
changeShow:function(){
this.isShow = !this.isShow;
}
}
})
</script>
3.6、v-bind设置元素的属性:
设置元素的属性
v-bind:属性名=表达式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 设置一个class属性 */
.active{
border:1px solid red;
}
</style>
</head>
<body>
<div id="app">
<h2>{{message}}</h2>
<img v-bind:src="imgSrc" >
<img :src="imgSrc" :title="imgT+'!!!'" :class="{active:isActive}" @click="changeActive">
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
message:"lxw",
imgT:"图片2222",
imgSrc:"https://pic.badwei.xyz/163999208014671.png",
isActive:false
},
methods:{
// 是否使用class
changeActive:function(){
this.isActive = !this.isActive;
}
}
})
</script>
</body>
</html>
(2)demo-切换图片
<div id="mask">
<div class="center">
<!-- 图片 -->
<img :src="imgArr[index]" alt="" />
<!-- 左箭头 -->
<a href="javascript:void(0)" v-if="index>0" @click="prev" class="left">
<img src="./images/prev.png" alt="" />
</a>
<!-- 右箭头 -->
<a href="javascript:void(0)" v-show="index<imgArr.length-1" @click="next" class="right">
<img src="./images/next.png" 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/00.jpg",
"./images/01.jpg",
"./images/02.jpg",
"./images/03.jpg",
"./images/04.jpg",
"./images/05.jpg",
"./images/06.jpg",
"./images/07.jpg",
"./images/08.jpg",
"./images/09.jpg",
"./images/10.jpg",
],
index: 0
},
methods: {
prev:function(){
this.index--;
},
next:function(){
this.index++;
}
},
})
</script>
3.7、v-for循环
根据数据生成列表结构
循环,可以同时取到值和index
v-for="(item,index) in arr"
<div id="app">
<h2>{{message}}</h2>
<input type="button" value="添加数据" @click="add">
<input type="button" value="删除数据" @click="remove">
<ul>
<li v-for="(item,index) in arr">{{item}}你好index={{index}}</li>
</ul>
<h2 v-for="item in arr1">{{item}}</h2>
<h2 v-for="item in arr1" :title="item.name">{{item.name}} </h2>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
message:"v-for",
arr:[1,2,3,4,5],
arr1:[
{name:"岩弟弟"},
{name:"岩弟弟2号"}
]
},
methods:{
add:function(){//添加数据
this.arr1.push({name:"岩弟弟三号"})
},
remove:function(){//删除数据最左边
this.arr1.shift();
}
}
})
</script>
3.8、v-model双向数据绑定
双向数据绑定把表单元素与data数据双向绑定
<div id="app">
{{message}}<br>
<input v-model="message"></input>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
message:"lxw"
}
})
</script>
(3)demo-记事本
<div id="app">
<h2>{{message}}</h2>
<input v-model="newdata"><input type="button" value="添加" @click="add">
<ul>
<li v-for="(item,index) in arr">{{index+1}} {{item}}<input type="button" value="删除" @click="del(index)"></li>
</ul>
<input type="button" value="清空数据" @click="delAll" v-show="arr.length>0"><br>
<a v-show="arr.length>0">共{{arr.length}}条数据</a>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
message:"lxw-记事本",
arr:["岩弟弟","丫丫","小胖子"],
newdata:""
},
methods:{
//添加
add:function(){
if(this.newdata=="")alert("不能添加空值")
else {
this.arr.push(this.newdata);
this.newdata="";
}
},
//单个删除
del:function(index){
this.arr.splice(index,1);
},
//全部删除
delAll:function(){
this.arr = [];
}
}
})
</script>
4、Vue网络应用
4.1、axios
axios官网:https://github.com/axios/axios
一些开源接口https://github.com/AutumnFish/testApi
<input id="get1" type="button" value="get请求" class="get">
<input id="post1" type="button" value="post请求" class="post">
<!-- 官网提供的 axios cdn在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
document.querySelector("#get1").onclick = function(){
axios.get("https://autumnfish.cn/api/joke/list?num=3")
.then(function(response){
console.log(response);
alert(response.data.jokes);
},function(err){
console.log(err);
})
};
document.querySelector(".post").onclick=function(){
axios.post("https://autumnfish.cn/api/user/reg",
{username:"abc1214100"})
.then(function(response){
console.log(response);
alert(response.data);
},function(err){
console.log(err);
})
};
</script>
4.2、axios搭配vue
<div id="app">
<input type="button" value="下一条" @click="getJokes">
<p>{{joke}}</p>
</div>
<!-- 官网提供的 axios cdn在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el:"#app",
data:{
joke:""
},
methods:{
getJokes:function(){
var that = this;//这里定义一个that保存一下vue的this
axios.get("https://autumnfish.cn/api/joke")
.then(function(response){
//这里不能直接使用vue中data的this,因为axios已经重置this
that.joke = response.data;
console.log(this.joke);
},function(err){
console.log(err);
})
}
}
})
</script>
(4)demo-天气查询
<div id="app">
<a @click="chickCity('武汉')">武汉</a>
<a @click="chickCity('北京')">北京</a>
<a @click="chickCity('上海')">上海</a>
<a @click="chickCity('深圳')">深圳</a>
<input type="text" v-model="city" @keyup.enter="searchWeather">
<ul>
<li v-for="item in arr">时间:{{item.date}};最高温:{{item.high}};最低温:{{item.low}}</li>
</ul>
</div>
<!-- 官网提供的 axios cdn在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="./js/main.js"></script>
var app = new Vue({
el:"#app",
data:{
city:"",
arr:[]
},
methods:{
searchWeather:function(){
that = this;
// console.log(this.city);
axios.get('http://wthrcdn.etouch.cn/weather_mini?city='+this.city)
.then(function(response){
that.arr=response.data.data.forecast;
},function(err){
console.log(err);
})
},
chickCity:function(city){
this.city=city;
this.searchWeather();
}
}
})
(5)音乐播放器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>音乐</title>
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div id="app" 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>
<!-- 官网提供的 axios cdn在线地址 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="./js/main.js"></script>
</body>
</html>
/*
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: "https://p1.music.126.net/R7gU6oGYmVSWIkRfuZ6Bag==/109951164000969173.jpg",
// 歌曲评论
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) {}
// );
that.musicUrl = "http://music.163.com/song/media/outer/url?id=" + musicId + ".mp3";
// 歌曲详情获取
axios.get("https://api.imjad.cn/cloudmusic/?type=detail&id=" + 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;
}
}
});
评论区