学习路线图
第一节
1.1 什么是Vue?
构建于用户界面的渐进式框架。
渐进式的JavaScript框架,主要关注于视图层。
渐进式框架: 视图层渲染、组件、路由、状态管理
1.2 Vue的特点?
简单易学,轻量级框架、灵活。
1.3 Vue的安装
直接在官网下载Vue.js,使用script标签引入即可;
(一)引入方式一
<script src="vue.js"></script>
(二)引入方式二
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
1.4 Vue2与Vue3的响应式原理区别?
vue2的响应式原理:es5中 Object.defineProperty
vue3的响应式原理:es6中 proxy
相比于vue2.x,使用proxy的优势如下
defineProperty只能监听某个属性,不能对全对象监听
可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)
可以监听数组,不用再去单独的对数组做特异性操作 vue3.x可以检测到数组内部数据的变化
1.5.1 Vue2入门案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello Vue</title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<input v-text="msg"><br/>
<!-- {{插入表达式}} -->
{{msg}}
<!-- 数值类型也是可以渲染的
{{}}表达式中也可以实现JavaScript表达式
-->
<p>{{num + 1}}</p>
<!-- 先分割 split(''),反转reverse(),在拼接join('') -->
<p>{{msg.split('').reverse().join('')}}</p>
<!-- 三目运算 -->
<p>{{isOk ? '显示':'不显示'}}</p>
<!-- 小写转大写 -->
<p>{{m.toUpperCase()}}</p>
</div>
<script>
//创建Vue实例对象 Vue 首字母必须大写
var vm = new Vue({
el:'#app',//element
data:{//提供数据
msg:'hello world',
num: 5,
isOk:true,
m:'abcd'
}
})
</script>
</body>
</html>
1.5.2 Vue3入门案例
<div id="app">
{{msg2}}
</div>
<!-- Vue3 -->
<script src="https://unpkg.com/vue@next"></script>
<script>
/* Vue3不支持是直接创建vue实例的 */
// var vm = new Vue({});
/* vue2和vue3是响应式有一定区别*/
var vm = Vue.createApp({//选项
data(){
return{
msg2:"hello Vue3"
}
}
});
var app = vm.mount("#app");//挂载根组件上
console.log(vm)
console.log(app)
</script>
1.5.3 function知识
<script>
function datas() {
return{
msg:'aa',
num:'2'
}
}
var obj1 = datas();//此处是函数返回
var obj2 = datas();
obj2.msg = 'bbb';
console.log(obj1)//{msg: "aa", num: "2"}
console.log(obj2)//{msg: "bbb", num: "2"}
console.log('---------------------')
var msg1 = {
msg:'aa',
}
function datas1(){
return msg1;
}
var a = datas1();//此次是对象返回,a改变msg后,影响到b
var b = datas1();
a.msg="abc"
console.log(a)//{msg: "abc"}
console.log(b)//{msg: "abc"}
</script>
1.6 MvvM开发模式
双向绑定:通过v-model,可以实现表单输入和应用数据之间的双向绑定,简单来说就是表单的数据修改可以修改数据层中的数据,数据层中的修改也可以反映到表单之中。
1.7 指令
{{插值表达式}} 数值类型也可渲染的 {{}}表达式中也可以使用JavaScript表达式
v-cloak 解决我们插值表达式闪烁问题
v-text 等同于innerText,会覆盖原本的内容,但是不会有闪烁;
v-html 等同于innerHtml,会覆盖原本的内容,但是不会有闪烁,可以解决html标签;
v-once 只会在初始化的时候插入一次值 当数据发生变化的时,视图不再发生更新;[了解]
v-pre 不编译指令,这个指令不需要表达式;[了解]
三种将数据渲染到页面的方法的缺点
1、{{}} 加载的时候会出现闪烁的问题,解决方式使用v-cloak
2、v-html 没有闪烁的问题,但是会将标签中间的数据覆盖,谨慎使用
3、v-text 没有闪烁的问题,但是会将标签中间的数据覆盖,也不嫩个渲染HTML格式数据。
第二节
2.1 v-show指令
根据我们的表达式之间的真假值, 切换元素的display:block/none
用来控制该元素是否显示,会占据dom节点,但是不会占页面的位置
2.2 v-if v-else v-else-if:
v-if 是条件渲染指令,它是根据表达式的真假来删除和插入元素;
v-else它是和v-if搭配一起使用的,充当我们的else;
三种情况下/三种以上
v-if、v-else、v-else-if:决定是否渲染当前dom流程的控制
有else关系的元素必须为兄弟元素,否则无法生效
使用这个属性之后,元素不会被渲染至dom中,也不是隐藏,而是直接删除dom
v-else-if:可以连续使用(注意:跟着v-if或者v-else-if)
2.3 v-for:
迭代、遍历、数组、对象、对象数组、数字
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-for指令</title>
<style type="text/css">
.one{list-style: none;}
.one button{width: 80px;margin-left: 5px;margin-top: 5px;}
</style>
</head>
<body>
<div id="app">
<h3>{{des}}</h3>
<!-- 遍历数组 -->
<h3 v-for="i in list" >{{i}}</h3><hr/>
<h3 v-for="(i,index) in list" >电影名称:{{i}},下标为:{{index}}</h3><hr/>
<h3 v-for="(i,index) of list" >电影名称:{{i}},下标为:{{index}}</h3><hr/>
<!-- 数组对象 -->
<h3 v-for="s in shu" >{{s.name}}</h3><hr/>
<!-- 对象数组 -->
<!-- users:该对象有三个属性,固定写法是(val,key),val:键值 key:键名 -->
<h3 v-for="(val,key,index) in users" >键值:{{val}}; 健名: {{key}}; 下标: {{index}}</h3><hr/>
<!-- 数字 -->
<li class="one" v-for="i in 9">
<button v-for="j in i">{{j}} * {{i}} = {{i*j}}</button>
</li><hr/>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data: {
des:'学习v-for指令',
list:["八百",'战狼','人民的名义','井岗镇'],
shu:[
{id:1,name:'聪聪',c:'2003'},
{id:2,name:'淞铭',c:'2003'},
{id:3,name:'建云',c:'2003'},
{id:4,name:'亮亮',c:'2003'},
],
users:{
id:1,
name:'潇潇',
age:18,
hobby:'散打,舞蹈',
},
}
});
</script>
</body>
</html>
v-if和v-show的区别:
v-if和v-show的作用都是把内容显示和隐藏,不同之处是,v-if在将元素隐藏的时候,是把整个dom元素删除。v-show是在dom元素上添加一个样式,把内容隐藏起来。
频繁切换:使用v-show较好
运行条件较少改变:使用v-if较好
第三节
3.1v-model分为两种情况:
1、在表单元素使用【input、文本域、选择框、复选框】
<!-- 提供需要挂载的标签 -->
<div id="app">
<h3>{{deg}}</h3>
<!-- 操作单行文本 -->
信息:<input type="text" v-model="deg1" placeholder='请输入内容' >
<p>接收信息:{{deg1}}</p>
<!-- 多行文本 -->
<textarea rows="6" v-model="tA" cols="15"></textarea>
<p>接收信息:{{tA}}</p>
<!-- 选择框 select -->
<select v-model="sec">
<option disabled="disabled" value="">请选择</option>
<option>蓝色满天星</option>
<option>红玫瑰</option>
<option>一束芙蓉王烟</option>
</select>
<p>选择框:{{sec}}</p>
<!-- 复选框 -->
<input type="checkbox" v-model="hobby" value="吃饭"/>吃饭
<input type="checkbox" v-model="hobby" value="睡觉"/>睡觉
<input type="checkbox" v-model="hobby" value="玩游戏"/>玩游戏
<input type="checkbox" v-model="hobby" value="运动"/>运动
<p>爱好:{{hobby}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',//挂载对象
data: {//数据属性
deg:'我是一个小可爱',
deg1:'',
tA:'这是多行文本域',
sec:'',
hobby:[]
}
});
</script>
2、在组件上使用
3、v-model修饰符:.lazy .number .trim
<div id="app">
<h3>{{des}}</h3>
<!-- .lazy 当失去焦点时才进行渲染 -->
<input type="text" v-model.lazy='msg' placeholder="请输入内容">
<p>{{msg}}</p>
<!--
.number 将我们输入框中的内容转换为数值类型,不是数字类型的会自动清空。
当先输入字符串后输入数字,就无法将字符串省略掉
-->
<input type="text" v-model.number='num' placeholder="请输入"/>
<p>{{num}}</p>
<!-- .trim自动去除输入框中的首尾空格 -->
<input type="text" v-model.trim='num' placeholder="请输入内容">
<p>{{num}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data: {
des:'我们的故事',
msg:'',
}
});
</script>
3.2 v-bind
用于属性绑定:class属性、style属性href,只要是属性就可以使用v-bind进行绑定
绑定style对象语法必须用到v-bind
[对象语法]:v-bind:style的对象语法十分直观,看着像css,其实他是一个JavaScript对象
总结:
v-model:双向绑定数据
v-bind:用于属性绑定—class属性:对象语法/数组语法/三目运算—style属性:对象语法
<div id="app">
<h1>{{deg}}</h1>
<!-- v-bind绑定herf属性 v-bind:href 绑定属性标签:属性标签名 -->
<a v-bind:href="url">点击跳转到百度</a>
<!-- v-bind:绑定src属性 -->
<img v-bind:src="imgUrl">
<!-- 简单格式 -->
<img :src="imgUrl">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data: {
deg: '我们一起学习v-bind',
url:'https://www.baidu.com/',
imgUrl:'img/1.jpg'
}
});
</script>
3.3 动态绑定
v-bind动态绑定class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-bind动态绑定class</title>
<style>
img{width: 300px;height: 400px;}
ul{list-style: none;}
.box{width: 100px;height: 100px;border: 1px solid pink}
.textSize{font-size:18px; font-weight:900;}
.textColor{color: red;}
.bg{background-color: blue;color: #fff;}
.bc{border: 5px solid green;}
</style>
</head>
<body>
<div id="app">
<h1 v-text="deg">{{deg}}</h1>
<!--对象语法:
传给v-bind:class一个对象({}).v-bind:class指令可以与普通class属性共享
-->
<ul class="box" :class="{textColor:isColor,textSize:isSize}">
<li>vue</li>
<li>node</li>
<li>react</li>
</ul>
<!-- 数组语法 -->
<div :class="[isA,isB]">
我们的股数
</div><br/>
<!-- 三目运算 -->
<li :class="isok ? isA : isB">我米滴答滴答</li>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data: {
deg: '我们一起学习v-bind',
url:'https://www.baidu.com/',
imgUrl:'img/1.jpg',
isColor:true,
isSize:true,
isA:'bg',
isB:'bc',
isok:true,
}
});
</script>
</body>
</html>
v-bind动态绑定style
<div id="app">
<h1 v-text="des"></h1>
<!--
对象语法
v-bind:style的对象语法十分直观,看着非常直观,非常像css,其实它是一个JavaScript对象
-->
<div v-bind:style="styleObject">
内联样式
</div>
<p v-bind:style="{color:ColorStyle,fontSize:FontStyle+'px'}">
你好潇潇,要下课了!!!
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data: {//数据属性
el: '#app',//挂载对象
des:'我们一起来学习v-bind绑定style',
ColorStyle: 'red',
FontStyle: 50,
styleObject: {
color:'pink',
'font-size':'50px'
}
}
});
</script>
第四节
4.1v-on指令
作用: 对页面的事件进行绑定;
语法: v-on:事件 = “事件处理的函数名” ;可以使用@代替
<div id="app">
<h3>{{des}}</h3>
<!--通过v-on给元素绑定事件 -->
<!-- <button type="button" v-on:click="num++">num++</button> -->
<!-- v-on 可以使用@符号来代替 -->
<button type="button" @click="num++">num++</button>
<p>{{num}}</p>
<hr />
<!-- 如果事件直接绑定函数名称,那么默认会传递事件的对象作为函数的第一个参数v-on:click = handle1"" -->
<button type="button" @click="handle1(123)">点击++</button>
<!-- 想传入自定义的实参值,又想获得事件对象
借助:$event关键字 vue框架内部的专门指向事件对象的关键字
$event:对象将被自动当做实参传入
event:我们需要使用$event变量显示传入 event对象
-->
<button type="button" @click="handle2(123,'abc',$event)">handle2</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data: {
des:'一起学习v-on',
num:0,
},
// methods中主要定义的是一些函数
methods: {
addNum:function(){
// this是vue的实例对象
console.log(this == vm)
//在函数中,想要使用data中的数据,一定要加this
this.num++
},
handle1(event){
console.log(typeof event);
},
handle2(num,str,event){
console.log(num);
console.log(str);
// console.log(event.target.tagName);
//event.target指的是事件触发的目标,哪一个元素触发了事件就获取改dom的元素
console.log(event.target.innerHTML);
}
},
});
</script>
4.2v-on指令和v-bind结合
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-on结合v-bind结合使用</title>
<Style>
.app{width:100px;height:100px;background-color:black;border: 1px solid red;color:#fff}
.isok{width:300px;height:300px;}
.isAER{background-color:blue;}
</Style>
</head>
<body>
<div id='app1'>
<div class="app" :class="{isok:isok1,isAER:isAER1}">
<p>我们一起学习v-on结合v-bind</p>
</div>
<button type="button" @click="handle">转换</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app1',
data: {
isok1:false,
isAER1:false
},
methods: {
handle() {
//控制值在true或false之间转换
this.isAER1 = !this.isAER1
this.isok1 = !this.isok1
}
},
});
</script>
</body>
</html>
4.3v-pre指令
跳转当面元素和它子元素的编译过程
4.4v-once指令
v-once 覆盖原始的内容,只执行一次[数据改变时,插值处的内容不会持续更新]
<div id="app">
<!-- v-pre显示原始的内容,跳过编译 -->
<p v-pre>{{msg}}</p>
<!-- v-once 覆盖原始的内容,只执行一次[数据改变时,插值处的内容不会持续更新] -->
<p v-once>{{msg}}</p>
<h3 v-pre v-text="msg">这是你要计算的值</h3>
<button type="button" @click="name">增加</button>
<button type="button" @click="name1">减少</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data: {
msg: 0,
},
methods: {
name() {
this.msg++
},
name1() {
this.msg--
},
},
});
</script>
4.5事件修饰符
修饰符是由.开头的指令后缀的来表示的
.capture实现捕获触发事件的机制 【实现捕获触发事件的机制,即是给元素添加一个监听器,当元素发生冒泡时,先触发带有该修饰符的元素。若有多个该修饰符,则由外而内触发。】
.prevent阻止默认事件/.once只触发一次函数
.self实现只有点击当前元素,才会触发事件处理函数
.self和.stop的区别
.self只会阻止自己身上冒泡行为的触发,不会真正阻止冒泡行为;.stop阻止冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件修饰符</title>
<style>
.inner {width: 400px;height: 400px;background-color: pink;}
.outer {width: 600px;height: 600px;background-color: blue;}
</style>
</head>
<body>
<div id="app">
<!-- .stop阻止冒泡 -->
<div class="inner" @click="name">
<input type="button" value="点击" @click.stop="name1">
<!-- 修饰符可以串联 既可以阻止默认事件 还可以阻止冒泡事件 -->
<a href="https://www.bilibili.com/video/BV1vE411871g?p=13" @click.prevent="linkf">有问题来B站</a>
</div>
<!-- .prevent阻止默认事件 -->
<a href="https://www.bilibili.com/video/BV1vE411871g?p=13" @click.prevent="linkf">有问题来B站</a>
<!-- .capture实现捕获触发事件的机制 -->
<div class='inner' @click.capture="div1Handler">
<input type="button" value='戳他11' @click="bntHander1"/>
</div><br/>
<!-- .self实现只有点击当前元素,才会触发事件处理函数 -->
<div class='inner' @click.self="div1Handler">
<input type="button" value='戳他' @click="bntHander1"/>
</div><br/>
<!-- .self和.stop的区别 -->
<div class='outer' @click="div2Handler">
<!-- .self只会阻止自己身上冒泡行为的触发,不会真正阻止冒泡行为 -->
<div class='inner' @click.self="div2Handler">
<input type="button" value='戳他22' @click="bntHander1"/>
</div>
</div>
<!-- .once只触发一次函数 -->
<a href="http://www.baidu.com" v-on:click.prevent.once='onece'>有问题找我</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
des:'我们来学习事件修饰符!!!',
},
methods: {
name() {
console.log("这是触发了inner的按钮");
},
name1(){
console.log("这是触发了button的按钮");
},
linkf(){
console.log("有问题来找B站!!!!");
alert('有问题找B站');
},
div1Handler(){
console.log("这是触发了div1Handler的按钮");
},
bntHander1() {
console.log("这是触发了bntHander1的按钮");
},
div2Handler() {
console.log("这是触发了div2Handler的按钮");
},
onece() {
console.log("这是触发了onece事件");
}
},
});
</script>
</body>
</html>
v-once指令和.once修饰符是有区别的?
v-once是应用在我们的标签元素上;.once修饰符是应用在我们的事件函数上
第五节
5.1v-for为什么要加key
无:key属性,状态默认绑定的是位置(index 下标),有key时状态根据key属性绑定到的相应数组元素
绑定到的元素,建议用id (唯一标识)
加key主要是为了高效的更新虚拟dom
5.2按键修饰符
@keyup 监听键盘按下的事件
@keyup.enter 响应enter键 串联修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>按键修饰符</title>
</head>
<body>
<div id="app">
<h1>{{msg}}</h1><br/>
<label for="">Id:
<input type="text" v-model="id"/>
</label>
<label for="">name:
<input type="text" v-model="name"/>
</label>
<button type="button" @click="add">添加</button>
<!--@keyup 监听键盘按下的事件 -->
<input type="text" @keyup="add" value="按任意键"/>
<!--@keyup.enter 响应enter键 串联修饰符 -->
<input type="text" @keyup.enter="add"/>
<!-- 注意:v-for循环的时候,key属性只能使用num和string获取 -->
<!-- key在使用的时候必须使用v-bind属性绑定的形式,指定key的值 -->
<p v-for="item in users" :key="item.id">
<input type="checkbox" />{{item.id}}----{{item.name}}
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data: {
msg: '增加数据、按键修饰符',
id: '',
name: '',
users:[
{id:1,name: '莫非'},
{id:2,name: '梦缘'},
{id:3,name: '建云'}
]
},
methods: {
add() {
/* 在数组末尾加一个或多个元素,并返回新的长度 */
//this.users.push({id:this.id,name:this.name})
/* 在数组开头添加一个或多个元素,并返回新的数组 */
this.users.unshift({id:this.id,name:this.name})
},
},
});
</script>
</body>
</html>