一、Vue基础
1、Vue简介
JS 框架;
简化 Dom 操作;
响应式数据渲染。
2、Vue程序
导入开发版本的Vue.js CDN;
创建Vue实例对象,设置el属性和data属性;
使用简洁的模板语法把数据渲染到页面上。
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
{{message}}
</div>
<script>
const app = new Vue({
el:'#app',
data:{
message:"Hello World"
}
})
</script>
3、Vue挂载点
Vue 实例的作用范围:Vue会管理 el 选项命中的元素及其内部的后代元素;
Vue 可以使用其他的选择器,但是推荐使用 ID 选择器;
Vue 可以使用其他的双标签,不能使用 html 和 body 标签。
4、Vue数据对象
Vue 中用到的数据定义在 data 中;
data 中可以写复杂类型的数据;
渲染复杂类型数据时,遵守 js 的语法即可。
二、Vue本地应用
1、v-text指令
v-text 指令的作用是设置标签的内容;
默认写法会替换全部内容,使用差值表达式{{ message }}仍可以替换指定内容;
内部支持写表达式 < h2 v-text ="message+’!’ ">。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-text指令</title>
</head>
<body>
<div id="app">
<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>
const app = new Vue({
el:'#app',
data:{
message:"牛年",
info:'牛气'
}
})
</script>
</body>
</html>
2、v-html指令
v-html 指令的作用是:设置元素的 innerHTML;
内容中若有 html 结构会被解析成标签;
v- text 指令无论内容是什么只会解析成文本;
解析文本使用v-text, 需要解析html结构使用 v-html。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-html指令</title>
</head>
<body>
<div id="app">
<p v-html = "content"></p>
<p v-text = "content"></p>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:'#app',
data:{
content:"<a href = 'https://cn.vuejs.org/'>Vue</a>"
}
})
</script>
</body>
</html>
3、v-on指令
v-on 指令的作用是:为元素绑定事件;
事件名不需要写 on;
指令可以简写为 @;
绑定的方法定义在 methods 属性中;
方法内部通过 this 关键字可以访问定义在 data 中数据。
<!DOCTYPE html>
<html xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title> v-on指令</title>
</head>
<body>
<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="双击事件" @dblclick ="doIt">
<h2 @click = 'changeFood'>{{ food }}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"> </script>
<script>
const app = new Vue({
el:'#app',
data:{
food:"土豆"
},
methods:{
doIt:function () {
alert('做it');
},
changeFood:function(){
this.food +="好好吃!"
}
},
})
</script>
</body>
</html>
补充:
事件绑定的方法写成函数调用的形式,可以传入自定义参数;
定义方法时需要定义形参来接受传入的实参;
事件的后面跟上 .修饰符可以对事件进行限制;
例如 .enter 可以限制触发的按钮为回车。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-on 指令补充</title>
</head>
<body>
<div id="app">
<input type="button" value="点击" @click="doIt('很快啊','闪电五连鞭')">
<input type="text" @keyup.enter="sayHi">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
methods:{
doIt:function (p1,p2) {
console.log("马保国");
console.log(p1);
console.log(p2);
},
sayHi:function () {
alert("年强人不讲武德");
}
},
})
</script>
</body>
</html>
4、计数器案例
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>计数器案例</title>
<style>
.input-num span{
height: 100%;
font-size: 40px;
flex: 1;
text-align: center;
line-height: 80px;
font-family: auto;
background-color: #f6f6f6;
}
.input-num button{
width: 150px;
height: 100%;
font-size: 40px;
color: red;
cursor:pointer;
border: none;
outline: none;
background-color: #f6f6f6;
}
</style>
</head>
<body>
<div id="app">
<div class = 'input-num'>
<button @click="sub">
-
</button>
<span>{{ num }}</span>
<button v-on:click="add">
+
</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 编码-->
<script>
// 创建Vue实例
const 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>
5、v-show指令
v-show 指令的作用是:根据表达式真假切换元素的显示状态;
原理是修改元素的 display 实现显示隐藏;
指令后面的内容,最终都会解析为布尔值;
值为 true 元素显示,值为 false 元素隐藏;
数据改变之后,对应元素的显示状态会同步更新。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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="..." />
<img v-show="age>=18" src="..."/>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
isShow: false,
age: 16
},
methods: {
changeIsShow: function () {
this.isShow = !this.isShow;
},
addAge: function () {
this.age++;
}
},
})
</script>
</body>
</html>
6、v-if指令
v-if 指令的作用是:根据表达式的真假切换元素的显示状态;
本质是通过操纵 dom 元素来切元素显示状态;
表述式的值为 true,元素存在于dom树中,为 false,从 dom 树中移除;
如果需要频繁的切换可以使用 v-show 指令,反之使用 v-if,前者的切换消耗比后者小。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-if指令</title>
</head>
<body>
<div id="app">
<input type="button" value="切换显示" @click="toggleIsShow" >
<p v-if ="isShow"> 来偷袭!</p>
<p v-show ="isShow"> 很快啊! v-show修饰 </p>
<h2 v-if = "number>=35">混元形意太极拳 </h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
isShow:false,
number:34
},
methods:{
toggleIsShow:function () {
this.isShow = !this.isShow;
}
}
})
</script>
</body>
</html>
7、v-bind 指令
v-bind 指令的作用是:为元素绑定属性;
完整写法是 v-bind:属性名 = 表达式;
简写的话可以直接省略V-bind,只保留 :属性名 = 表达式;
需要动态的增删 class 建议使用对象的方法,不推荐使用三元运算符。
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>v-bind指令</title>
<style>
.active{
border: 5px solid red;
}
</style>
</head>
<body>
<div id="app">
<img v-bind:src="imgSrc" alt="" >
<br>
<img :src="imgSrc" :title = "imgTitle+'!!!'" :class="isActive?'active':''"
@click="toggleActive">
<br>
<img :src="imgSrc" alt="" :title="imgTitle+'!!!'" :class = {active:isActive}
@click="toggleActive" >
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
imgSrc: "图片/二哈黄花.png",
imgTitle:"搞笑",
isActive:false
},
methods:{
toggleActive:function () {
this.isActive = !this.isActive;
},
}
})
</script>
</body>
</html>
8、v-for指令
v-for 指令的作用是:根据数据生成列表结构;
数组经常和 v-for 结合使用;
语法是(item. index) in 数据;
item 和 index 可以结合其它指令一起使用;
数组长度会更新到页面上,是响应式的。
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<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="(it,index) in arr" style="list-style-type: none">
{{index+1}}黑马程序员校区:{{it}}
</li>
</ul>
<h2 v-for="item in people" v-bind:title="item.name">
{{item.name}}
</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
arr:["北京","上海","广州","深沉"],
people:[{name:"男人"},
{name: "女人"}
]
},
methods:{
add:function () {
this.people.push({name:"小孩"});
},
remove:function(){
this.people.shift();
}
},
})
</script>
</body>
</html>
9、v-model指令
v-model 指令的作用是便捷的设置和获取表单元素的值;
绑定的数据会和表单元素值相关联;
绑定的数据←→表单元素的值 双向绑定。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-model指令</title>
</head>
<body>
<div id="app">
<input type="button" value="修改message" @click="setM">
<input type="text" v-model="message" @keyup.enter="getM">
<h2>{{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el:"#app",
data:{
message:"Vue2"
},
methods:{
getM:function () {
alert(this.message);
},
setM:function () {
this.message="Hello World!";
}
}
})
</script>
</body>
</html>
三、Vue网络应用
1、axios基本使用
axios 必须先导入才可以使用;
使用get 或 post 方法即可发送对应的请求;
then 方法中的回调函数会在请求成功或失败时触发;
通过回调函数的形参可以获取相应内容,或错误信息。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>axios基本使用</title>
</head>
<body>
<input type="button" value="get请求" class="get">
<input type="button" value="post请求" class="post">
<!-- 官网提供的 axios 在线地址-->
<script src="http://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=3").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)
},function (err) {
console.log(err)
})
}
</script>
</body>
</html>
2、axios vue
axios 回调函数中的 this 已经改变,无法访问到data中的数据;
把 this 保存起来,回调函数中直接使用保存的 this 即可;
和本地应用的最大区别就是改变了数据来源。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>axios vue</title>
</head>
<body>
<div id="app">
<input type="button" value="获取笑话" @click="getJoke">
<p>{{ joke }}</p>
</div>
<script src="http://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
请求参数:无
相应内容:随机笑话
*/
const app = new Vue({
el:"#app",
data:{
joke:"很好笑的笑话"
},
methods:{
getJoke:function () {
var that =this;
axios.get("https://autumnfish.cn/api/joke").then(function (response) {
console.log(response.data);
that.joke = response.data;
},function (err){})
}
}
})
</script>
</body>
</html>
3、天知道案例
1、应用的逻辑代码建议和页面分离, 使用单独的 js 文件编写;
2、axios 回调函数中 this 指向改变,需要额外保存一份;
3、服务器返回的数据比较复杂,获取的时候需要注意层级结构;
4、自定义参数可以让代码的复用性更高;
5、methods 中定义的方法内部,可以通过 this 关键字点出其他方法;
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>天知道案例</title>
<link rel="stylesheet" href="天知道案例.css" />
</head>
<body>
<div class="wrap" id="app">
<div class="search_form">
<div class="logo"><img src="图片/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="changeCity('北京')">北京</a>
<a href="javascript:" @click="changeCity('上海')">上海</a>
<a href="javascript:" @click="changeCity('广州')">广州</a>
<a href="javascript:" @click="changeCity('深圳')">深圳</a>
</div>
</div>
<ul class="weather_list">
<li v-for="(item,index) 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>
<!-- 官网提供的 axios 在线地址-->
<script src="http://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 1.开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="天知道案例.js"></script>
</body>
</html>
CSS:
body{
font-family:'Microsoft YaHei';
}
.wrap{
position: fixed;
left:0;
top:0;
width:100%;
height:100%;
background:#fff;
}
.search_form{
width:640px;
margin:100px auto 0;
}
.logo img{
display:block;
margin:0 auto;
}
.form_group{
width:640px;
height:40px;
margin-top:45px;
}
.input_txt{
width:538px;
height:38px;
padding:0px;
float:left;
border:1px solid #41a1cb;
outline:none;
text-indent:10px;
}
.input_sub{
width:100px;
height:40px;
border:0px;
float: left;
background-color: #41a1cb;
color:#fff;
font-size:16px;
outline:none;
cursor: pointer;
position: relative;
}
.input_sub.loading::before{
content:'';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url('图片/loading.gif');
}
.hotkey{
margin:3px 0 0 2px;
}
.hotkey a{
font-size:14px;
color:#666;
padding-right:15px;
}
.weather_list{
height:200px;
text-align:center;
margin-top:50px;
font-size:0px;
}
.weather_list li{
display:inline-block;
width:140px;
height:200px;
padding:0 10px;
overflow: hidden;
position: relative;
background:url('图片/line.png') right center no-repeat;
background-size: 1px 130px;
}
.weather_list li:last-child{
background:none;
}
.info_date{
width:100%;
height:40px;
line-height:40px;
color:#999;
font-size:14px;
left:0px;
bottom:0px;
margin-top: 15px;
}
.info_date b{
float: left;
margin-left:15px;
}
.info_type span{
color:#fda252;
font-size:30px;
line-height:80px;
}
.info_temp{
font-size:14px;
color:#fda252;
}
.info_temp b{
font-size:13px;
}
.tem .iconfont {
font-size: 50px;
}
body,ul,h1,h2,h3,h4,h5,h6{
margin: 0;
padding: 0;
}
h1,h2,h3,h4,h5,h6{
font-size:100%;
font-weight:normal;
}
a{
text-decoration:none;
}
ul{
list-style:none;
}
img{
border:0px;
}
/* 清除浮动,解决margin-top塌陷 */
.clearfix:before,.clearfix:after{
content:'';
display:table;
}
.clearfix:after{
clear:both;
}
.clearfix{
zoom:1;
}
.fl{
float:left;
}
.fr{
float:right;
}
JS:
/*
请求地址:http://wthrcdn.etouch.cn/weather_mini
请求方法:get
请求参数:city(城市名)
响应内容:天气信息
*/
var app= new Vue({
el:"#app",
data:{
city:'',
weatherList:[]
},
methods:{
queryWeather:function () {
var that = this;
axios.get("http://wthrcdn.etouch.cn/weather_mini?city="+this.city).then(function (response) {
that.weatherList = response.data.data.forecast;
})
.catch(function (err) {
})
},
changeCity(city){
this.city = city;
this.queryWeather();
}
}
})