一、什么是Vue
1. 前端技术的发展(html、CSS、JavaScript)
(1)jQuery:是对JavaScript进行了封装,使得操作DOM、事件处理、动画处理、ajax交互变得非常简洁、方便。是JavaScript的库。
(2)Vue:通过虚拟的DOM来减少对真实DOM的操作,通过尽可能少的、简单的API实现数据的绑定。支持单向和双向的数据绑定。
(3)Vue的基本概念:
a. 是一套用于构建用户界面的渐进式框架:可以实现自底向上的逐层开发。
b. 可以用Vue开发一个全新的项目,也可以将Vue引入到一个现有的项目中
(1)MVC架构:模型 — 视图 — 控制器
- M:Model(模型),对数据进行操作
- V:View(视图),用来展示数据
- C:Controller(控制器),处理用户的请求
(2)MVVM架构:
- M:Model(模型)
- V:View(视图)
- VM:ViewModel(视图模型) —- 实现数据的双向绑定
数据的双向绑定:Vue的特征之一,当视图发生改变时,模型能立即感知到;当模型中的数据发生改变时,视图也能立即反应出来。
二、Vue开发的方式
1. 基本方式:在页面中引入vue.js文件。(vscode)
2. 组件方式:利用Vue-cli(Vue脚手架)开发。(vscode、WebStorm、Vue Gui)
3. 创建Vue实例:new Vue({})
(1)el:表示与vue实例绑定的唯一的根标签。是通过标签的id或class属性进行绑定
(2)data:初始化vue实例的属性的值。在底层会自动生成属性的setter和getter方法
可以使用 vue对象名.$data.属性名 的方式来获取值
(3)methods:用来定义方法。这些方法vue的实例可以直接访问
<script src="../js/vue.js"></script>
<body>
<div class="root">
<p>{{ msg }}</p>
<p>{{ info }}</p>
<button @click="changeMsg">请单击</button>
</div>
<div id="raat">
<p>{{ nng }}</p>
</div>
<script>
let temp = 'Hi!'
const vm = new Vue({
el:'.root',
data:{//定义数据
msg:'Hello World!',
info:temp
},
methods:{//定义方法
changeMsg(){
this.msg = '大雁塔'//this代表的是当前所在的Vue实例---vm
}
}
})
new Vue({
el:'#raat',
data:{
nng:'白桦林'
// nng:temp
},
})
console.log(vm.$data.info);
</script>
</body>
三、Vue的基本指令(重点)
1. 插值表达式:{{ 变量名 }}。将Vue实例的对应的属性值在页面中显示出来
2. 内置指令:vue的内置指令都是以 v- 开头的特殊属性,通过这些指令来操作属性的值
(1)v-show:可以根据表达式的值的真假,来决定是否显示数据
<script src="../js/vue.js"></script>
<body>
<div id="app">
<p v-show="flag">中秋节</p>
<p v-show="temp">大雁塔</p>
<!-- <button @click="show">变换</button> -->
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
flag: true,
temp: false
},
// methods:{
// show(){
// // this.flag = false
// // this.temp = true
// this.flag = !this.flag
// this.temp = !this.temp
// }
// },
})
window.setInterval(() => {
vm.flag = !vm.flag
vm.temp = !vm.temp
}, 1000)
</script>
</body>
(2)v-html:插入标签
<script src="../js/vue.js"></script>
<body>
<div id="app">
<h2>你喜欢的水果:</h2>
<form>
<label>
<input type="checkbox">苹果
</label>
<label>
<input type="checkbox">香蕉
</label>
<label>
<input type="checkbox">橘子
</label>
<label>
<input type="checkbox" @click="show">其他
</label>
<br><br>
<div v-html="htmlStr" v-show="flag">
</div>
</form>
</div>
<script>
const vm = new Vue({
el:'#app',
data:{
htmlStr:'<textarea></textarea>',
flag:false
},
methods:{
show(){
this.flag = !this.flag
}
}
})
</script>
</body>
(3)v-text:在元素中插入值。作用和插值表达式 {{ }}相同
<script src="../js/vue.js"></script>
<body>
<div id="app">
<p v-text="test"></p>
<p>{{tast}}</p>
</div>
<script>
const vm = new Vue({
el:'#app',
data:{
test:'白桦林',
tast:'凤凰花'
}
})
</script>
</body>
(4)v-if、v-else、v-else-if:类似于if-else 的功能
<script src="../js/vue.js"></script>
<body>
<div id="app">
<div v-if="role==1">
<h2>超级管理员</h2>
</div>
<div v-else-if="role==2">
<h2>管理员</h2>
</div>
<div v-else>
<h2>过客</h2>
</div>
</div>
<script>
const vm = new Vue({
el:'#app',
data:{
role:4
}
})
</script>
强调:v-show和v-if的区别
a. 实现方式:v-if底层采用appendChild方式实现,v-show是通过样式属性display来控制元素的显示和隐藏。正因为实现方式上面有差异,导致了他们的加载速度方面产生了差异
b. 加载性能:v-if的加载速度更快,v-show的加载速度慢
v-if 是惰性的,它是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建,v-show 也是情性的:如果在初始渲染时条件为假,则什么也不做一一直到条件第一次变为真时,才会开始渲染条件块。v-show 就简单得多一一不管初始条件是什么,元素总是会被洁染,并且只是简单地基于 CSS进行切换。
一般来说,v-if 有更高的切换开销,而 v-show有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好,如果在运行时条件很少改变,则使用 v-if 较好。
(5)v-for:循环指令,用于遍历数组、集合、对象的属性
<script src="../js/vue.js"></script>
<body>
<div id="app">
<ul>
<li v-for="item in arr">
{{ item }}
</li>
</ul>
<ul>
<li v-for="(item,index) in arr">
{{ index }} ==== {{ item }}
</li>
</ul>
<ul>
<li v-for="item in obj">
{{item}}
</li>
</ul>
<ul>
<li v-for="(item,key,index) in obj">
{{ item }} ==== {{ key }} ==== {{ index }}
</li>
</ul>
<ul>
<li v-for="item in objArr">
{{ item }}
</li>
</ul>
<ul>
<li v-for="item in objArr">
{{item.id}}
{{item.name}}
{{item.address}}
</li>
</ul>
</div>
<script>
const vm = new Vue({
el:'#app',
data:{
arr:[11,22,33,44,55,66],//普通数组
obj:{id:1001,name:'A1',address:'西安'},//对象
objArr:[//对象数组:数组中的每个元素都是一个对象
{id:1001,name:'A1',address:'西安'},
{id:1002,name:'A2',address:'上海'},
{id:1003,name:'A3',address:'北京'},
{id:1004,name:'A4',address:'南京'},
{id:1005,name:'A5',address:'深圳'}
]
}
})
</script>
</body>
练习:将上例中objArr的数据显示在table中
<script src="../js/vue.js"></script>
<body>
<div id="app">
<ul>
<li v-for="item in objArr">
{{item.id}}
{{item.name}}
{{item.address}}
</li>
</ul>
<table border="1">
<thead>
<tr>
<th width="100">编号</th>
<th width="100">名称</th>
<th width="100">地址</th>
</tr>
</thead>
<tbody style="text-align: center;">
<tr v-for="item in objArr">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.address}}</td>
</tr>
</tbody>
</table>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
arr: [11, 22, 33, 44, 55, 66],//普通数组
obj: { id: 1001, name: 'A1', address: '西安' },//对象
objArr: [//对象数组:数组中的每个元素都是一个对象
{ id: 1001, name: 'A1', address: '西安' },
{ id: 1002, name: 'A2', address: '上海' },
{ id: 1003, name: 'A3', address: '北京' },
{ id: 1004, name: 'A4', address: '南京' },
{ id: 1005, name: 'A5', address: '深圳' }
]
}
})
</script>
</body>
(6)v-bind:绑定元素的属性,并执行相关操作。简写方式为( :属性名 )
<script src="../js/vue.js"></script>
<style>
.ok{
color: red;
font-size: 25px;
}
</style>
<body>
<div id="app">
<a :href="link">超链接</a>
<br><br>
<p :class="{ ok:isOK }">大唐芙蓉园</p>
<button @click="change">改变超链接的值</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
link: 'http://www.baidu.com',
isOK:true
},
methods: {
change() {
this.link = 'http://www.bilibili.com',
this.isOK=!this.isOK
}
}
})
</script>
</body>
(7)v-on:监听事件,并执行相应的操作
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{msg}}</p>
<button v-on:click="change">修改</button>
</div>
<script>
const vm = new Vue({
el:'#app',
data:{
msg:'钟楼'
},
methods:{
change(){
this.msg = '曲江'
}
}
})
</script>
</body>
强调:v-on的简写方式(@事件名)
(8)v-model:将input标签的值和变量进行绑定,实现数据和视图的双向绑定
<script src="../js/vue.js"></script>
<body>
<!-- 将input标签的值和变量进行绑定,实现数据和视图的双向绑定 -->
<div id="app">
<p>性别:</p>
<input type="radio" name="sex" value="男" v-model="gender">男
<input type="radio" name="sex" value="女" v-model="gender">女
<p>你选择的性别是:{{gender}}</p>
<hr>
<p>地理分类:</p>
<select v-model="book" name="" id="">
<optgroup label="华东地区">
<option value="江苏">江苏</option>
<option value="浙江">浙江</option>
<option value="上海">上海</option>
</optgroup>
<optgroup label="西北地区">
<option value="陕西">陕西</option>
<option value="甘肃">甘肃</option>
<option value="宁夏">宁夏</option>
</optgroup>
</select>
<p>你选择的地区是:{{ book }}</p>
<hr>
<p>兴趣爱好:</p>
<input type="checkbox" name="chk" value="游戏" v-model="hobby">游戏
<input type="checkbox" name="chk" value="篮球" v-model="hobby">篮球
<input type="checkbox" name="chk" value="游泳" v-model="hobby">游泳
<input type="checkbox" name="chk" value="下棋" v-model="hobby">下棋
<input type="checkbox" name="chk" value="书法" v-model="hobby">书法
<p>你的爱好是:{{ hobby }}</p>
<hr>
<label for="">
姓名:<input type="text" v-model="userName">
</label>
<br><br>
<p>你的姓名是:{{ userName }}</p>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
gender: '',
book: '',
hobby:[],
userName:''
}
})
</script>
</body>
(9)v-once:可以让元素或组件只渲染一次,一旦绑定,数据就不会改变。
<script src="../js/vue.js"></script>
<body>
<div id="app">
<h2>v-once示例</h2>
<input type="text" v-model="onceValue">
<p>第一个:{{ onceValue }}</p>
<p v-once>第二个(一次绑定):{{ onceValue }}</p>
</div>
<script>
const vm = new Vue({
el:'#app',
data:{
onceValue:''
}
})
</script>
</body>
练习:实现如图所示的菜单效果
<script src="../js/vue.js"></script>
<style>
body {
width: 600px;
}
a {
text-decoration: none;
/*去掉下划线*/
display: block;
color: #fff;
/*字体颜色*/
width: 120px;
height: 40px;
line-height: 40px;
border: 1px solid #fff;
border-width: 1px 1px 0 0;
background: #255f9e;
}
li {
list-style-type: none;
}
#app>li {
float: left;
text-align: center;
position: relative;
}
#app li a:hover {
color: #fff;
background: #ffb100;
}
#app li ul {
position: absolute;
left: -40px;
top: 40px;
margin-top: 1px;
font-size: 12px;
}
</style>
<body>
<div id="app">
<li v-for="menu in menus" @mouseover="menu.show = !menu.show" @mouseout="menu.show = !menu.show">
<a :href="menu.url">{{menu.name}}</a>
<ul v-show="menu.show">
<li v-for="sub in menu.subMenus">
<a :href="sub.url">{{sub.name}}</a>
</li>
</ul>
</li>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
menus: [
{
name: '我的淘宝',//主菜单的名称
url: '#',//主菜单对应的地址
show: false,//是否显示子菜单
subMenus: [//子菜单的列表
{
name: '已买到的宝贝',
url: '#'
},
{
name: '已卖出的宝贝',
url: '#'
}
]
},
{
name: '收藏的宝贝',
url: '#',
show: false,
subMenus: [
{
name: '收藏的宝贝',
url: '#',
}, {
name: '收藏的店铺',
url: '#',
}
]
}
]
}
})
</script>
</body>
练习:音乐播放器
<script src="../js/vue.js"></script>
<style>
body{
background-image: url(../OIP-C.jpg);
background-repeat: no-repeat;
background-size: 100%;
}
#app{
width: 600px;
}
#app ul li h2{
color: blueviolet;
}
#app ul li p{
color: green;
}
.active{
background: skyblue;
}
</style>
<body>
<div id="app">
<audio :src="songs[currentIndex].songUrl" controls autoplay></audio>
<ul>
<li v-for="song in songs" @click="play(song.id)" :class="{active:song.id === currentIndex+1}">
<h2>歌名:{{song.name}}</h2>
<p>歌手:{{song.artist}}</p>
</li>
</ul>
</div>
<script>
const vm = new Vue({
el:'#app',
data:{
songs:[
{
id:1,
name:'假行僧',//音乐名
songUrl:'../songs/崔健-假行僧.mp3',//音乐地址
artist:'崔健'//歌手
},
{
id:2,
name:'一生有你',//音乐名
songUrl:'../songs/水木年华 - 一生有你.mp3',//音乐地址
artist:'水木年华'//歌手
},
{
id:3,
name:'再见杰克',//音乐名
songUrl:'../songs/痛仰乐队-再见杰克.mp3',//音乐地址
artist:'痛仰乐队'//歌手
},
{
id:4,
name:'伤心的人别听慢歌 (贯彻快乐)',//音乐名
songUrl:'../songs/五月天-伤心的人别听慢歌 (贯彻快乐).mp3',//音乐地址
artist:'五月天'//歌手
},
{
id:5,
name:'爱的箴言',//音乐名
songUrl:'../songs/郑钧-爱的箴言.mp3',//音乐地址
artist:'郑钧'//歌手
}
],
currentIndex:0//当前用户选择的音乐的下标
},
methods:{
play(id){
this.currentIndex = id-1
}
}
})
</script>
</body>