vue2笔记完整版
VUE闲来无事
VUE闲来无事一、vue核心的相关学习一,搭建vue开发环境1.下载vue.js2.下载扩展工具二,hello world案例三,helloworld项目扩展四,模板语法五,数据绑定六,el和data的两种写法发七,理解MVVM模型八,数据代理1.Object.defineProperty2.什么是数据代理3.vue中的数据代理九,事件处理1.事件处理的基本使用2.事件修饰符3.键盘事件4.事件总结十,计算属性1.姓名案例2.计算属性的简写3.天气案例 监视属性-watch4.深度监视5.监视属性简写十一,class和style绑定十二,条件渲染十三,列表渲染1,基本列表2.列表过滤3.列表排序4.数据更新时的问题5.vue数据检测的原理6.set()方法7.总结十四,表单渲染十五,内置指令1.v-text2.v-html3.v-cloak4.v-once5.v-pre十六,自定义属性十七,生命周期一,mounted二,创建三,挂载四,更新五,销毁六,不常用的钩子二,vue组件的理解,开始组件化编程一,对组件的理解二,非单文件组件一,基本构成二,注意事项三,组件的嵌套四,VueComponent五,组件和实例的内置关系三,单文件组件三,vue脚手架的相关知识一,创建脚手架二,分析脚手架结构三,render函数四,修改默认配置五,refs属性六,props配置七,mixin混入八,ToDoList案例1.组件化编码流程(通用)2.代码部分3.总结部分九,组件自定义事件1.绑定2.解绑3.总结十,全局事件总线十一,$nextTick十二,过渡与动画1,动画配置2,过度效果3,多个元素过度4,集成第三方库十三,插件四,vue中的AJAX1.配置代理2.github请求案例3,插槽1.默认插槽2.具名插槽3.作用域插槽4.总结五,vuex1,vuex简介2,求和案例3,vuex的工作原理4,搭建vuex的环境5,vuex开发者工具6,getters配置对象7,mapState和mapGetters八,mapActions和mapMutations九,多组件共享数据十,vuex模块化十一,vuex模块化二六,路由一,什么是路由二,路由技术的基本使用三,路由使用的注意事项四,路由的嵌套五,路由的query参数六,命名路由七,路由的param参数八,router-link的replace属性九,编程式路由导航十,缓存路由组件十一,两个新的生命周期函数十二,路由守卫七,Vue UI组件库
一、vue核心的相关学习
本人想先看vue3的但是奈何没文化看不懂,环境也不会装,直接就寄了,只能从头看。
一,搭建vue开发环境
1.下载vue.js
http://v2.cn.vuejs.org/v2/guide/installation.html
2.下载扩展工具
我见过最**的事情了,先是下载很难,最后借的网盘下载完成后,谷歌自己引入后不能用,只能用联想浏览器,真的醉了。
二,hello world案例
<!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">
<script type="text/javascript" src="../vue.baise/vue.js"></script>
<title>Document</title>
</head>
<body>
<!-- 一个容器 -->
<div id="root">
<h1>Hello World! 我是{{name}}</h1>
<h1>我的年龄时21</h1>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
//创建实例
new Vue({
el:'#root' , // el用于指定当前实例服务于那个容器,值通常为css选择器
data:{//data用于存储数据,数据共el指向对象使用,值暂时先写成一个对象
name:'王鼎舒'
}
})
</script>
</body>
</html>
1.想让vue工作,就必须创建一个vue实例,且要传入一个配置对象
2.root容器里的代码依然符合html规范,只不过混入了一些特殊的vue语法
3.root容器的代码被称为【vue模板】
三,helloworld项目扩展
1.vue容器和实例一一对应
2.真实开发中只有一个vue实例,配合着一些组件一起使用
3.{{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的属性
4.一旦data中的数据发生改变,那么页面中用到数据的地方也会发生改变。
四,模板语法
<!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">
<script type="text/javascript" src="../vue.baise/vue.js"></script>
<title>Document</title>
</head>
<body>
<!--
-->
<div id="root">
<h1>插值语法</h1>
<h3>你好,{{name}}</h3>
<hr>
<h1>语法指令</h1>
<a v-bind:href="url">点击跳转到学习网站1</a>
<a :href="url">点击跳转到学习网站2</a>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue(
{
el:"#root",
data:{
name:"wds",
url:"https://www.huya.com/"
}
}
)
</script>
</body>
</html>
vue模板语法有两大类:
1.插值语法:
功能:用于解析标签体内容
写法:{{xxx}},xxx是js表达式且可以直接读取到data中的属 性
2.指令语法:
功能:用于解析标签(包括:标签属性,标签体内容,绑定事件.....)
举例”v-bind:“简写为“:”且可以直接读取data中的所有属性
备注:vue有很多的指令,且形式都是v-????,此处我们只是用v-bind举个例子。
五,数据绑定
<!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">
<script type="text/javascript" src="../vue.baise/vue.js"></script>
<title>数据绑定</title>
</head>
<body>
<div id="root">
单项数据绑定:<input type="text" v-bind:value="name"><br>
双向数据绑定:<input type="text" v-model:value="name"><br>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue(
{
el:'#root',
data:{
name:'我讨厌学习'
}
}
)
</script>
</body>
</html>
vue中有两种数据绑定方式:
1.单向绑定:(v-bind),数据只能从data导向页面
2.双向绑定:(v-model),数据不仅能从data流向页面,还可以从页面流向data
备注;
1.双向绑定一般都应用在表单类元素上(如input select等)
2.v-model:value简写为v-model,其默认收集的就是value
六,el和data的两种写法发
<!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">
<script type="text/javascript" src="../vue.baise/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="root">
<h1>Hello World! 我是{{name}}</h1>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
var a = new Vue({
//第一种写法
// el:'#root' ,
//对象式:data的第一种写法
// data:{
// name:'王鼎舒'
// }
data:function () {
return {
name:'王鼎舒 '
}
}
})
setTimeout(()=>{
//第二种写法
a.$mount('#root')
},1000)
</script>
</body>
</html>
el的两种写法:
1.new Vue的时候配置el的属性
2.先创建Vue的实例,随后再通过vm.¥mount(‘#root’)指定el的值
data的两种写法
1.对象式
2.函数式
选择:目前两种写法都可以,学习组件后,data必须是函数式,否则出错
一个重要的原则:
由Vue管理的函数一定不能写箭头函数
七,理解MVVM模型
v 视图 view 对应data中的数据
m 模型 model 模板
vm 视图模型 vue实例对象
八,数据代理
1.Object.defineProperty
备注:我也不知道学这个是干啥
<!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">
<script type="text/javascript" src="../vue.baise/vue.js"></script>
<title>Document</title>
</head>
<body>
<script type="text/javascript">
Vue.config.productionTip = false
let number = 18
let person = {
name:"王鼎舒",
age:"21"
}
Object.defineProperty(person,'sex',{
// value:'man',
// enumberable:true,//控制属性是否可以枚举,默认值是false
// writeable:true,//控制属性是否可以被修改,默认值是false
// configurable:true//控制属性是否可以被删除,默认值是false
//当有人调用person的age属性时,get函数就会被调用,且返回值就是get的值
get:function(){
return 'hello'
}
})
// console.log(Object.keys(person))
console.log(person)
</script>
</body>
</html>xxxxxxxxxx
2.什么是数据代理
通过一个对象代理另一个对象中属性的操作(读/写)
3.vue中的数据代理
九,事件处理
1.事件处理的基本使用
<div id="root">
<h2>{{name}}讨厌学习</h2>
<!-- <button v-on:click="shouInfo">点击产生提示</button> -->
<button @click="shouInfo">点击产生提示</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el:"#root",
data:{
name:"王鼎舒"
},
methods:{
shouInfo(event){
//event.target 发生事件的事件目标
// console.log(event.target)
//这里的this指向vm对象
// console.log(this)
alert("绝了")
}
}
})
</script>
2.事件修饰符
vue中的事件修饰符:
1.prevent:默认阻止事件(常用)
2.stop:默认事件冒泡(常用)
3.once:事件只触发一次(常用)
4.capture:使用事件捕获模式
5.self:只有event,target是当前操作的元素时才触发
6.passive:事件只有默认行为执行,无需等待回调执行完毕。
3.键盘事件
1.vue中常用的按键别名:
-
回车 enter
-
删除 delete
-
退出 esc
-
空格 space
-
换行 tab
-
上 up 下 down 左 left 右 right
4.事件总结
修饰符是能连着写的 例如:@click.stop.prevent=“abc”
键盘事件 例如:@keyup.ctrl.y
十,计算属性
1.姓名案例
method方法
<div id="root">
姓:<input type="text" v-model="firstName"><br><br>
名:<input type="text" v-model="lastName"><br><br>
姓名:<span>{{fullName()}}</span>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
firstName:'张',
lastName:'三'
},
methods:{
fullName(){
return this.firstName + '-' + this.lastName
}
}
})
</script>
</body>
<div id="root">
姓:<input type="text" v-model="firstName"><br><br>
名:<input type="text" v-model="lastName"><br><br>
姓名:<span>{{firstName.slice(0,3)}}-{{lastName }}</span>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
firstName:'张',
lastName:'三'
}
})
</script>
这两种方法效率不高
计算属性方法
<!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">
<script type="text/javascript" src="../vue.baise/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="root">
姓:<input type="text" v-model="firstName"><br><br>
名:<input type="text" v-model="lastName"><br><br>
姓名:<span>{{fullName}}</span>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
const vm = new Vue({
el: "#root",
data: {
firstName: '张',
lastName: '三'
},
computed:{
fullName:{
//get当有人读取fullname时,get就会被调用,且返回值就作为fullName的值
//get的调用1.初次调用get时 2.所依赖的属性发生改变
get(){
return this.firstName+'-'+this.lastName
},
set(value){
const arr = value.split("-")
this.firstName = arr[0]
this.lastName = arr[1]
}
}
}
}
)
</script>
</body>
</html>
计算属性:
-
定义:要用的属性不存在,要通过已有属性计算
-
原理:底层借助了之前的Object.defineproperty方法提供getter和setter方法
-
优势:与methods方法相比,内部有缓存机制
-
备注:1.计算的属性最终会出现在vm上,可以直接读取
2.如果计算属性要被修改,那就必须要写set函数上去修改
2.计算属性的简写
只考虑读取不考虑修改的时候才能够使用简写形式
3.天气案例 监视属性-watch
<div id="root">
<h2>今天天气很{{nice}}</h2>
<button @click="showInfo">切换天气</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
ishot:true
},
computed:{
nice(){
return this.ishot? "炎热" : "凉爽"
}
},
methods: {
showInfo(){
this.ishot = !this.ishot
}
},
// watch:{
// ishot:{
// immediate:true,//初始化handler时调用一下
// //handler什么时候被调用?当ishot发生改变
// handler(newvalue,oldvalue){
// console.log("天气发生变化",newvalue,oldvalue)
// }
// }
// }
})
vm.$watch('ishot',{immediate:true,
handler(newvalue,oldvalue){
console.log("天气发生变化",newvalue,oldvalue)
}
})
</script>
监视属性watch:
-
当被监视额属性变化时,回调函数自动调用,进行相关操作
-
监视属性必须存在,才能监视
-
监视属性的两种写法
1.new vue时传入watch配置
2.通过vm.$watch监视
4.深度监视
<div id="root">
<h2>今天天气很{{nice}}</h2>
<button @click="showInfo">切换天气</button>
<hr>
<h3>a的值是{{numbers.a}}</h3>
<button @click="numbers.a++">点击让a+1</button>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
ishot:true,
numbers:{
a:1,
b:2
}
},
computed:{
nice(){
return this.ishot? "炎热" : "凉爽"
}
},
methods: {
showInfo(){
this.ishot = !this.ishot
}
},
watch:{
//深度监视
numbers:{
deep:true,
handler(){
console.log("a发生改变")
}
},
//监视多级属性中某一属性的变化
'numbers.a':{
handler(){
console.log("a发生改变")
}
}
}
})
</script>
</body>
深度监视:
vue中的watch默认不监视对象内部的值的变化(一层)
配置deep:true可以检测对象 内部值的改变(多层)
备注:
vue自身可以检测对象内部值的改变,但是watch默认不可以
使用watch时根据数据具体结构,决定是否采用深度监视
5.监视属性简写
配置项里之后handler时可以简写
十一,class和style绑定
绑定class样式
1.字符串写法
2.数组写法
3.对象写法
<!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">
<script type="text/javascript" src="../vue.baise/vue.js"></script>
<title>Document</title>
<style>
* {
margin: 0px;
padding: 0px;
}
html,
body {
height: 100%;
}
.basic {
width: 200px;
height: 150px;
border: 2px solid black;
}
.normal {
}
.happy {
}
.sad {
}
</style>
</head>
<body>
<div id="root">
<div class="basic" :class="a" @click="changemod">这是一个div</div><br><br>
<div class="basic" :class="classArr" @click="changemod">这是一个div</div><br><br>
<div class="basic" :class="classobj" @click="changemod">这是一个div</div>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
a:"normal",
classArr:['happy','sad','normal'],
classobj:{
happy:false,
sad:false,
normal:true
}
},
methods: {
changemod(){
const arr = ["happy" , "normal" , "sad"]
const index = Math.floor( Math.random()*3)
this.a = arr[index]
}
},
})
</script>
</body>
</html>
style样式绑定一般不使用
十二,条件渲染
v-if:写法
1.v-if=”表达式”
2.v-else=“表达式”
3.v-else-if=“表达式”
适用于切换频率较低的场景,其中不展示dom的元素直接被移出(display:none),三个表达式可以一起使用,但是结构体不能被打断。
v-show:写法
1.v-shou=“表达式”
适用于切换频率较高的场景
不展示的dom不会被移出只是会被隐藏起来。
十三,列表渲染
1,基本列表
<!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">
<script type="text/javascript" src="../vue.baise/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="root">
<h1>{{name}}讨厌学习</h1>
<button @click="add">点击添加刘鹏的数据</button>
<ul>
<li v-for="p,index in persons" :key="p.id">{{p.name}}-{{p.age}}<input type="text"></li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:"#root",
data:{
name:"王鼎舒",
persons:[
{id:001,name:"wds",age:18,sex:"man"},
{id:002,name:"lkc",age:81,sex:"man"},
{id:003,name:"lt",age:8,sex:"man"}
]
},
methods: {
add(){
const p = {id:'004',name:"lp",age:'100+',sex:'woman'}
this.persons.unshift(p)
}
},
})
</script>
</body>
</html>
面试题:react、vue中的key有什么作用?(key的内部原理)
虚拟DOM中key的作用:key是虚拟DOM中对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
对比规则:
旧虚拟DOM中找到了与新虚拟DOM相同的key:
若虚拟DOM中内容没变, 直接使用之前的真实DOM若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM旧虚拟DOM中未找到与新虚拟DOM相同的key:创建新的真实DOM,随后渲染到到页面
用index作为key可能会引发的问题:
若对数据进行逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低若结构中还包含输入类的DOM:会产生错误DOM更新 ==> 界面有问题开发中如何选择key?
最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表,使用index作为key是没有问题的————————————————版权声明:本文为CSDN博主「梦入_凡尘」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_55593227/article/details/119717498
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">
<script type="text/javascript" src="../vue.baise/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="root">
<h1>人员列表</h1>
<hr>
<input type="text" placeholder="请输入姓名" v-model="keyword">
<li v-for="(p,index) in filpersons" :key="p.id">{{p.name}}-{{p.age}}</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: "#root",
data: {
name: "王鼎舒",
keyword: '',
persons: [
{ id: 001, name: "wds", age: 18, sex: "男" },
{ id: 002, name: "lkc", age: 81, sex: "男" },
{ id: 003, name: "lt", age: 8, sex: "男" },
{ id: 004, name: "nm", age: 18, sex: "男" },
{ id: 005, name: "dly", age: 81, sex: "男" },
{ id: 006, name: "adsaddasd", age: 8, sex: "男" }
],
filpersons: []
},
watch: {
keyword: {
immediate: true,
handler(value){
this.filpersons = this.persons.filter((p) => {
return p.name.indexOf(value) !== -1
})
}
}
}
})
</script>
</body>
</html>
3.列表排序
出了问题
<!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">
<script type="text/javascript" src="../vue.baise/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="root">
<h1>人员列表</h1>
<hr>
<input type="text" placeholder="请输入姓名" v-model="keyword">
<button @click="sortType=2">升序排序</button>
<button @click="sortType=1">降序排序</button>
<button @click="sortType=0">原顺序</button>
<li v-for="(p,index) in filpersons" :key="p.id">{{p.name}}-{{p.age}}</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el: "#root",
data: {
name: "王鼎舒",
keyword: '',
sortType: 0 ,
persons: [
{ id: 001, name: "wds", age: 18, sex: "男" },
{ id: 002, name: "lkc", age: 81, sex: "男" },
{ id: 003, name: "lt", age: 8, sex: "男" },
{ id: 004, name: "nm", age: 28, sex: "男" },
{ id: 005, name: "dly", age: 831, sex: "男" },
{ id: 006, name: "adsaddasd", age: 44, sex: "男" }
],
},
computed:{
filpersons(){
return this.persons.filter((p)=>{
return p.name.indexOf(this.keyword) !== -1
})
if(this.sortType){
arr.sort((p1,p2)=>{
return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age
})
}
return arr
}
}
})
</script>
</body>
</html>
4.数据更新时的问题
5.vue数据检测的原理
通过data数据,利用vm代理data中的数据
Vue监视数据的原理:
vue会监视data中所有层次的数据
如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据
对象中后追加的属性,Vue默认不做响应式处理如需给后添加的属性做响应式,请使用如下API:Vue.set(target,propertyName/index,value)vm.$set(target,propertyName/index,value)如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
调用原生对应的方法对数组进行更新重新解析模板,进而更新页面在Vue修改数组中的某个元素一定要用如下方法:
使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()Vue.set() 或 vm.$set()特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象(data等) 添加属性————————————————版权声明:本文为CSDN博主「梦入_凡尘」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_55593227/article/details/119717498