Vue学习笔记完整版
Vue的特点
采用模块化模式,、提高代码的复用率,且维护更加友好
声明式编码,让编程人员无需直接操作DOM,提高开发效率
使用虚拟DOM(Virtual-DOM)+优秀的Diff算法,尽量复用DOM节点

Vue的配置对象
el:挂载点
el——就是element的简称
el用于指定当前Vue实例为那个容器,值通常为css的选择器
一个Vue实例不能同时去接管两个容器
一个Vue实例只能对接一个容器
Vue实例和容器之间是一对一的关系
x1const x=new Vue({2 el:"#id",//也可以这么写——el:document.getElementById("id")3})4
data:数据对象
Vue中用到的数据定义在data中
data中可以写复杂数据类型的数据
渲染复杂数据类型是,遵守js的语法即可
xxxxxxxxxx41
2<div id="app">3 {{name.toUpperCase()}}4</div>toUpperCase方法是将小写字母变成大写字母的方法
xxxxxxxxxx71
2const x=new Vue({3 el:"#app",4 data:{5 name:"abc"6 }7})在Vue的实例里面html标签里使用{{}}来接受的数据属于插值语法,
另外还有一种获取数据的方式指令语法,但是指令语法是用于在标签属性上或者标签内部,而插值语法的数据是在标签文本内容里
插值语法:
{{}}——用于指定标签体的内容指令语法:
——用于解析标签(包括:标签的属性、标签体的内容、绑定事件等)
el与data的两种写法
通过实例化Vue可得知


首先要对Vue进行实例化然后将其赋值给一个变量
el的第二种写法
xxxxxxxxxx111<div id="a">2{{name}}3</div>4<script>5const a=new Vue({6data:{7name:"李白"8}9})10a.$mount("#a")11</script>使用a.$mount(“”)替换el,这样做可以做其他事项
data的第二种写法:函数式——等到学到组件时候必须使用这种函数式的data不能使用对象式data
xxxxxxxxxx1212<script>3const a=new Vue({4data:function(){5console.log(this) //此处的this是Vue实例对象6return{7name:"李白"8}9}10})11a.$count("#a")12</script>
如果使用的是箭头函数来写data,上方打印的this就变成了window全局对象,
即:data:()=>{
console.log(this) //当前this就变成了window全局对象
return{
name:“李白”
}
}
以后学到组件时,data必须使用函数式(不能使用箭头函数和对象式),否则会报错
由Vue管理的函数一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了
常用的指令语法
v-bind——绑定元素的属性值可以用冒号替换——
<p v-bind:title="this is a p"></p>——><p :totle="this is a p"></P>v-if
v-for
v-show——格局获取到的值来切换元素是否显示
案例:点击按钮切换图片的显示和隐藏
xxxxxxxxxx2112<body>3<div id="a">4<button @click="show">enter</button>5<img src="./image_0.13118047491897467.gif" alt="" v-show="a">6</div>7</body>8<script src="./vue.js"></script>9<script>10new Vue({11el:"#a",12data:{13a:false,14},15methods: {16show:function(){17this.a=!this.a18}19},20})21</script>v-text——设置元素的文本值即innerText
v-html——设置元数的innerHTML
v-on——绑定事件可以简写为@——需要用到methods——methods是编写方法函数的的一个对象,与data属于同级别
v-model——只能运用在输入类元素上
案例:双向绑定数据
xxxxxxxxxx91<input v-model="value"/>2<script>3new Vue({4el:"",5data:{6name:"value"7}8})9</script>
VUE.js学习
学习本门课程需要掌握HTML、CSS、JavaScript、AJAX基础知识
开发版本引用
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
VUE基础
JavaScript框架
简化DOM操作
响应式数据驱动
第一个VUE程序
xxxxxxxxxx2612<html lang="en">3
4<head>5 <meta charset="UTF-8">6 <meta http-equiv="X-UA-Compatible" content="IE=edge">7 <meta name="viewport" content="width=device-width, initial-scale=1.0">8 <title>VUE基础</title>9 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>10</head>11
12<body>13 <div id="app">14 {{ message }}15 </div>16</body>17<script>18 var app = new Vue({19 el: '#app',20 data: {21 message: '你好 世界 我爱你 不客气'22 }23 })24</script>25
26</html>步骤:
导入开发版本的vue.js
创建vue实例对象,设置el属性和data属性
使用简洁的模板语法把数据渲染到页面
el:挂载点
xxxxxxxxxx111<div id="a">2 {{message}}3</div>4<script>5 var a=new Vue({6 el:"#a",//选择器获取id7 data:{8 message:"hello world" //将页面信息打印出来9 }10 })11</script>el——是用来对标签进行选择的,id选择器、class选择器、标签选择器等,在实际开发中建议使用id选择器,对于选择的对应标签只能支持双标签——即有开始标签和结束标签的,如div等,不能支持单标签,如audio标签等,因为在单标签内部不能书写其他内容,即包裹不了其他内容,但也不是什么双标签都能让el挂载到,如 标签和 标签
Vue实例的作用范围是el选项命中的元素及其内部的后代元素
可以使用其他的选择器,但建议使用id选择器
不要使用body标签和html标签
el——的作用是设置Vue实例挂载(管理)的元素
data:数据对象
xxxxxxxxxx211<div id="a">2 {{message}}<!--在标签中要写入框架下的对应的数据对象就要使用两个花括号来对属性进行包裹起来-->3 <h2>4 {{shcool.name}}<!--获取shcool里的name属性-->5 </h2>6</div>7<script>8 var a=new Vue({9 el:"#a",//选择器获取id10 data:{ //data数据对象11 message:"hello world" ,//将页面信息打印出来12 shcool:{13 name:'LiBai',14 age:18,15 set:'boy',16 id:12317 }18 19 }20 })21</script>Vue中用到的数据定义在data中
data中可以写复杂数据类型的数据
渲染复杂数据类型是,遵守js的语法即可
Vue本地应用
通过Vue实现常见的网页效果
学习Vue指令,以案例巩固知识
Vue指指的是以 v- 开头的一组特殊语法
内容绑定、事件绑定
v-once
v-once所在的节点在初次动态渲染后,就视为静态内容
以后数据的改变不会引起v-once所在节点结构内容的更新,可以用于优化性能
xxxxxxxxxx201
2<div id="a">3 <span v-once>{{a}}</span>4 <button>5 点击a+16 </button>7 <spam>{{a}}</spam>8</div>9<script>10const vm=new Vue({11 el:"#a",12 data:{13 a:114 },methods:{15 click:function(){16 this.a++17 }18 }19})20</script>像上面的的例子,在第一个span标签里使用了v-once指令后,点击button执行函数click后,第二个span标签的值会发生改变,但第一个span不会发生改变
v-pre
让Vue跳过其所在节点的编译过程
可以利用它跳过没有使用指令语法,没有使用插值语法的节点,会加快编译,相当于vue不去解析当前节点
xxxxxxxxxx131<div id="a">2 <span>{{a}}</span>3 <span v-pre>{{b}}</span>4</div>5<script>6 const vm=new Vue({7 el:"a",8 data:{9 a:1,10 b:211 }12 })13</script>执行结果:
1 {{b}}
v-text
这个指令是把数据设置给标签的文本值(textContent)
xxxxxxxxxx191<div id="a">2 <h2 v-text="message+'!'">112233</h2>3 <h2>4 I Love You:{{messge+"!"}}<!--使用这种方式,标签里的内容不会被替换掉-->5 </h2>6</div>7<script>8 var a=new Vue({9 el:"#a",10 data:{11 message:"hello world",//这样执行程序的话,就会在h2标签内部打印出hello world字样,但是会有个缺点,就是无论对应标签内有什么,都会被替换掉,即112233会被替换成hello world12 school:{13 name:"BD",14 adress:"BeiJin",15 age:20016 }17 }18 })19</script>支持字符串拼接,如
{{massage+“!”}}默认写法会替换全部内容,使用差值表达式{{}}可以替换指定内容
内部支持写表达式
v-text:”message+ ‘!’ ”
v-html
设置标签的innerHTML
xxxxxxxxxx271<div id="a">2 <p v-html="name">3 4 </p>5 <p v-html="web"><!--显示baidu并且是一个超链接-->6 7 </p>8 <p v-text="web"><!--显示的是<a href='https://www.baidu.com'>baidu</a>-->9 10 </p>11</div>12<script>13var a=new Vue({14 el:"#a",15 data:{16 name:"I Love You",17 data:{18 year:2022,19 mouth:4,20 day:24,21 week:6,22 web:" <a href='https://www.baidu.com'>baidu</a> "23 }24 25 }26})27</script>v-text和v-html指令的差异
v-text是直接显示data里面的内容的,data里面写什么就显示什么,而v-html里,如果data里面是符合html结构的的语句的话就会显示HTML语句,其余与v-text类似
内容中的html结构会被解析为标签
v-text指令无论内容是什么只会解析为文本
解析文本内容使用v-text,解析html结构使用v-html
v-on基础
为元素绑定事件
v-on:可以使用@代替,如下所示
xxxxxxxxxx271<div id="a">2 <input type="button" v-on:click="content"><!--鼠标单击事件-->3 <input type="button" v-on:click="home">4 <input type="button" @dblclick="food"><!--鼠标双击事件-->5 <p>6 {{text}}7 </p>8</div>9<script>10 var a=new Vue({11 el:"#a",12 data:{13 text:"very good"14 }15 methods:{16 content:function(){17 alert('ilove you')18 },19 home:function(){20 alert('remennber me')21 },22 food:function(){23 this.text+="you"//调用方法使用关键字this,每点击一次在text文本后面增加一个you24 }25 }26 })27</script>v-on指令作用是为元素绑定事件
事件名不需要写on
指令可以简写为@
绑定方法定义在methods属性中
方法内部通过this关键字可以在访问定义在data 中的数据
methods:逻辑
在里面定义方法,v-on绑定的方法
案例:计数器
xxxxxxxxxx331<body>2 <div id="jishuqi">3 <div class="input_num">4 <button @click="pdd">-</button>5 <span>{{num}}</span>6 <button @click="add">+</button>7 </div>8 </div>9</body>10<script>11 var a= new Vue({12 el:"#jishuqi",13 data:{14 num:115 },16 methods:{17 add:function(){18 this.num+=119 if(this.num>10){20 alert('以超出最大数额')21 this.num = 1022 }23 },24 pdd:function(){25 this.num-=126 if (this.num < 0) {27 alert('以到达最低数额')28 this.num=029 }30 }31 }32 })33</script>显示切换、属性绑定
v-show
根据表达值的真假切换元素的显示和隐藏
本质是切换display的值
xxxxxxxxxx181<div id="a">2 <button @click="show">Enter</button>3 <img src="" v-show="">4</div>5<script>6var a=new Vue({7 el:"a",8 data:{9 show:ture,10 age:1811 },12 methods:{13 enter:function(){14 this.show=!this.show//这样点击按钮时就会来回切换show的值从而到达显示和隐藏掉图片的目的15 }16 }17})18</script>指令后面的内容最终都会解析为布尔值
值为true时显示,为false时隐藏
v-if
根据表达式的真假来切换元素的显示和隐藏(操作dom元素)
xxxxxxxxxx191<div id="a">2 <p v-if="ture">3 this is a page4 </p>5 <p v-if="show">6 this is a page too!7 </p>8 <p v-if="!show">9 these are many pages and all for me!10 </p>11</div>12<script>13 var a=new Vue({14 el:"#a",15 data:{16 show:false17 }18 })19</script>本质是通过操作dom元素来切换显示状态
当表达式的值为true的时候元素存在于dom树中,为false时从dom树中移除
v-bind
设置元素的属性(比如src、title、class)
语法:
v-bind:属性名="表达式"使用的时候v-bind是可以省略的直接写成
<img :title="imgtitle">的样式,注意的是标签名与指令后面必须要有一个空格相隔,切不可写成<img:title="imftitle">等模样
xxxxxxxxxx201<div id="a">2 <img :src="imgsrc" alt="" :title="imgtitle" @click="active" :class="imgactive?'active':''"><!-- 简写写法,其中:class="imgactive?'active':''"这样的写法是根据获取大imgactive的布尔值进行赋值,如果为真则赋值为active否则赋值为空 -->3 <img v-bind:src="imgsrc" alt="" v-bind:title="imgtitle+'!!!!!'" ><!-- 完整写法,也可以用字符串拼接 -->4 <img :src="imgsrc" alt="" :title="imgtitle" @click="active" :class="{active:imgactive}">5</div>6<script>7 var a=new Vue({8 el:"#a",9 data:{10 imgsrc:"./1.jpg",11 imgtitle:"this is a photo",12 imgactive:false13 },14 methods:{15 active:function(){16 this.imgactive=!this.imgactive17 }18 }19 })20</script>v-bind指令是为元素绑定属性
完整写法是v-bind:属性名
简写的话直接省略v-bind只保留 :属性名
需要动态的增删class建议使用对象的方式
案例:图片切换
xxxxxxxxxx301 2<div id="img">3 <button v-show="index!=0" class="left" @click="up">◀</button>4 <img :src="src[index]" alt="">5 <button v-show="index!=3" class="right" @click="down">▶</button>6 </div>7</body>8<script>9 var a = new Vue({10 el: "#img",11 data: {12 src: [13 "./1.png",14 "./2.png",15 "./3.png",16 "./4.png"17 ],18 index: 019 },20 methods: {21 up: function () {22 this.index--23 },24 down: function () {25 this.index++26 }27 }28 })29</script>30
xxxxxxxxxx531 * {2 margin: 0px;3 padding: 0px;4 box-sizing: border-box;5 }6
7 body {8 width: 100vw;9 height: 100vh;10 display: flex;11 justify-content: center;12 align-items: center;13 }14
15 #img {16 width: 50vw;17 display: flex;18 justify-content: center;19 align-items: center;20 padding: 0px;21 box-shadow: 5px 5px 6px rgba(0, 0, 0, 0.5), -5px -5px 6px rgba(0, 0, 0, 0.5);22 }23
24 button {25 margin: 0px;26 padding: 0;27 display: flex;28 justify-content: center;29 align-items: center;30 cursor: pointer;31 background-color: rgba(0, 0, 0, 0.5);32 border: none;33 height: 5vw;34 width: 2vw;35 color: white;36 position: absolute;37 }38
39 .left {40 left: 25vw;41 border-top-right-radius: 1vw;42 border-bottom-right-radius: 1vw;43 }44
45 .right {46 right: 25vw;47 border-top-left-radius: 1vw;48 border-bottom-left-radius: 1vw;49 }50
51 img {52 width: 50vw;53 }列表循环、表单元素绑定
v-for指令
根据数据生成列表结构(并且是响应式类)
xxxxxxxxxx201<div id="a">2 <ul>3 <li v-for="item in arr">{{item}}</li><!--其中in是关键字,item是一个名字而已可变,和arr则是要遍历的数组名,根据定义好的数组名进行修改-->4 </ul>5 <div v-for="(a,index) in object" :title="a.name"><!--对象数组的引用,(a,index)这是在对象数组前面添加的一个索引-->6 {{index}}{{a.name}}{{a.id}}<!--属性值调用-->7 </div>8</div>9<script>10var a=new Vue({11 el:"#a",12 data:{13 arr:[1,2,3,4,5],14 object:[{name:"jack",id:2000},{name:"Ross",id:2001}]15 },16 methods:{17 add:function(){this.object.push({name:'ailishi',id:1999})}//函数添加数组属性以及值18 }19})20</script>v-for的作用是根据数据生成列表结构
数组经常和v-for结合使用
语法是(item,index) in 数据——item代表每一项,其不必名为item命名可以任意,index代表索引,in是关键字,数据则为定义好的那个数组名(需要注意的是,如果遍历的是对象,那index(也可以自定义名字)就代表的是对象的属性名,item就对应的是属性值,与之前的数组对是相反的)
item和index可以结合其他指令一起使用
数组长度的更新会同步到页面上时响应式的
使用v-for指令,还有一个重要的的东西——key,key的特殊主要是在Vue的虚拟DOM算法,在新旧的nodes对比时辨别VNodes,如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型的元素的算法,而使用key,它会基于key的变化量重新排列元素顺序,并且移出 key不存在的元素。
有相同父元素的子元素必须有独特的key,重复的key会造成渲染错误
常见的用例是结合v-for
xxxxxxxxxx41
2<ul>3 <li v-for="item in items" :key="item.id">{{item}}</li>4</ul>如果不想使用对象或者数组定义一个id属性,则可以让key的值等于对应的索引
xxxxxxxxxx31<ul>2 <li v-for="(item,index ) in items" :key="index">{{item}}</li>3</ul>v-for同样能遍历字符串
这时,item代表了字符串的每一个字,index就是每一个字对应的索引
xxxxxxxxxx131<div id="#app">2 <ul>3 <li v-for="(a,b) in str">{{a}}:{{b}}</li>4 </ul>5</div>6<script>7new Vue({8 el:"",9 data:{10 str:"hello"11 }12})13</script>v-for可以遍历指定次数——
v-for="(i,index) in 10"
v-for指令:
用于展示列表数据
语法:v-for=“(item,index) in xxx”:key=“yyy”
可遍历:数组、对象、字符串、指定次数
在Vue中key的作用
key就是给节点一个标识——就相当于与人类生活中的身份证号
v-on补充
传递自定义参数,事件修饰符
更多事件修饰符参考地址 https://cn.vuejs.org/v2/api/#v-on
要是想要传递参数在后面加上具体的值,如:
<input type="button" @click="a(p1,p2)"/>
xxxxxxxxxx141<div id="a">2 <input type="button" @click="a(p1,p2)"/>3 <input type="button" @keyup.enter="sayHi"/><!--按钮事件,定义一个按钮之后按下这个按钮就会触发对应的事件,使用'.'来对定义的按键进行绑定,如本例中定义了按下回车键就会触发函数sayHi事件-->4</div>5<script>6 var a=new Vue({7 el:"#a",8 data:{},9 methods:{10 a:function(p1,p2){},11 sayHi:function(){alert("hello world")}12 }13 })14</script>v-model
获取和设置表单元素的值(双向数据绑定)
xxxxxxxxxx191<div id="a">2 <input type=:"text" v-model="information" @keyup="a"><!--关联时在input里输入的内容就会同步显示在p标签里面,切是实时的,当按下回车按钮时也会弹出一个警告框同步input输入的内容-->3 <p>4 {{information}}5 </p>6</div>7<script>8 var a=new Vue({9 el:"#a",10 data:{11 information:""12 },13 methods:{14 a:function(){15 alert(this.information)16 }17 }18 })19</script>v-model指令作用是便捷的设置和获取表单元素的值
绑定的数据会和表单元素值相关联
表单元素的值和绑定的数据是双向绑定的无论修改谁另一个的值也会随之改变
案例:记事本
xxxxxxxxxx401<body>2 <div id="txt">3 <input type="text" v-model="content" @keyup.enter="add" placeholder="请输入任务">4 <ul>5 <li v-for="(a,index) in arr"><span class="index">{{index+1}}.</span><span>{{a}}</span><button class="bu" @click="clear(index)">x</button></li>6 </ul>7 <div class="clearall"><span class="num" >{{num}}</span><button class="but" @click="clearall">clear</button></div>8 </div>9</body>10<script>11 var a = new Vue({12 el: "#txt",13 data: {14 content: "",15 arr: [],16 num:017 },18 methods: {19 add: function () {20 if(this.content==''){21 alert('您什么都没有输入哟,我的小可爱')22 }else{23 this.num++24 this.arr.push(this.content)25 this.content = ''26 }27
28 },29 clearall:function(){30 this.arr.splice(0)31 this.num=032 this.content = ''33 },34 clear:function(index){35 this.arr.splice(index,1)36 this.num--37 }38 },39 })40</script>v-cloak指令
理解MVVM模型
M:模型(Model):对应data中的数据。
V:视图(View):模板
VM:视图模型(ViewModel):Vue实例对象)

所以但要使用变量来接收Vue实例化对象时一般标准化使用vm来接收,即:
const vm= new Vue({})
因此也得出了在标签体里的内容也不仅仅可以写data里的属性了,可以也vm里有的东西,例如:
<div id="a">{{$options}}</div>

M:模型(model)——data中的数据
V:视图(View)——模板代码
VM:视图模型(ViewModel)——Vue实例
data中的所有属性,最后都会出现在VM身上
vm身上所有的属性以及Vue原型上所有的属性,在Vue模板上都可以使用
数据代理
回顾Object.defineProperty方法
数据代理使用到该方法
Object.defineProperty——给一个对象添加属性用的方法
xxxxxxxxxx211let number=182let person={3 name:"LiBai",4 sex:"man"5}6Object.defineProperty(person,'age',{ //该方法有三个参数,第一个为对象名,第二个为添加的属性名,第三个为一个{},里面定义属性的值,还有一些控制项7 value:18,8 enumerable:true,//控制属性是否可以每局9 writable:true , //控制属性是否可以被修改10 configurable:true, //控制属性是否可以被删除11 12 //当有人读取对象的属性时,get函数就会被执行,且返回值就是对应属性的值,这里是读取person对象的age属性13 get:function(){14 return number //使用这个方法就可以让person对象和number变量产生直接的联系,即当number的值变化的时候person的属性age的值也会跟着变化15 },16 17 //当有人修改对象的属性时,set()函数就会被调用,且会收到修改的具体值18 set(value){19 number=value 20 }21})数据代理的定义
数据代理:通过一个对象代理对另一个对象中属性的操作 (读/写)
例如:
xxxxxxxxxx111
2let obj1={x:100}3let obj2={y:200}4Object.defineProperty(obj2,'x',{5 get:function(){6 return obj1.x7 },8 set(value){9 obj1.x=value 10 }11})Vue中的数据代理
Vue实例里的data,如果要使用的话,是要写成
vm._data的方式,这样就可以直接调用里面的属性,如vm._data.nameVue数据代理的好处——更加方便操作data中的数据
基本原理:
通过Object.defineProperty()把data对象中所有的属性添加到vm上,为每一个添加到vm上的属性,都指定一个getter和setter,在getter和setter内部去操作data中对应的属性

事件处理
使用指令——
v-on可以简写为@,后面加上事件的类型
所有被Vue管理的函数最好都写成普通函数,否则函数里面的
this关键字指向的是window全局对象
函数写在methods配置项里面——需要注意的是,函数也可以写在data配置项里面,但是会让Vue执行消耗更多的性能,即会数据代理,而写在methods里面是不需要数据代理的
xxxxxxxxxx261const vm=new Vue({2 el:"",3 data:{4 5 },6 methods:{7 //例如下的箭头函数的this就指向的是window8 showInfo:(event)=>{9 10 console.log(this)11 12 },13 //如下的普通函数就指向的是Vue14 addNumber:function(event){15 console.log(this)16 },17 //如下的写法也可以18 addSum(event{19 console.log(this)20 21 }).22 23 24 }25})26
当需要使用参数时,则在对应的标签上加上
(参数)即可,例如<div @click='add(1)></div>'当需要传参且还需要使用event——即事件对象时,在括号里面添加上$event,例如
<div @click='add($event,1)></div>'$event可以放在参数的前面也可以放在参数的后面
事件回调需要配置在methods对象中,最终会在vm上
methods中配置的函数,不要用箭头函数,否则this就不是vm了
methods中配置的函数,不是被Vue管理的函数,this的指向是vm或组件实例对象
@click=“demo”和@click=“demo($event)”效果一样,只是后者能够传参
事件修饰符
prevent:阻止默认事件
stop:阻止事件冒泡
once:事件只触发一次
capture:使用事件的捕获模式
self:只有event.target——获取操作该函数的对象,输出时打印的是操作函数的具体元素信息。是当前操作的元素才触发事件
xxxxxxxxxx1712<div id="app">3<button @click="add">4点击5</button>6</div>7<script>8const vm=new Vue({9el:"#app",10data:{},11methods:{12add(event){13console.log(event.target)14}15}16})17</script>
passive:事件的默认行为立即执行,无需等待事件回调执行完毕
如果要是有事件修饰符,则在事件后面加上即可,例如<button @click.stop='add(event)'</button>
如果需要使用多个修饰符——例如需要阻止冒泡,也需要阻止默认事件时,就可以连着写修饰符,会按照顺序执行修饰符的功能
xxxxxxxxxx31<div @click="b">2<a href="https://www.baidu.com" @click.stop.prevent="a">百度</a> <!--这样就能让当点击a百度时就不进行跳转到百度页面,也不会执行父级元素上的的函数b-->3</div>
键盘事件
键盘上对应的每个按键的编码,使用e.keyCode获取对应按键的编码
例如——
<button @keyup.enter="add"></button>当点击键盘上的回车键时会触发对应的函数,如果单独使用@keyup或者@keydown则点击键盘上的任何一个按键都会触发对应的函数
在Vue上,给出了常用的几个按键的别名,以下:
回车——enter
删除——delete
退出——esc
空格——space
换行——tab(特殊,必须配合keydowe使用)
上——up
下——down
左——left
右——right
Vue未提供的别名的按键,可以使用按键的原始key值(注意,是key值——会直接获取到键盘上按键的名称,区别于keyCode获取按键的编码,有时按键上的名称不是单个单词,而是以驼峰命名组成的多个单词组成,这时就不能使用)去绑定,当注意要转为kebab-case(短横线命名)
系统修饰键(用法特殊):ctrl,alt,shift,meta(就是win键)——这四个按键配合keyup使用都会有问题的
配合keyup(键盘事件)使用:按下修饰的同时,再按下其他键,随后释放其他键,事件才会触发
配合keydown使用,正常触发
也可以使用keyCode去指定具体的按键(目前不推荐)——mdn上明确标识已经弃用该方式,所以现在最好的方式时使用对应按键的名称去绑定按键执行操作
Vue.config.keyCodes.自定义键名=键码,可以去定制按键别名(也不太推荐该方法)
xxxxxxxxxx412Vue.config.keyCodes.huice=13 //以此就可以使用huice这个名称来绑定编码为13(回车)的按键了34
需要注意的是,如果需要使用组合键,例如需要使用按下ctrl和y键时才会触发事件时,可以连着写
xxxxxxxxxx412<button @keyup.ctrl.y="a"> <!--点击ctrl+y组合键时才会触发a函数-->3点击4</button>
计算属性与监视
计算属性-computed
计算属性(computed)也属于一个新的配置项,和data属于同级别的Vue属性
只要data中的数据发生变化Vue就会重新解析模板
xxxxxxxxxx281
2<div id="app">3 <input v-model="fistName"><br/>4 <input v-model;="lastName"><br/>5 <p>6 {{fullName}}7 </p>8
9</div>10<script>11const vm=new Vue({12 el:"app",13 //在data里面的叫做属性14 data:{15 fistName:"张",16 lastName:"三"17 },18 //,在computed里面的叫——计算属性19 computed:{20 fullName:{21 //当有人读取fullName时执行getter,这里的getter和前面学到的数据代理的getter是有区别的,这里的this指向Vue实例(Vue已经帮我们处理好了),getter的返回值就是fullName的值22 get(){23 return this.fistName+"-"+this.lastName24 }25 }26 }27})28</script>注意点
在计算属性里时,Vue已经帮我们做了数据缓存,所以在初始读取fullName时getter被调用,以后再被读取时就不用调用getter了。
计算属性所依赖的值发生该变的时候getter也会被调用,比如以上的data里的数据发生改变了,导致了fullName的数据发生了改变了,那getter也就会被调用
所以在设计getter时,getter拥有两个特征(以上)
同样的,getter不能写成箭头函数的模样,否则this的指向就变成了window
注意
使用计算属性computed时,切记不要把computed里面的对象当做对象那样的方式来使用,例如使用fullName对象里面的方法——funName.get(),在计算属性里面这样的方式不被允许的,应当把对象当做变量来使用,就像案例里面那样的使用插值表达式{{fullName}}
计算属性:
定义:要用的属性不存在,要通过已有的属性计算得来
原理:底层借助Object.definepeoperty方法提供的getter和setter
get函数什么时候执行?
初次去读时会执行一次
当依赖的数据发生变化时会被再次调用
优势:与methods实现相比,内存有缓存机制(复用),效率更好,调用方便
备注:
计算属性最终会出现在vm上,直接读取即可
如皋计算属性要被修改,那必须写在set函数去响应修改,且set中药引起计算时依赖的数据发生改变
计算属性的简写
只有考虑读取不考虑修改的时候才能使用简写的方式
xxxxxxxxxx271
2<div id="app">3 <input v-model="fistName"><br/>4 <input v-model;="lastName"><br/>5 <p>6 {{fullName}}7 </p>8
9</div>10<script>11const vm=new Vue({12 el:"app",13 //在data里面的叫做属性14 data:{15 fistName:"张",16 lastName:"三"17 },18 //,在computed里面的叫——计算属性19 computed:{20 //简写的方式21 fullName:function(){22 return this.fistName+"-"+this.lastName23 }24 }25 }26})27</script>监视属性
使用watch作为Vue的监视属性
xxxxxxxxxx241const vm=new Vue({2 el:"",3 data:{4 isHot:true5 },6 methods:{7 8 },9 computed:{10 11 },12 //监视属性13 watch:{14 //直接写要监视的属性,这里监视的是data里的isHot属性15 isHot:{16 //当isHot发生改变时调用hander函数,这个函数不仅能发现isHot别修改了,也会吧isHot修改前的值返回,也会吧isHot修改后的值返回17 //也可以监视计算属性18 handler(newValue,oldValue){ //两个参数——新的值,原来的值19 20 },21 immediate:true//immediate——初始化时,让handler调用一下22 }23 }24})还有另一种监视属性的写法,如下
xxxxxxxxxx231
2const vm=new Vue({3 el:"",4 data:{5 isHot:true6 },7 methods:{8 9 },10 computed:{11 12 },13 14})15 //这样写大有两个参数,第一个是要监视的属性,第二个是配置对象,学法和前面的一样16vm.$watch("isHot",{17 //当isHot发生改变时调用hander函数,这个函数不仅能发现isHot别修改了,也会吧isHot修改前的值返回,也会吧isHot修改后的值返回18 //也可以监视计算属性19 handler(newValue,oldValue){ //两个参数——新的值,原来的值20 21 },22 immediate:true//immediate——初始化时,让handler调用一下 23})监视属性watch:
当被监视的属性变化时,回调函数自动调用,进行相关操作
监事的属性必须存在,才能进行监视
immediate——初始化时让handler调用一下
监视的两种写法
new Vue时传入watch配置
通过vm.$watch监视
深度监视
xxxxxxxxxx451
2<div id="app">3 <h2>4 {{person.a}}5 </h2>6 <button @click="a++">7 点击8 </button>9</div>10<script>11 const vm=new Vue({12 el:"#app",13 data:{14 person:{15 name:"李白",16 a:1,17 b:218 19 }20 },21 methods:{22 23 },24 computed:{25 26 },27 watch:{28 //监视多级结构中某个属性的变化29 'person.a':{30 handler(){31 console.log("监视a,a发生变化了")32 },33
34 },35 person:{36 //监视多级结构柱中所有属性的变化37 deep:true38 handler(){39 40 console.log("对象person里面的属性有发生改变")41 }42 }43 }44 })45</script>深度监视:
Vue中的watch默认不监视对象内部值得改变(一层)
配置deep:true可以检测内部值得变化(多层)
备注:
Vue自身可以监视对象内部的值得改变,但Vue提供的watch默认不可以
使用watch时根据数据的饿具体结构,决定是否采用深度监视
监视的简写
简写形式的前提是不需要deep和immediate配置项,也就是说,当你的监视属性里面只有handler时就可以开启简写
xxxxxxxxxx341<div id="app">2 <h2>3 {{person.a}}4 </h2>5 <button @click="a++">6 点击7 </button>8</div>9<script>10 const vm=new Vue({11 el:"#app",12 data:{13 isHot:"feel",14 person:{15 name:"李白",16 a:1,17 b:218 19 }20 },21 methods:{22 23 },24 computed:{25 26 },27 watch:{28 //简写形式——直接使用监视的data属性形式——函数名就是监视的属性名,其他用法和handler函数一致29 feel(n,o){30 console.log(n,o)31 }32 }33 })34</script>另一种写法:
xxxxxxxxxx351<div id="app">2 <h2>3 {{person.a}}4 </h2>5 <button @click="a++">6 点击7 </button>8</div>9<script>10 const vm=new Vue({11 el:"#app",12 data:{13 isHot:"feel",14 person:{15 name:"李白",16 a:1,17 b:218 19 }20 },21 methods:{22 23 },24 computed:{25 26 },27
28 })29 //这种写法也可以30 vm.$watch('isHot',function(newData,oldData){31 //这个函数跟之前的handler函数的内容是一致的32 console.log(newData,oldData)33 34 })35</script>绑定样式
绑定class样式
绑定class样式适用于样式的类名不确定,需要动态指定
xxxxxxxxxx241<style>2 .a{width:20px;background-color:red}3 .b{width:30px;background-color:blue}4 .c{width:50px;background-color:yellow}5</style>6<div id="#app">7 <!--给元素添加class样式,使用属性绑定的方法-->8 <div class="a" :class="style" @click="change">9 10 </div>11</div>12<script>13const vm=new Vue({14 el:"",15 data:{16 style:"c"17 },18 methods:{19 change(){20 this.style="b"21 }22 }23})24</script>还可以这样写
xxxxxxxxxx251<style>2 .a{width:20px;background-color:red}3 .b{width:30px;background-color:blue}4 .c{width:50px;background-color:yellow}5</style>6<div id="#app">7 <!--给元素添加class样式,使用属性绑定的方法,这样写的话可以将定义好的数组的值都做为,使用于要绑定的样式类名不确定,个数不确定-->8 <div class="a" :class="arr" @click="change">9 10 </div>11</div>12<script>13const vm=new Vue({14 el:"",15 data:{16 style:"c",17 arr:['a','b','c']18 },19 methods:{20 change(){21 this.style="b"22 }23 }24})25</script>绑定style样式
使用这样的写法,必须使用属性绑定style,且style里面的值是一个对象
xxxxxxxxxx161
2<div id="#app">3 <div :style="styleObj"> <!--<div :style="{fontSize:'40px'}">如果直接写表达式的话就这样写-->4 这就是街舞5 </div>6</div>7<script>8const vm=new Vue({9 el:"#app",10 data:{11 styleObj:{12 fontSize:"40px" //对应的style对象里面的可以是不能随便写的,必须是style里面的有的属性,然后使用小驼峰命名的方式作为对象的key13 }14 }15})16</script>
生命周期
生命周期
又名:生命周期的回调函数,生命周期函数,生命周期钩子
是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数
生命周期函数的名字是不可更改的,但函数的具体内容是程序员根据需求编写的
生命周期函数中的this指向vm或组件实例对象
mounted——是一个函数,与methods和data属于同一级别
Vue完成模板的解析并把初始的真实的DOM元素放入页面后(挂载完毕)调用mounted
xxxxxxxxxx161
2<script>3 new Vue({4 el:"",5 data:{},6 methods:{},7 //Vue完成模板的解析并把真实的DOM元素放入页面后调用mounted8 mounted(){9 //例如使用一个定时器10 setInterval(()=>{11 console.log("counted")12 })13 }14 })15
16</script>Vue组件化编程
Vue组件

组件的定义:实现应用中局部功能代码和资源的集合
非单文件组件
一个文件中包含有多个组件
vue组件的三大步骤
定义组件(创建组件)
注册组件
使用组件
如何定义组件
使用 Vue.extend({})创建,使用时注意,el配置项是不能写在里面的,data配置项要写成函数的形式,且数据写在return对象里面,组件被复用时数据存在引用关系,template配置定义组件的结构
xxxxxxxxxx141
2const student=Vue.extend({3 template:'<div>学生的名字:{{name}}<button @click="alert">点击显示名字</button></div>',4 data(){5 return {6 name:"张三"7 }8 },9 methods:{10 alert:function(){11 alert(this.name)12 }13 }14})如何注册组件(局部注册)
靠new Vue的时候传入components配置项
xxxxxxxxxx81
2new Vue({3 el:"#app",4 data:{},5 components:{6 student:student //分别为用来标识组件的变量和定义好的组件的名字7 }8})如何注册组件(全局注册)
使用Vue.component(a,b) a标识组件的变量名,b为定义好的组件名
xxxxxxxxxx31
2Vue.component('student',student)3
案例:
xxxxxxxxxx7712<html lang="en">3
4<head>5 <meta charset="UTF-8">6 <meta http-equiv="X-UA-Compatible" content="IE=edge">7 <meta name="viewport" content="width=device-width, initial-scale=1.0">8 <title>Document</title>9</head>10
11<body>12 <div id="a">13 <!-- 使用组件 -->14 <school></school>15 <hr>16 <student></student>17
18 </div>19 <!-- 使用组件 -->20 <hr>21 <div id="b">22 <hello></hello>23 </div>24</body>25<script src="../vue.js"></script>26<script>27 // 创建组件28 const school = Vue.extend({29 // 一定不要写el配置项,因为最终的组件都要被vm管理,由vm决定服务于哪个容器,data配置项要写成函数的样式30 // 在template配置项里面写组件的结构31 template:'<div><h2>学校:{{name}}</h2><div>',32 data() {33 return {34 name: "北京大学"35 }36 },37 })38 const student=Vue.extend({39 template:"<div>学生:{{name}}<button @click='alert'>点击</button></div>",40 data(){41 return{42 name:"张三"43 }44 },45 methods: {46 alert:function(){47 alert(this.name)48 }49 },50 })51 const hello=Vue.extend({52 template:'<div>你好{{name}}</div>',53 data() {54 return {55 name:"Tom"56 }57 },58 })59// 注册组件(局部注册)60 const vm = new Vue({61 el: "#a",62 // 使用components表示组件的意思用来注册组件的63 components: {64 school:school,65 student:student66 }67 })68// 注册组件(全局注册)69Vue.component('hello',hello)70
71 new Vue({72 el:"#b",73
74 })75</script>76
77</html>
组件的注意点
关于组件名:
一个单词组成:
第一种写法:首字母小写——school
第二种写法:首字母大写——School
多个单词组成
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool(需要Vue脚手架支持)
组件名尽量回避HTML中已有元素的名称,可以使用name配置项指定组件在开发工具中呈现的名字
xxxxxxxxxx151const student=Vue.extend({2name:"sb",//使用这个name配置项后,在开发者工具里面展示的都是这个名字,不受后续注册时取的名字的影响,但使用的时候,必须是注册那个时候定义的名字3template:'',4data(){5return {67}8}9})10new Vue({11el:"#a",12components:{13student:student14}15})
关于组件标签
第一种写法:
<school></school>第二种写法:
<school/>不用使用脚手架时,
<school/>会导致后续组件不能渲染
一个简写方式:
const school=Vue.extend(options) 可简写为 const school = options
xxxxxxxxxx1712const student={3template:'',4data(){5return {6name:"李白"7}8},9methods:{1011}12}13new Vue({14components:{15student:student16}17})
一个重要的内置关系
xxxxxxxxxx91//定义一个构造函数2function Demo(){3 this.a=14 this.b=15}6//创建一个Demo实例对象7const d=new Demo()8console.log(Demo.prototype) //显示原型属性9console.log(d.__proto__) //隐式原型属性显示原型属性和隐式原型属性都指向原型对象
单文件组件
一个文件中只包含有一个文件——a.vue
xxxxxxxxxx121<template>2<!-- 组件结构 -->3 <div id="app"></div>4</template>5
6<style scoped>7/* 样式 */8</style>9<script>10// 交互相关代码11
12</script>如果要想让别人使用你的组件,必须使用暴露,Vue提供了三种暴露的方式:
使用关键字export——分别暴露
xxxxxxxxxx121<template></template>2<script>3 export const school=Vue.extend({4 data(){5 6 },7 methods:{8 9 }10 })11</script>12<style></style>使用关键字export——统一暴露
xxxxxxxxxx131<template></template>2<script>3 const school=Vue.extend({4 data(){5 6 },7 methods:{8 9 }10 })11 export{school}12</script>13<style></style>使用关键字export——默认暴露
xxxxxxxxxx131<template></template>2<script>3 const school=Vue.extend({4 data(){5 6 },7 methods:{8 9 }10 })11 export default school12</script>13<style></style>一般来说,都是使用默认暴露,默认暴露往往是暴露一个,在调用的时候也比较简单
单文件组件的简写
xxxxxxxxxx281<template>2 <div class="demo">3 <h2>4 5 </h2>6 <button @click="alert">7 点击执行事件8 </button>9 </div>10</template>11<script>12 export default{ //这里使用默认暴露13 name:"School", //组件的名字,一般是和.vue文件名相同14 data(){15 schoolName:"北京大学"16 },17 methods:{18 alert:function(){19 alert("this is a big boy!")20 }21 }22 }23</script>24<style>25 .demo{26 background-color:"red"27 }28</style>App.vue
汇总所有的组件,在该组件里注册其他所有的组件
xxxxxxxxxx171<template>2
3</template>4<script>5 //引入组件6 import School from './School'7 8 export default {9 //注册组件10 components:{11 School12 }13 }14</script>15
16<style>17</style>main.js
调用App.vue,是入口文件
xxxxxxxxxx71import App from './App.vue'2new Vue({3 el:"#root", //容器在index.html里4 components:{5 App6 }7})index.html
是整个项目的唯一一个html文件
xxxxxxxxxx1812<html lang="en">3<head>4 <meta charset="UTF-8">5 <meta http-equiv="X-UA-Compatible" content="IE=edge">6 <meta name="viewport" content="width=device-width, initial-scale=1.0">7 <title>Document</title>8</head>9<body>10 <div id="root">11 <App></App>12 </div>13 <!--使用的JavaScript文件必须在容器后面-->14 <script src="./vue.js"></script>15 <script src="./main.js"></script>16</body>17
18</html>完成上述的操作后并不能运行index.html文件,因为浏览器并不认识mian.js里的代码,做的这些是为了了解脚手架开发
脚手架的使用
cli——command line interface (命令行接口工具)
Vue脚手架时Vue官方提供的标准化开发工具
最新的版本是4x
创建vue项目——create xxx(项目名)
选择vue版本
切换到项目目录 ——cd xxx(项目名)
运行项目——npm run serve
停止项目,在终端使用ctrl+c快捷键
vue脚手架隐藏了所有的webpack相关的配置,若想查看具体的webpack配置项,请执行——vue inspect > output.js
一个名为one的Vue项目结构

App.vue——所有vue组件都要在这里面进行注册和使用
components文件夹放置编写的组件
assets文件夹放置资源
整个vue项目只有一个html文件即index.html文件
main.js里的render配置项
如果项目中引入的vue是残缺版的vue,则使用render来解析
关于不同版本的vue
vue.js与vue.runtime.xxx.js的区别:
vue.js是完整版的Vue,包含:核心功能和模板解析器
vue.runtime.xxx.js是运行版的Vue,只包含:核心功能,没有模板解析器
因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到createElement函数去指定具体内容
ref属性的使用
在vue里是不推荐使用原生的JavaScript代码来进行dom操作的,若果需要要使用类似的dom操作,原生的JavaScript使用使用id或者class等来对元素进行绑定,在vue里使用ref属性进行标记,vue的vc会收集所有的ref标记的属性,要使用的时候可以直接使用
xxxxxxxxxx331<template>2<div>3 <div ref="a">4 5</div>6<div ref="b">7 8</div>9 <button @click="show">10 点击触发事件11 </button>12 </div>13</template>14<script>15 import School from './components/School'16 export default{17 name:"App",18 compoents:{19 School20 },21 data(){22 return {23 24 }25 },26 methods:{27 show() {28 console.log(this.$refs.a)29 }30 }31 }32
33</script>同时ref属性可以使用在组件上,获取到的是组件的实例对象,如果使用的id给组件进行绑定,使用原生的JavaScript获取id会得到组件的html结构
xxxxxxxxxx261<template>2<div>3 <h1>4 this is a boy5 </h1> 6 <School ref="sch"></School>7 <button @click="show">8 9 </button>10 </div>11</template>12<script>13 import School from './components/School'14 export default{15 data(){16 return {17 18 }19 },20 methods:{21 show(){22 console.log(this.$refs.shc)23 }24 }25 }26</script>ref属性被用来给元素或子组件注册引用信息(id的代替者)
应用在html标签上获取的真实的DOM元素,应用在组件上是组件的实例对象(vc)
props配置项
