黑马程序员前端基础教程-4个小时带你快速入门vue:https://b23.tv/80W1WG
学前条件:HTML+CSS+JavaScript+[BOM/DOM]+Ajax
工具:VSCode(插件:Live Server)
一、Vue基础
二、本地应用
三、网络应用
四、综合应用
1.------------------------------------------------------------------------------
官方: https://cn.vuejs.org/
开发环境版本,包含了有帮助的命令行警告
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
生产环境版本,优化了尺寸和速度
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统
!+Tab:自动补全html标准模板
第一个demo步骤:
1.导入开发版本的vue.js
2.创建Vue实例对象,设置el属性和data属性
3.使用简洁的模板语法把数据渲染到页面上
<!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>vue基础</title>
</head>
<body>
<div id="app">
{{ message }}
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
el:挂载点
作用:设置Vue实例挂载(管理)的元素
Vue会管理el选项命中的元素及其内部的后代元素
可以使用其他选择器,但是建议使用ID选择器
可以使用其他的双标签,不能使用HTML和BODY
<!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>el:挂载点</title>
</head>
<body>
{{ message }}
<div id="app" class="app">
{{ message }}
<span>
{{ message }}
</span>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
//el: '#app', //id选择器
//el: ".app", //class选择器
el:"div", //标签选择器
data: {
message: 'Hello Vue!'
}
})
</script>
</body>
</html>
data:数据对象
Vue中用到的数据定义在data中
data中可以写复杂类型的数据
渲染复杂类型数据时,遵守js的语法即可
<!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>data:数据对象</title>
</head>
<body>
<div id="app" class="app">
{{ message }}
<h2>{{ school.name }} {{ school.mobile }}</h2>
<ul>
<li>{{ campus[0] }}</li>
<li>{{ campus[1] }}</li>
<li>{{ campus[2] }}</li>
<li>{{ campus[3] }}</li>
</ul>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app', //id选择器
data: {
message: 'Hello Vue!',
school: {
name: "胡歌",
mobile: "123-456-8888"
},
campus: ["北京大学", "上海大学","武汉大学","武汉工程大学"]
}
})
</script>
</body>
</html>
2.------------------------------------------------------------------------------
Vue指令:以v-开头的一组特殊语法
内容绑定,事件绑定
显示切换,属性绑定
列表循环,表单元素绑定
(1)v-test:设置标签的文本值(textContent)
默认写法会替换全部内容,使用差值表达式{{}}可以替换指定内容
内部支持写表达式
<!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>v-text指令</title>
</head>
<body>
<div id="app">
<h2 v-text="message">武汉</h2>
<h2 v-text="info">武汉</h2>
<h2>{{ message }}武汉</h2>
<h2 v-text="message + '!'">十堰</h2>
<h2 v-text="info + '!'">十堰</h2>
<h2>{{ message + '!' }}十堰</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
message: "Hello, world!",
info: "This is HTML test..."
}
})
</script>
</body>
</html>
(2)v-html:设置标签的innerHTML
内容有html机构会被解析为标签
v-text指令无论内容是什么,只会解析为文本
解析文本使用v-text,需要解析html结构使用v-html
<!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>v-html指令</title>
</head>
<body>
<!-- 2.html -->
<div id="app">
<p v-html="content"></p>
<p v-text="content"></p>
<p v-html="content1"></p>
<p v-text="content1"></p>
</div>
<!-- 1.导入开发环境 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 3.创建vue实例
var app = new Vue({
el: "#app",
data: {
content: "好好学习,天天向上。",
content1: "<a href='https://www.baidu.com/'>百度一下</a>"
}
})
</script>
</body>
</html>
(3)v-on:为元素绑定事件
事件名不需要写on
指令可以简写为@
绑定的方法定义在methods属性中
方法内部通过this关键字可以访问定义在data中数据
<!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>v-on指令</title>
</head>
<body>
<!-- 2.html -->
<div id="app">
<input type="button" value="v-on指令" v-on:click="doIt">
<input type="button" value="v-on简写" @click="doIt">
<input type="button" value="双击事件" v-on:dblclick="doIt">
<h2 @click="changeFood">{{ food }}</h2>
</div>
<!-- 1.导入开发环境 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 3.创建vue实例
var app = new Vue({
el: "#app",
data: {
food: "西红柿炒鸡蛋"
},
methods: {
doIt: function(){
alert("我被点击了^-^.")
},
changeFood: function(){
this.food += "好好吃!"
}
}
})
</script>
</body>
</html>
案例一:计数器
<!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>
</head>
<body>
<div id="app">
<div id="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>0){
this.num --;
} else{
alert("别点了,最小了!")
}
}
}
})
</script>
</body>
</html>
(4)v-show:根据表达式值得真假,切换元素的显示和隐藏
广告、遮罩层
原理是修改元素的display,实现显示隐藏
指令后面的内容,最终都会解析为布尔值
值为true元素显示,值为false元素隐藏
数据改变之后,对应元素的显示状态会同步更新
<!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>v-show指令</title>
</head>
<body>
<div id="app">
<input type="button" value="切换显示状态" @click="changeIsShow">
<input type="button" value="切换显示状态" @click="addAge">
<img v-show="isShow" src="/babys.gif" alt="">
<img v-show="age>=18" src="/babys.gif" alt="">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
isShow: true,
age: 16
},
methods: {
changeIsShow: function(){
this.isShow = ! this.isShow;
},
addAge: function(){
this.age ++;
}
}
})
</script>
</body>
</html>
(5)v-if:根据表达式的真假,切换元素的显示和隐藏(操纵dom)
表达式值为true,元素存在于dom树中,为false,从dom树中删除
频繁的切换用v-show,反之用v-if,前者切换消耗小
<!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>v-if指令</title>
</head>
<body>
<div id="app">
<input type="button" value="切换显示" @click="toggleIsShow">
<p v-if="isShow">v-if指令</p>
<p v-show="isShow">v-if指令111</p>
<h2 v-if="temperature>=30">热死了</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
isShow: false,
temperature: 35
},
methods: {
toggleIsShow:function(){
this.isShow = !this.isShow;
}
}
})
</script>
</body>
</html>
(6)v-bind:设置元素属性
完整写法 v-bind:属性名
简写 直接省略v-bind,只保留 :属性名
需要动态的增删class建议使用对象的方式
<!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>v-bind指令</title>
<style>
img{
height:100px;
width:100px;
}
.active{
border: 1px solid red;
}
</style>
</head>
<body>
<div id="app">
<img v-bind:src="imgSrc" alt="" >
<img :src="imgSrc" alt="" >
<br>
<img :src="imgSrc" :title="imgTitle+'!'" alt="" >
<br>
<!-- <img :src="imgSrc" alt="" :class="isActive?'active':''" @click="toggleIsActive"> -->
<img :src="imgSrc" alt="" :class="{active:isActive}" @click="toggleIsActive">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
imgSrc: "/huawei.jpeg",
imgTitle: "华为",
isActive: false
},
methods: {
toggleIsActive: function(){
this.isActive = !this.isActive;
}
}
})
</script>
</body>
</html>
案例二: 轮播图
<!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>
<style>
img{
width: 400px;
height: 200px;
}
</style>
</head>
<body>
<div id="app">
<P>这是第{{index+1}}张照片,共{{imgArr.length}}张</P>
<img :src="imgArr[index]">
<br>
<a href="javascript:void(0)" @click="next" v-show="index>0" >上一张</a>
<a href="javascript:void(0)" @click="prev" 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: ["/A.jpg","/B.jpg","/C.jpg","/D.jpg"],
index: 0
},
methods: {
prev: function(){
this.index ++;
},
next: function(){
this.index --;
}
}
})
</script>
</body>
</html>
(7)v-for:根据数据生成列表结构
数组经常和v-for结合使用
语法是(item,index)in 数据
item 和 index可以结合其他指令一起使用
数组的长度的更新会同步到页面上是响应式的
<!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>v-for指令</title>
</head>
<body>
<div id="app">
<input type="button" value="添加数据" @click="add" >
<input type="button" value="删除数据" @click="remove" >
<ul>
<li v-for="item,index in arr">{{index+1}}-{{ item }}</li>
</ul>
<h2 v-for="item,index in vegetables">{{index}}-{{item.name}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
arr: ["北京","上海","武汉","河北"],
vegetables: [
{name: "西红柿炒蛋"},
{name: "椒盐玉米"}
]
},
methods: {
add: function(){
this.vegetables.push({name: "番茄炒西红柿"})
},
remove: function(){
this.vegetables.shift();
}
}
})
</script>
</body>
</html>
(8)v-on补充
传递自定义参数,事件修饰符
文档传送门:https://cn.vuejs.org/v2/api/#v-on
事件绑定的方法写成函数调用的形式,可以传递自定义参数
定义方法时需要定义形参来接收传入的实参
事件的后面跟上 .修饰符可以对事件进行限制
.enter 可以限制触发的按钮为回车
事件修饰符有很多种
<!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>v-on指令补充</title>
</head>
<body>
<div id="app">
<input type="button" value="点击" @click="doIt(666,'永远的神')">
<br>
<input type="text" placeholder="ChatWithMe" @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,p2){
console.log(p1);
console.log(p2);
},
sayHi: function(){
alert("吃过了...");
}
}
})
</script>
</body>
</html>
(9)v-model:获取和设置表单元素的值(双向数据绑定)
绑定的数据会和表单元素值相关联
绑定的数据<--->表单元素的值
<!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>v-model指令</title>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
<h2>{{ message }}</h2>
<!-- <input type="text" v-model="message" @keyup.enter="getM"> -->
<input type="button" value="修改" @click="setM">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
message: "马尔扎哈"
},
methods: {
getM: function(){
alert(this.message);
},
setM: function(){
this.message = "古力娜扎";
}
}
})
</script>
</body>
</html>
案例三:小黑记事本
<!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>
<style>
.content{
border: 1px solid red;
width: 175px;
border-top: 20px;
}
.footer{
width: 175px;
display: flex;
justify-content: space-between;
align-items: center
}
</style>
</head>
<!-- 1.新增
1)生成列表结构
2)获取用户输入
3)回车,新增数据
2.删除
点击删除指定内容 v-on splice
3.统计
统计信息个数 v-text length
4.清空
点击清空所有信息 v-on
5.隐藏
没有数据时,隐藏元素 v-show / v-if
-->
<body>
<h2>小黑记事本</h2>
<div id="app">
<input type="text" v-model="inputValue" @keyup.enter="add" placeholder="请输入任务">
<div class="content">
<p v-for="item,index in list" @click="remove(index)">{{index+1}}.{{item}}</p>
</div>
<div v-show="list.length" class="footer">
<h4>{{list.length}} items left</h4>
<input type="button" value="clear" @click="clear" style="height:30px">
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: "#app",
data: {
list: ["写代码", "做作业", "玩游戏"],
inputValue: ""
},
methods: {
add: function () {
this.list.push(this.inputValue);
},
remove: function (index) {
//console.log(index)
this.list.splice(index, 1);
},
clear: function () {
this.list = [];
}
}
})
</script>
</body>
</html>
3.------------------------------------------------------------------------------
Vue结合网络数据开发应用
axios:网络请求库+vue结合
功能强大的网络请求库
引入:<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
axios.get(地址?查询字符串k1=v1&k2=v2).then(function(response){},function(err){})
xios.post(地址,参数对象{k1:v1,k2:v2}).then(function(response){},function(err){})
笑话接口:
https://autumnfish.cn/api/joke/list
用户注册接口
https://autumnfish.cn/api/user/reg
<!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>axios基本使用</title>
</head>
<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>
document.querySelector(".get").onclick = function(){
axios.get("https://autumnfish.cn/api/joke/list?num=6").then(function(response){
console.log(response);
},function(err){
console.log(err);
})
};
document.querySelector(".post").onclick = function(){
axios.post("https://autumnfish.cn/api/user/reg",{username:"Jack"}).then(function(response){
console.log(response);
},function(err){
console.log(err);
})
}
</script>
</body>
</html>
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">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>axios+vue</title>
</head>
<body>
<div id="app">
<input type="button" value="获取笑话" @click="getJoke">
<p> {{ joke }} </p>
</div>
<!-- vue -->
<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: "#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);
that.joke = response.data;
},function(err){})
}
}
})
</script>
</body>
</html>
案例四:天气预报
接口:http://wthrcdn.etouch.cn/weather_mini?city=
<!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>
<style>
li{
list-style-type: none;
float: left;
margin-right: 15px;
}
li .type{
color: coral;
}
li .low_high{
color: coral;
font-size: 10px;
}
li .date{
color: gray;
font-size: 10px;
}
</style>
</head>
<body>
<div id="app">
<h3 style="margin-left:90px;color: #225599;">天知道</h3>
<div class="input_btn" style="margin-left:40px;">
<input type="text" v-model="city" @keyup.enter="searchWeather" placeholder="请输入查询天气" class="input_txt">
<input type="button" value="搜索" class="input_sub" @click="btnSearch">
<!-- <button>搜索</button> -->
</div>
<div class="hotkey" style="font-size:14px; margin-left:40px;">
<a href="javascript:;" @click="changeCity('北京')" >北京</a>
<a href="javascript:;" @click="changeCity('上海')" >上海</a>
<a href="javascript:;" @click="changeCity('武汉')" >武汉</a>
<a href="javascript:;" @click="changeCity('十堰')" >十堰</a>
</div>
<ul class="weather_list">
<li v-for="item in weatherList">
<p class="type">{{item.type}}</p>
<p class="low_high">{{item.low}}~{{item.high}}</p>
<p class="date">{{item.date}}</p>
</li>
</ul>
</div>
<!-- vue -->
<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 src="./js/main.js" ></script>
</body>
</html>
/*
1.回车查询
1)按下回车 v-on .enter
2)查询数据 axios接口 v-model
3)渲染数据 v-for 数组 that
2.点击查询
1)点击城市 v-on 自定义参数
2)查询数据 this.方法
3)渲染数据
*/
var app = new Vue({
el: "#app",
data: {
city: "",
weatherList: []
},
methods: {
searchWeather:function(){
//console.log("天气查询");
//console.log(this.city);
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;
},function(err){})
},
changeCity:function(city){
this.city = city;
//console.log(city);
this.searchWeather();
},
btnSearch:function(){
this.searchWeather();
}
}
})
4.------------------------------------------------------------------------------
案例五:音乐播放器
歌曲搜索
1)按下回车 v-on .enter
2)查询数据 axios接口 v-model
3)渲染数据 v-for数组 that
歌曲播放
1)点击播放 v-on 自定义参数
2)歌曲地址查询 接口 歌曲id
3)歌曲地址设置 v-bind
歌曲封面
1)点击播放 增加逻辑
2)歌曲封面获取 接口 歌曲id
3)歌曲封面设置 v-bind
歌曲评论
1)点击播放 增加逻辑
2)歌曲评论获取 接口 歌曲id
3)歌曲评论渲染 v-for
播放动画
1)监听音乐播放 v-on play
2)监听音乐暂停 v-on pause
3)操纵类名 v-bind 对象
MV播放
1)MV图标显示 v-if
2)mv地址设置 v-on 接口 mvid
3)遮罩层 v-show v-on
4)MV地址设置 v-bind
【待补充。。。】