目录
1、Vue介绍
1.1 Vue是什么?
构建用户界面的js库,数据驱动的渐进式框架,Vue.js通过简单的API响应数据绑定和组合的视图组件化开发,基于MVVM模式,快速创建用户界面
Vue作者前Google员工尤雨溪
1.2 Vue历史
2013发布草案版本
2015发布1.0版本
2016发布2.0版本
2020 3.0beta版本
1.3 Vue特性
轻量、数据绑定、指令、插件化、组件化
2、Vue项目环境搭建(掌握)
Vue是一个JavaScript框架
2.1 使用Vue官方脚手架(vue-cli)
vue-cli 是一个基于Vue.js进行快速开发的完整系统,是一个官方脚手架,可以帮我们快速创建Vue项目工程
2.2 vue-cli安装与使用步骤
(1)下载(命令行或者官方网站)
npm i yarn -g
(2)配置环境变量(使用命令行寻找位置)此电脑-属性-环境变量等
yarn global bin //查看yarn全局目录
(3)全局安装
yarn global add @vue/cli
(4)创建项目(或者命令行输入vue ui 图形化创建)
vue create 项目名
(5)进入项目目录,启动项目
yarn serve
如图项目创建成功
3、Vue组件化
3.1 组件特点
可重用、可组合、易维护
3.2 自定义组件创建以及使用
创建自定义组件Msg.vue
<template>
<div>
<p>留言区:</p>
<textarea name="" id="" cols="30" rows="10">
</textarea>
<button>点击</button>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
使用自定义组件Msg.vue
(1)引入自定义组件
(2)注册组件
(3)渲染自定义组件
3.3 数据驱动实现点击换名
<template>
<div >
<p>{{ name }}</p>
<!-- <button v-on="click:change"> 点我</button> -->
<button @click="change"> 点我</button>
<div v-show="show">用户名或密码错误</div>
<span>{{msg}}</span>
</div>
</template>
<script>
export default {
components:{
},
//数据驱动思想:把界面所有需要的变化的数据存放在data return 对象中,当要改变界面,只需要操作数据,当data数据发生变化时,视图会自动更新
//数据驱动核心 组件需要变化的动态数据 不关心节点 只关注数据
data(){
return {
name:"张三",
msg:"*****",
show:false
}
},
//函数存放的地方
methods:{
change:function(){
// console.log(123)
this.name="李四"
// this.show=true;
}
// change(){
// }
},
//注册自定义组件
components:{
}
}
</script>
<style>
</style>
4、Vue指令(掌握)
4.1 什么是指令
指令是一个带有v-前缀的特殊标签属性,指令属性的值预期是单个JavaScript表达式
4.2 常见的指令
指令: 用最少的代码最更多的事情
v-text: 改变元素内容, 等效于innerText
v-html:改变元素内容,解析标记! 等效于innerHTML
v-if: 对节点进行增加/删除(底层使用DOM节点操作,append remove)性能低
v-show: 对节点进行显示/隐藏(底层操作CSS的display属性) 性能高
v-on: 绑定事件,简写@ 例: @click='函数名'
v-bind: 绑定动态属性,简写: 例如:属性名='data中的值'
v-for: 循环快速创造节点,要循环哪个元素,就加在哪个元素上
<tr v-for="(item,index) in 数组" :key="index">
<td>{{ item.xxx 取值 }}</td>
</tr>
v-model(常用作value值获取):
可以绑定表单元素的value值(和动态数据绑定在一起)
是唯一一个双向绑定的指令
当value值发生变化, 指令就会改变对应的动态数据
当动态数据发生变化, 指令会改对应的value值
4.3 指令使用(Vcode.vue)
<template>
<div>
<!-- 可以解析标签 -innerHTML-->
<p v-html="txt"></p>
<!-- 操控元素内容 -innerText -->
<p v-html="txt1"></p>
<!-- 操控节点元素 对元素进行删除和新增 性能低 -->
<h1 v-if="show">v-if</h1>
<!-- 操控元素的display属性 -->
<h1 v-show="show">v-show</h1>
<table border="1px">
<tbody>
<tr v-for="(item,index) in emps" :key="index" >
<td>{{ item.uid }}</td>
<td>{{ item.name }}</td>
<td>{{ item.sex }}</td>
<td>{{ item.depar }}</td>
</tr>
</tbody>
</table>
<!-- v-bind 绑定动态属性 相当于: 可以获取循环或者data里面的动态数据-->
<!-- v-on 简称@ 绑定事件 -->
<p :title="t" @click="clickFuc">123</p>
<button @click="addEmp">新增员工</button>
<img @click="clickImg" :src="imgsrc" >
</div>
</template>
<script>
export default {
data(){
return{
txt:"我是测试",
show:false,
emps:[{id:0,uid:10008,name:'张三',sex:'女',depar:'h5'},
{id:1,uid:10001,name:'张三',sex:'男',depar:'ui'},
{id:2,uid:10002,name:'张三',sex:'女',depar:'h5'},
{id:3,uid:10003,name:'张三',sex:'男',depar:'ui'},
{id:4,uid:10004,name:'张三',sex:'女',depar:'java'}],
t:'今天也是元气满满的一天',
imgsrc:"https://tse2-mm.cn.bing.net/th/id/OIP-C.tkjADgN8qLMcI8hQZA1cbwAAAA?pid=ImgDet&rs=1",
}
},
methods:{
clickFuc(){
this.t='加油'
},
addEmp(){
this.emps.push({
id:9,
uid:100010,
name:'lisa',
sex:'女',
depar:'test'
})
},
clickImg(){
this.imgsrc='https://tse1-mm.cn.bing.net/th/id/R-C.ad38092869fefbfc3ff01d45020d5e03?rik=UxTBU07d%2fNnMIw&riu=http%3a%2f%2fimg.ewebweb.com%2fuploads%2f20191010%2f16%2f1570696957-hLziPTUtod.jpg&ehk=TICEDx%2f0FGmfADQE9NTZJ99Je%2blAKc2Z99TIqqI0UrY%3d&risl=&pid=ImgRaw&r=0'
}
}
}
</script>
<style>
</style>
4.4 指令相关的小案例一(日夜切换以及消息发送)
<template>
<div :class="cls">
<button @click="clickExchange" >日间/夜间</button>
<div>
消息消息消息消息
</div>
<!-- v-model="val"只能作用于表单元素 input select等 因为这些元素都有value属性 -->
<input type="text" v-model="val">
<button @click="clickSend">点我发送</button>
<p>{{val}}</p>
<br>
<p v-for="(item,index) in list" :key="index">{{ item.msg }}</p>
</div>
</template>
<script>
export default {
data(){
return {
cls:'light',
list:[],
val:''
}
},
methods:{
clickExchange(){
this.cls=(this.cls=='light'? 'dark':'light')
},
clickSend(){
// this.list.push({id:this.list.length,msg:"今天下大暴雨11"})
let date=new Date()
let msg=date.getHours()+":"+date.getMinutes()+":"
+date.getSeconds()+" "+this.val;
this.list.push({id:this.list.length,msg:msg})
}
}
}
</script>
<style scoped>
.light{
color: aliceblue;
background: wheat;
}
.dark{
color: rgb(46, 14, 153);
background:rgb(24, 48, 48);
}
</style>
4.5 指令相关的小案例二(购物车)
<template>
<div>
<table>
<tbody>
<tr v-for="(item,index) in list" :key="index">
<td><img :src="item.pic"/></td>
<td>{{item.info}}</td>
<td>{{item.price}}</td>
<td ><button @click="clickNumJian(index)" :disabled="dis">-</button>
<span >{{item.num}}</span>
<button @click="clickNumAdd(index)">+</button>
</td>
<td>{{item.price*item.num}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data(){
return {
list:[
{id:0, pic:"https://img20.360buyimg.com/seckillcms/s280x280_jfs/t1/130667/9/26088/125267/6245451dE0f59f394/bfb4ad659904173b.jpg.webp",
info:"银色,1000W",price:600,num:9},
{id:1,pic:"https://img13.360buyimg.com/seckillcms/s280x280_jfs/t1/216263/25/16859/133769/624fd883Ed02a7b9c/a0cffc6062626823.jpg.webp"
,info:"银色,1000W",price:600,num:9},{id:2,pic:"https://img11.360buyimg.com/seckillcms/s260x260_jfs/t1/86498/22/25250/72901/62296e85E8694c5ef/639a079a5225a5d5.jpg.webp"
,info:"银色,1000W",price:600,num:6},{id:3,pic:"https://img13.360buyimg.com/seckillcms/s280x280_jfs/t1/218566/7/15728/63006/6242de26Ee4af62f4/941ed6b80c677ceb.jpg.webp"
,info:"银色,1000W",price:600,num:3},{id:4,pic:"https://img14.360buyimg.com/seckillcms/s144x144_jfs/t1/102546/36/26050/201907/62490554E3f38be5e/c3790bc769f8ef61.jpg!q70.jpg.webp"
,info:"银色,1000W",price:600,num:1}],
dis:false
}
},
methods:{
clickNumJian(index){
this.list[index].num>1? this.list[index].num--:1
if( this.list[index].num==1){
this.dis='true'
}
} ,
clickNumAdd(index){
this.list[index].num++
}
}
}
</script>
<style lang="scss" scoped>
</style>
4.6 class和style特殊属性可以使用对象写法
<template>
<div :class="cls">
v-bind的特殊用法
<button :title="title" @click="clickChange">点我点我</button>
<div :style="divsty">
我是文字
</div>
</div>
</template>
<script>
export default {
data(){
return{
title:'动态提示',
divsty:{
color:"red",
fontSize:'26px',
},
// cls:"cls1 cls2"
cls:{
cls1:true,
cls2:true
}
}
},
methods:{
clickChange(){
// this.title='123'
// this.divsty.color='yellow'
this.cls.cls1=false;
}
}
}
</script>
<style scoped>
.cls1{
background: darkviolet;
}
.cls2{
color: aqua
}
</style>
4.7 scoped属性(使得样式不会被覆盖)
4.8 computed计算属性
计算属性运行一次后,会缓存运行结果,只要其中的依赖数据没有发生变化,第二次直接读取
不会重复运算
用法:属性,所以调用无需加圆括号 {{计算属性的名字}} this.计算属性mingzi
4.9 面试题(computed和methods的区别)
(1)性能差别,computed会缓存结果,多次调用不会重复执行,性能高
(2)返回值,computed必须有返回值,methods可以没有
(3)传参,computed无法传参,methods可以传参
4.10 选项卡N选一思路以及案例
(1)data中建立对应的动态数据
(2)在选项卡点击时,把当前的selectIndex改成点击的索引
(3)在对应的选项卡中使用动态的class判断是否选中自己
5、 前端路由Vue-router(核心插件)
5.1 什么是前端路由?
前端路由定义了地址和组件一一对应的关系(一个URL地址,对应一个页面级别的组件)
Vue-router是Vue官方的一个插件,可以按需安装。便于构建单页面应用
SPA(单页应用)主页面只有一个,切换时只进行部分容器的切换
多页面应用(PC端) 主体页面有N个
vue全家桶vue+vuerouter+vuex
作用:实现应用完整/局部组件切换
5.2 安装
1,手动安装 yarn add vue-router -S
2,脚手架安装
5.3 配置
1,创建router.js文件,引入路由插件,使用VueRouter
2,创建路由对象并且暴露此路由对象(第一个path为'/')
5.4 使用
在main.js文件中,将router对象引入并注入vue实例中
在要显示切屏的页面,放置出口
router版的a标签
6、 生命周期(掌握)
6.1 什么是生命周期
表示组件从创建到销毁的完整过程
vue生命周期图
1、new Vue()开始创建项目
2、初始化vue内部事件,开启生命周期 beforeCreate
3、初始化组件所有动态数据(data,methods,computed等相关属性)
created:通知函数,组件数据初始化完成 可以发送初始化ajax
4、询问目标DOM容器是否准备完毕 $mount('#app')
yes下一步 no等待目标容器加载完成
5、询问是否有template标签
beforeMount 通知函数,组件即将开始转译并渲染
6、逐行转译将他转换为HTML片段,将HTML代码片段放入DOM容器
mounted 通知函数,组件已经转译并渲染完成,用户可以看到界面
7、数据发生变化时,进入更新阶段
beforeUpdate:数据发生变化,准备更新
8、转译,进行最小粒度渲染(vue会对比,进行变化部分的更新,提升性能)
updated:通知函数,界面更新完毕
9、组件不需要进入销毁阶段
beforeDestroy:通知,组件即将回收
10、vue开始组件资源回收,清空事件
destroyed:通知,组件已经被销毁
6.2 四大阶段(参照上图)
create阶段、mount阶段(增加)、update阶段、destroy阶段
create阶段:初始化组件内部数据
mount阶段:template转译及渲染
update阶段:组件的更新最小粒度渲染
destroy阶段:组件的销毁、回收释放内存
7、 组件通信(掌握)
7.1 基本语法(父传子)
自定义属性不能绑定点击事件
父传子
(1)在父元素中定义要传递给子元素的值
父元素
data(){
return{
arr:[1,2,3],
str:'hello'
}
}
(2)把要传递的值使用自定义属性的方式绑定到子元素中
<Son test="test111" xxx="aaa" :arr='arr' :str='str' />
(3)在子元素中,使用props获取自定义属性
子元素
// 可以获取自己身上的所有属性
props:["test","xxx","arr",'str']
(4)如何使用props中接到的值
{{name}} this.name
注意:props的名字和data或methods中的不能重名!!!
7.2 基本语法(子传父)
(1)在父元素中自定义一个函数(用来接收参数)
(2)绑定自定义事件 在子元素,把此函数传递过去
(3)在子元素需要的地方,使用$emit触发一次自定义事件,执行对应函数并传参