一、Vue入门
1.1入门案例
1.在页面中引入vue.js框架
2.定义vue对象
let app = new Vue({
el:"#vue作用域的div标签id",
data:{
//所有数据模型
},
methods:{
//页面中所有触发的js方法
},
created(){
//页面初始化,准备调用方法
}
})
3.编写HTML页面部分,使用vue的指令将页面和数据模型绑定
代码练习:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>快速入门</title>
<script src="../js/vue-2.6.12.js"></script>
</head>
<body>
<!--
使用vue声明一个变量username, 并把它的值显示在div中
-->
<div id="app"> <!-- 全局的div,所有标签都写道此div中 -->
我的名字叫{{ name.toUpperCase() }},我今年已经{{ age }}岁了,是个{{age>=18 ? "成年人" : "未成年"}}<br>
我喜欢玩的游戏是{{ game.gamename }}<br>
我有{{friends.length}}个好朋友<br>
我第一个好朋友的名字叫{{ friends[0].name }},他的年龄是{{ friends[0].age }}<br>
我第二个好朋友的名字叫{{ friends[1].name }},他的年龄是{{ friends[1].age }}<br>
</div>
<script>
const app = new Vue({
el:"#app",//绑定元素
data:{//页面所需要的所有数据变量
name:"zhangsan",
age:18,
friends:[
{name:"小帅",age:18},
{name:"小丑",age:20}
],
game:{gamename:"和平精英",address:"海岛"}
}
})
</script>
</body>
</html>
1.2 插值表达式(从vue的数据模型中取东西)
插值表达式是一种Vue的模板语法,用于给页面进行赋值,注意点:
{{}}除了基本的赋值外,还可以进行简单的方法调用、数学运算、三元运算等等
{{}}中仅仅支持表达式,不支持语句,比如:if、for
{{}}中使用的数据必须在data中存在
{{}}不能为标签的属性进行赋值
二、Vue指令
2.1 页面赋值(v-html)
v-html用于将指定变量的值渲染到页面上,如果变量值中有html语法,会进行解析
此标签跟插值表达式功能相似,区别在于插值表达式不会进行html语法的解析
使用v-html="str"会将标签中的内容替换为指定内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面赋值</title>
<script src="../js/vue-2.6.12.js"></script>
</head>
<body>
<div id="app">
插值表达式:{{str}}<br>
V-html:<span v-html="str">我不喜欢Java</span><!--使用v-html="str"会将标签中的内容替换为指定内容-->
</div>
<script>
const app = new Vue({
el:"#app",
data:{
str:"我喜欢<b>Java</b>"
}
})
</script>
</body>
</html>
2.2 双向绑定(v-model)
v-model是双向绑定,视图(View)和模型(Model)之间会互相影响
目前v-model的可使用元素有:input、select、textarea
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>双向绑定</title>
<script src="../js/vue-2.6.12.js"></script>
</head>
<body>
<div id="app">
<h3>姓名:</h3>
<input type="text" v-model="name">
<div>您写的姓名是:{{name}}</div>
<h3>性别:</h3>
<input type="radio" value="男" v-model="sex"> 男 <br>
<input type="radio" value="女" v-model="sex"> 女 <br>
<div>您选择的性别是:{{sex}}</div>
<h3>爱好:</h3>
<input type="checkbox" value="抽烟" v-model="hobby">抽烟<br>
<input type="checkbox" value="喝酒" v-model="hobby">喝酒<br>
<input type="checkbox" value="烫头" v-model="hobby">烫头<br>
<div>您选择的爱好是:{{hobby}}</div>
<h3>段位:</h3>
<select v-model="level">
<option value="">请选择</option>
<option value="青铜">青铜</option>
<option value="白银">白银</option>
<option value="王者">王者</option>
</select>
<div>您选择的段位是:{{level}}</div>
</div>
<script>
const app = new Vue({
el:"#app",
data:{//和表单标签双向绑定,设置的就是默认值
name:"Roes",
sex:"女",
hobby:["抽烟","喝酒"],
level:"白银"
}
})
</script>
</body>
</html>
2.3 属性绑定(v-bind)
对于HTML标签属性,如果想要动态传值,不能使用{{}},而应该使用专门的属性绑定语法
标准语法:v-bind:属性名="Vue中的变量" ,例如:< img v-bind:src="imgSrc" >
简写语法: :属性名="Vue中的变量" ,例如:< img :src="imgSrc" >
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>属性绑定</title>
<script src="../js/vue-2.6.12.js"></script>
</head>
<body>
<div id="app">
<h3>属性绑定基本使用</h3>
有两个图片地址分别是:../img/vue.png 和 ../img/mn.jpg,请在下面输入地址,改变图片:<br>
图片地址: <input type="text" v-model="imgSrc">
图片宽度: <input type="text" v-model="imgWidth">
<br>
<img v-bind:src="imgSrc" :width="imgWidth">
</div>
<script>
let app = new Vue({
el: '#app',
data: {
imgSrc: "../img/vue.png",
imgWidth: "100px"
},
})
</script>
</body>
</html>
2.4 列表遍历(v-for)
v-for="(临时变量,索引) in 数组"
v-for="(变量名,索引名) in 数组" ,例如: v-for="(user,index) in users"
变量名和索引名自己起
变量:表示循环中的每一条数据
遍历哪个标签,就要将这个指令当成属性写在谁哪个标签上
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>列表遍历</title>
<script src="../js/vue-2.6.12.js"></script>
</head>
<body>
<div id="app">
<table border="1" cellspacing="0" cellpadding="0" width="500px">
<tr>
<th>id</th>
<th>name</th>
<th>address</th>
</tr>
<tr v-for="(user,index) in users">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.address}}</td>
</tr>
</table>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
users: [//所有数据都在数据模型中
{id: 1, name: 'jack', address: '北京顺义'},
{id: 2, name: 'lucy', address: '上海虹桥'},
{id: 3, name: 'jerry', address: '天津宝坻'}
]
}
})
</script>
</body>
</html>
2.5 条件判断(v-if/v-show)
语法:
v-if 条件性的创建或者移除某些元素,判定为true时创建,判定为false移除
v-show 条件性的显示或者隐藏某些元素,判定为true时显示,判定为false隐藏
注意:
1) v-if 一般用于要么显示,要么隐藏的场景(具有安全性);
v-show用于频繁切换显示和隐藏的场景(避免的频繁创建标签的内存的消耗)
2) v-if还可以配合v-else以及v-else-if实现多分支条件判断,此时要注意三个标签中间不能有其它内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>条件判断</title>
<script src="../js/vue-2.6.12.js"></script>
</head>
<body>
<div id="app">
<!--从文本框输入成绩, 然后判断成绩是否及格 >=60:及格 <60:不及格-->
请输入成绩:<input type="text" v-model="score"><br>
<h3>v-if判断考试结果</h3>
您本次开始成绩:
<span v-if="score >=60">及格</span>
<span v-else-if="score < 60 && score>=0">不及格</span>
<span v-else="score < 0">成绩输入有误</span>
<h3>v-show判断考试结果</h3>
您本次开始成绩:
<span v-if="score >=60">及格</span>
<span v-if="score < 60">不及格</span>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
score: "0",
}
})
</script>
</body>
</html>
2.6 事件绑定(v-on)
事件绑定用于给页面元素添加事件,js支持的事件vue都支持
标准语法 v-on:事件名="函数名"
简化语法 @事件名="函数名"
注意:
1.事件绑定语法( v-on:事件名="函数名" | @事件名="函数名")
2.js方法需要写到vue对象的methods属性中
3.VUE对象中,相互调用时,需要以this.xxx的形式调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件绑定</title>
<script src="../js/vue-2.6.12.js"></script>
</head>
<body>
<div id="app">
<b>数量:</b>
<button v-show="num>1" @click="diff()">-</button>
<input type="text" v-model="num" style="width: 30px;">
<button v-on:click="add()">+</button>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
num: 1
},
methods: {
add(){
this.num++; //必须写this.num
},
diff(){
this.num--;
}
}
})
</script>
</body>
</html>
三、总结
3.1 Vue模板
const app = new Vue({ el: '#app', data: { //key: value格式的属性 }, methods: { //页面需要调用的方法 }, created(){ //当前页面加载时,自动调用 } })
3.2 Vue指令
1.向页面展示数据 插值: {{ key }} v-html:<span v-html="key"></span> 2.数据双向绑定 作用:用户在页面输入的内容和vue对象中的变量相互影响 应用标签:input 、select 、textarea v-model:<input type="text" v-model="key" /> 3.列表循环遍历 作用:循环创建多次标签(包含标签内的所有子标签和文本) 语法:v-for="(变量名,索引) in 数组" 例如:<tr v-for="(item,index) in key"> <td>{{item.xxx}}</td> <td>{{item.xxx}}</td> <td>{{item.xxx}}</td> </tr> 4.判断展示 作用:根据条件控制页面标签展示/不展示 语法:v-if / v-show 区别: (1)v-if可以和v-else-if和v-else配合完成条件判断 (2)v-if根据条件临时创建新的HTML元素,或移除HTML元素 (3)v-show根据条件,向html中添加css样式 5.绑定标签属性 作用:动态的对html中的标签属性做修改。比如:图片中的src,宽度,超链接中的href 语法:属性="key" 例如:<img :src="key"> , <a :href="key">点击一下</a> 6.绑定标签事件 作用:向html元素绑定时间。click,blur,focus,change 语法:@事件 (click,blur,focus,change) = "方法名" 例如:<button @click="add()">按钮</button>
四、Vue案例
4.1 切换图片
需求:
1.完成点击上一页/下一页切换图片的效果
2.最前和最后一页需要控制按钮只有有意义的一个
思路:
1.引入js
2.编写vue对象
3.编写html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>切换图片</title>
<script src="../js/vue-2.6.12.js"></script>
<!--
1.引入js
2.编写vue对象
3.编写html
-->
</head>
<body>
<div id="app">
<button @click="pre()" v-show="index>0">上一张</button>
<div>
<img :src="images[index]">
</div>
<button @click="next()" v-show="index<images.length">下一张</button>
</div>
<script>
const app = new Vue({
el:"#app",
data:{
//1、设置一个图片数组(图片路径)
images:[
"../img/11-00.gif",
"../img/11-01.gif",
"../img/11-02.gif",
"../img/11-03.gif",
"../img/11-04.png",
"../img/11-05.png",
"../img/10-01.png",
"../img/10-02.png"
],
//2、定义一个本次图片的所有位置
index:0
},
methods: {
//下一张
next(){
this.index++
},
//上一张
pre(){
this.index--
}
}
})
</script>
</body>
</html>
4.2 制作表格
需求:
使用Axios向指定后台发送请求,将拉取的数据使用vue技术渲染成HTML表格
后台的数据地址是:https://mock.apifox.cn/m1/3128855-0-default/emp/list
思路:
1、引入js,通过vue构造页面
2、发送ajax请求,将后台响应数据,展示页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>vue表格制作</title>
<script src="../js/vue-2.6.12.js"></script>
<script src="../js/axios-0.20.0.js"></script>
<!--思路
1、引入js,通过vue构造页面
2、发送ajax请求,将后台响应数据,展示页面
-->
</head>
<body>
<div id="app">
<table border="1" cellspacing="0" width="60%">
<tr id="head">
<th>编号</th>
<th>姓名</th>
<th>图像</th>
<th>性别</th>
<th>职位</th>
<th>入职日期</th>
<th>最后操作时间</th>
</tr>
<!--循环创建多次标签-->
<tr align='center' v-for="(user,index) in users">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td><img :src='user.image' width='70px' height='50px'></td>
<td><span>{{user.gender== 1 ? "男":"女"}}</span></td>
<td>{{user.job}}</td>
<td>{{user.entrydate}}</td>
<td>{{user.updatetime}}</td>
</tr>
</table>
</div>
<script>
const app = new Vue({
el:"#app",
data:{//真实数据
users:[]
},
methods: {
find(){
axios.get("https://mock.apifox.cn/m1/3128855-0-default/emp/list").then(resp=>{
this.users = resp.data.data
console.log( this.users )
})
}
},
//页面加载自动执行的方法,(created:建议在内部直接调用methods中的方法)
created () {
//页面刷新的时候,发送请求到服务器端,获取服务器返回的用户数据
this.find()
}
})
</script>
</body>
</html>
4.3 我的书架
需求:
1.完成书架的展示功能
2.完成书架的单本书删除功能
<!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>
<script src="../js/vue-2.6.12.js"></script>
</head>
<body>
<div id="app">
<h3>我的书架</h3>
<ul>
<li v-for="(book,index) in booksList" :key="book.id">
<!-- :key="book.id"使得checkbox同数据一起被删除 -->
<input type="checkbox">
<span>{{book.name}}</span>
<span>{{book.author}}</span>
<button @click="del(book.id)">删除</button>
</li>
</ul>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
booksList: [
{ id: 1, name: '《红楼梦》', author: '曹雪芹' },
{ id: 2, name: '《西游记》', author: '吴承恩' },
{ id: 3, name: '《水浒传》', author: '施耐庵' },
{ id: 4, name: '《三国演义》', author: '罗贯中' }
]
},
methods: {
del(id){//根据id删除元素
/* 方法1:循环数组,获取对象id,与要删除id比较,删除指定元素
//循环所有的bookList
for(let i = 0; i < this.booksList.length; i++){
//获取每一个book对象的id
let bookId = this.booksList[i].id
//判断bookId和参数id是否一致
if(bookId == id){
//从数组中删除元素
this.booksList.splice(i,1)
}
}
*/
//方法2:通过js的过滤方法filter,删除指定元素
this.booksList = this.booksList.filter(e=>{
//e表示数组中的每一条数据
return e.id != id
})
}
}
})
</script>
</body>
</html>
4.4 我的记事本
需求:
1.实现数据的载入
2.实现单个任务的删除
3.实现任务的清空
4.实现任务的添加
<!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" />
<link rel="stylesheet" href="../css/index.css" />
<script src="../js/vue-2.6.12.js"></script>
<title>我的记事本</title>
</head>
<body>
<!-- 主体区域 -->
<section id="app">
<!-- 输入框 -->
<header class="header">
<h1>我的记事本</h1>
<input placeholder="请输入任务" class="new-todo" v-model="name"/>
<!--添加任务:实现点击按钮添加任务-->
<button class="add" @click="add()">添加任务</button>
</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.name}}</label>
<button class="destroy" @click="del(item.id)"></button>
</div>
</li>
</ul>
</section>
<!-- 统计和清空 -->
<footer class="footer">
<!-- 统计:实现任务数量的统计,值为list.length -->
<span class="todo-count">合 计:<strong>{{list.length}}</strong></span>
<!-- 清空:实现任务的一键清空 -->
<button class="clear-completed" @click="clear()">
清空任务
</button>
</footer>
</section>
<!-- 底部 -->
<script>
const app = new Vue({
el: '#app',
data: {
name:"",
list: [
{ id: 2, name: '跑步一公里' },
{ id: 3, name: '跳绳200个' },
{ id: 6, name: '游泳100米' },
]
},
methods: {
//清空
clear(){
this.list=[]
},
//单个任务删除
del(id){
this.list=this.list.filter(e=>{
return e.id != id
})
},
//任务添加
add(){
//1、判断输入框内容是否为空
if(this.name){
//2、非空,构造任务对象
let task={
id: Date.now(),//当前时间毫秒数(暂时看作唯一标识)
name:this.name
}
//3、存入list数组
this.list.push(task)
//4、输入框清空
this.name=""
}
}
}
})
</script>
</body>
</html>