vue3学习笔记

Vue学习

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

添加开发Vue谷歌开发工具

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lBlrFOl8-1659270417035)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220717105451048.png)]

这里修改成false就不会提示出来上面的那个提示

才开始遇到错误了是因为多谢了一个的标签导致的错误

ico是Icon file的缩写,是Windows的图标文件格式的一种,可以存储单个图案、多尺寸、多色板的图标文件。 图标是具有明确指代含义的计算机图形。其中桌面图标是软件标识,界面中的图标是功能标识。  图标有一套标准的大小和属性格式,且通常是小尺寸的。每个图标都含有多张相同显示内容的图片,每一张图片具有不同的尺寸和发色数。一个图标就是一套相似的图片,每一张图片有不同的格式。从这一点上说图标是三维的。图标还有另一个特性:它含有透明区域,在透明区域内可以透出图标下的桌面背景。在结构上图标其实和麦当劳的巨无霸汉堡差不多。一个图标实际上是多张不同格式的图片的集合体,并且还包含了一定的透明区域。因为计算机操作系统和显示设备的多样性,导致了图标的大小需要有多种格式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DOdNH9y0-1659270417036)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220717112231547.png)]
在这里插入图片描述

按住Shift再点击刷新是强制刷新,会再次发送请求。

初识Vue:

​ 1.想让Vue工作,就必须创建一个Vue实例,并且传入配置对象

​ 2.root容器里面的代码仍然符合html规范,只不过混入了一些Vue的语法

​ 3.root容器里面的代码被称为Vue模板

容器和实例是一对一的关系,要不会出现问题

<!DOCTYPE html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
        <div id="root">
            <h1>hello,{{name}}</h1>
        </div>
		<script type="text/javascript">
            Vue.config.productionTip=false
            new Vue({
                el:'#root', //el用于当前的Vue为哪个实际例子进行服务,数值通常为css选择器
                data:{ //data中用于存储数据,数据供el所指定的容器去使用,暂时先写成一个对象
                    // :如果存在 render 函数或 template 属性,则挂载元素会被 Vue 生成的 DOM 替换;否则,挂载元素所在的 HTML 会被提取出来用作模版
                    name:'尚硅谷'
                }
            })
            </script>
        

	</body>
</html>

js表达式和js的语法是两种不同的

js表达式是可以传递数值的,而js的语法主要的还是js的if 或者 v-bind 的这些东西

v-bind总结一下就是使用这个api可以将后面的引号里面的参数换成Vue里面的参数

v-bind:可以简写成:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZZi2xyUg-1659270417037)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220717185107068.png)]

插值语法一般用在标签体当中,而指令语法可以用于解析标签

1插值语法:

​ 功能:用于解析标签体的功能。

​ 写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性

2 指令语法

​ 功能:用于解析标签(包括:标签属性,标签体内容,绑定事件…)

​ 备注:Vue当中有很多的指令,形式都是v-???

有冒号就会当成js代码去执行 可以对象里面去套对象 然后起相同的名字

JSON 与 JS 对象的格式一样,但是 JSON 的字符串中属性名必须加双引号。

v-model是可以进行双向绑定的,但是一般只能够用在表单元素(输入类元素上)

input 多选框 单选框 select这些都是的

绑定是分为两种的:

1.单向绑定(v-bind):数据只能从data流向页面

2.双向绑定(v-model):数据不仅可以从data流向页面还可以从页面流向data

v-model:value可以简写成:v-model因为v-model进行收集的就是value的数值

<!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">
    <title>Document</title>
    <script src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        {{name}}<br>
        <input type="text" :value="name">
        <input type="text" v-model:value="name">
    </div>
    <script type="text/javascript">
        new Vue(
            {
                el:"#root",
                data:{
                    name:"wsy"
                }
            }
        )
    </script>
</body>
</html>

v.&mount()挂载的意思是el的另一种写法,相对el这个参数来说要更加灵活一些

data也是有两种的一种是函数式的,一种式函数式的并且 data函数不能写成箭头式的=>会出现问题 这里面的this对象就成了window这个对象 而不是vue这个对象 并且data里面必须有return的返回数值

<!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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">{{name}}</div>
    <script>
        const v = new Vue({
            // data:{
            //     name:"wsy"
            // }
            data(){
                    return {
                        name:"wsy"
                    }
                }
        })
        // 原来是在对象里面就得去写好 el的,但是也可以通过下面的参数来进行绑定,这样更灵活一些
        v.$mount("#root")
    </script>
</body>
</html>

总结:data和el都含有两种写法:

​ 1.el有两种写法

​ (1):new Vue的时候配置el属性

​ (2):先创建Vue实例,随后再通过v.$mount(“”)来指定el的数值 挂载

​ 2.data有两种写法

​ (1):对象式

​ (2):函数式

​ 3.一个重要的原则

​ 由Vue管理的函数,一定不要去写箭头函数,一旦写了箭头函数,this的实例就不是Vue实例了

MVVM模型

观察发现:1.data中的所有属性都出现在了vm上面

​ 2.vm身上的属性以及Vue原型上的所有属性,在Vue模板都是可以直接使用的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fdU9mNgW-1659270417038)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220717200538883.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v7XNmGcA-1659270417039)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220717200812950.png)]

vm上面有的东西,vm原型的东西都是可以直接用的

1.const let 是块级作用域var没有块级作用域,var只有函数和全局作用域
2.const let 不存在变量声明的提前,var有声明的提前,所以const和let在声明变量/常量 之前,是没办法获取到的,称为暂时性死区temporal dead zone
3.const let是ES6提出的,var是ES5
4.const 声明的是常量,常量不能被修改,let和var声明的是变量,可以被修改
5.const在声明时必须赋值,而let和var不需要
6.let 和const不能重复声明同一个值:如 let a=1 ; let a =2 这样是不被允许的,但var可以,最后一个var声明的值会覆盖之前的 如:var b =1 ;var b =2 console.log(b) 结果为2

Object.defineProperty里的setter和getter方法类似java里面的getter和setter

<!DOCTYPE html>
<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">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript">
        let number = 18;
        let person = {
            name:'zhangsan',
            sex:'nan'
        };
        Object.defineProperty(person,'age',{
            get(){
                console.log("有人读取属性了");
                return number;
            },
            set(value){
                console.log("有人设置属性了")
                number=value
            }
        }
)
    </script>
</body>
</html>

Vue当中的数据代理 将_data中的数据代理到了vm对象当中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jKhWjlzN-1659270417039)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220718092309901.png)]

Vue中的数据代理:

​ 通过vm对象来代理data对象当中的属性(读/写)

Vue中对象数据代理的好处:

​ 更加方便操作data当中的数据

基本原理:

通过Object.defineProperty()把data对象当中的所有属性添加到vm上面

为每一个添加到vm上面的属性,都去指定一个setter/getter

在setter/getter内部去操作(读/写)data当中的属性

Vue的数据代理:

事件的基本使用:

​ 1.使用v-on:xxxx或者@xxxx来绑定事件,其中xxxx是事件名;

​ 2.事件的回调需要在methods对象中进行配置,最终都会在vm上面

​ 3.methods中配置的函数,不要用箭头函数,否则this就不是vm了

​ 4.methods配置的函数都是被Vue管理的函数,this的指向都会到vm上或者是组件实例对象上面

​ 5.@click="demo"和@click=“demo($event)” 效果是一致的,但是后者更灵活一些

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h1>{{name}}</h1>
        <button @click="showInfo(66)">点击进行提示信息</button>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                name:'wsy'
            },
            methods:{
                showInfo(number){
                    console.log(number)

                }
            }
        })
    </script>
</body>
</html>

Vue的事件修饰符@click或者其他的默认事件添加修饰:

(这些事件是可以去叠加使用的比如 @click.prevent.stop)

​ 1.prevent:阻止默认事件(常用)

​ 2.stop:阻止事件冒泡(常用)

​ 3.once事件只触发一次(常用)

​ 4.capture使用事件的捕获模式

​ 5.self只有event.target是当前操作元素时才触发元素

​ 6.passive:事件默认事件要理解执行,无需等待事件回调执行完毕(就是不用先执行js代码回调函数,再去执行默认事件)

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <a href="jadsjsadlksa" @click.prevent="showInfo(321)">baidu</a>
        <div @click="alertInfo">
            <button @click.stop="alertInfo">点击按钮,不要冒泡</button>
        </div>
        <button @click.once="alertInfo">只是点击一次</button>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            methods:{
                showInfo(value){
                    console.log(value)
                },
                alertInfo(){
                    alert("nihaoya")
                }
            }
        })
    </script>
</body>
</html>

placeholder可以做text框的提示

键盘事件:keydown和keyup的区别是 down只要按下去不需要抬起来就是有效果的,但是up必须抬起来才会有效果

1.Vue当中常见的按键别名:

​ 回车 =>enter

​ 删除=>delete

​ 退出=>esc

​ 空格=>space

​ 上=>up

​ 下=>down

​ 左=>left

​ 右=>right

2.Vue未提供别的按键,可以使用原始的按键去绑定 但主要转换成kebab-case来命名 就比如 大小写的键(CAPSLOCK-> caps-lock)

3.系统修饰键(用法特殊):crtl、alt、shift、meta

​ (1)配合keyup使用:按下修饰键的同时,再按下其他的键,随后释放其他的键,事件才会被触发

​ (2)配合keydown去使用:正常触发事件

4.也可以通过keycode去指定具体的按键(不推荐)

5.自己重新去定义案件 Vue.config.keyCodes.自定义键名=键码(不推荐)

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <input type="text" placeholder="按下回车提示输入" @keydown.enter="showInfo">
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            methods:{
                showInfo(e){
                    console.log(e.target.value)
                }
            }
        })
        vm.$mount("#root")
    </script>
</body>
</html>

计算属性

要实现一个案例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H7yRx0o6-1659270417040)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220718160049289.png)]

1.利用插值法进行实现

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        姓:<input type="text" v-model='lastname'><br><br>
        名:<input type="text" v-model='firstname'><br><br>
        全名:<span>{{lastname}}----{{firstname}}</span>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                lastname:'张',
                firstname:'三'
            }
        })
    </script>
</body>
</html>

通过{{lastname.slice(0,3)}}这个参数可以截取前几位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4fmjO4ko-1659270417041)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220718160338440.png)]

但是随着需求越来越多,表达式里面的参数也会越来越多,这样代码风格是有问题的,虽然不报错

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZNdY3n3K-1659270417041)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220718160632628.png)]

2.通过methods方法来进行实现

绑定事件的时候,函数的小括号加不加都可以,但是在插值语法当中是必须要去加括号的,否则执行不了函数

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        姓:<input type="text" v-model='lastname'><br><br>
        名:<input type="text" v-model='firstname'><br><br>
        全名:<span>{{fullName()}}</span>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                lastname:'张',
                firstname:'三'
            },
            methods:{
                fullName(){
                    console.log("-------log")
                    return this.lastname +'-------------'+ this.firstname
                }
            }
        })
    </script>
</body>
</html>

3.计算属性的实现

计算属性:

​ 1.定义:要用的属性不存在,要通过已有的属性计算得到,不可以是随便的一个变量

​ 2.原理:底层借助了Object.defineproperty方法提供的getter和setter

​ 3.被调用的两个时机 1.初始创建fullName计算属性的时候2.所依赖的数据发生变化的时候

​ 4.优势:与methods实现相比较,内部含有缓存机制(可以复用),效率更高,测试方便

​ 5.备注:

​ 1计算属性最终都会出现在vm上面,直接读取即可 2.如果计算属性要修改的,那必须写set去响应修改,并且要去修改依赖的数据

计算属性就是拿着已经写好的属性进行参数传递来实现新的属性

computed:里面来写新的对象 来承接get和set方法

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        姓:<input type="text" v-model='lastname'><br><br>
        名:<input type="text" v-model='firstname'><br><br>
        全名:<span>{{fullName}}</span>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                lastname:'张',
                firstname:'三'
            },
            computed:{
                // 这里的fullName不是对象,而是属性 所以没有办法去调用get方法
                fullName:{
                    // 当有人读取fullName的时候,get就会被调用,且返回值作为fullName的数值
                    // 被调用的两个时机 1.初始创建fullName计算属性的时候2.所依赖的数据发生变化的时候
                    // 如果含有多行都需要这个属性的时候只有第一次是调用get方法来获取数值的,之后都是不再调用的,走的是缓存
                    get(){
                        return this.lastname+'-'+this.firstname
                    },
                    // 当fullName被调用的时候,set就会被调用
                    set(value){
                        const arr = value.split('-')
                        this.lastname = arr[0]
                        this.firstname = arr[1]

                    }
                }
            }
        })
    </script>
</body>
</html>

一般来说计算属性只要有get就可以,当页面只含有get的时候,就可以利用简写的写法,跟着method的写法非常相似

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        姓:<input type="text" v-model='lastname'><br><br>
        名:<input type="text" v-model='firstname'><br><br>
        全名:<span>{{fullName}}</span>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                lastname:'张',
                firstname:'三'
            },
            computed:{
                // 当只含有get方法的时候,可以进行简写
                fullName(){
                    console.log("你好啊")
                    return this.lastname+'-'+this.firstname
                }
            }
        })
    </script>
</body>
</html>

监视属性:

一、监听

1、当被监视的属性发生变化时回调函数自动调用,进行相关操作

2、监视的属性(包括计算属性和属性)必须存在才能进行监视

3、监视属性的两种写法

①new Vue时传入watch配置(确定要监视谁时调用)

②通过vm.$watch监视

二、深度监听

1、Vue中的watch默认不监视对象内部值的改变(只监视一层)

2、配置deep:true可以监视对象内部(多层)值得改变

注:

1、Vue自身可以监视对象内部值得变化,但Vue提供的watch默认不可以

2、使用watch时根据数据的具体结构,决定是否采用深度监视

三、当监视的属性只有handler时可采用简写

参数:

handler(newValue,oldValue):当监视属性监视的属性的值的发生改变时调用

newValue:被监视的属性修改之后的值
oldValue: 被监视的属性被修改之前的值
**note:**这两者参数是可选的,即handler函数的参数可选
immediate:控制初始化时否是调用hander,默认值为false

deep:控制是否开启深度监视,默认值为false

deep = false:只要watch对象监视的属性的地址没有发生改变,就认为它没有改变,
哪怕这个属性是个对象或者数组且其内部的值发生了变化

deep = true:如果watch对象监视的属性是对象或者数组时,且它的内部值发生改变,认为这个属性发生了改变

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>今天天气很好{{weather}}</h2>
        <button @click="changeWeather">切换天气</button>
    </div>
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data() {
                return {
                    weather:'hot',
                    isHot:true
                }
            },
            methods: {
                changeWeather(){
                    if(this.isHot){
                        this.weather='rain',
                        this.isHot=false
                    }else{
                        this.weather='hot',
                        this.isHot=true

                    }
                }
            },

        })

    </script>
</body>
</html>
<!--利用了计算属性-->
<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>

</head>
<body>
    <div id="root">今天天气是{{weather}}
        <br>
        <button @click="changeWeather">点击切换天气</button>
    </div>
    
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                isHot:true
            },
            methods: {
                changeWeather(){
                    this.isHot = !this.isHot
                }
            },
            computed:{
                weather(){
                    return this.isHot?'hot':'rain'

                }
            }
        })
    </script>
</body>
</html>

利用监视属性:

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>

</head>
<body>
    <div id="root">今天天气是{{weather}}+{{Number.a}}
        <br>
        <button @click="changeWeather">点击切换天气</button>
    </div>
    
    <script type="text/javascript">
        new Vue({
            el:'#root',
            data:{
                isHot:true,
                Number:{
                    a:1,
                    b:2
                },
                weather:'hot'
            },
            methods: {
                changeWeather(){
                    this.isHot = !this.isHot
                    this.Number.a = this.Number.a + 1
                }
            },
            // computed:{
            //     weather(){
            //         return this.isHot?'hot':'rain'

            //     }
            // },
            watch:{
                Number:{
                    immediate:true,// 在加载完成后就调用一次immediate,表示还没有点击的时候就加载一下
                    deep:true, //表示的只要地址里面的数值发生改变的话,就会发生变化
                    handler(){
                        console.log("发生改变")
                    }
                },
                // 监视属性就是 监视的属性发生了变化 才会才会出发这个函数
                isHot(){
                    setTimeout(()=>{
                        this.weather = this.isHot?'hot':'rain'
                    },1000)
                    

                }

            }
        })
    </script>
</body>
</html>

computed和watch之间的区别:

​ 1.computed能完成的功能,watch都可以去完成、

​ 2.watch能完成的功能,computed不一定可以去完成;例如watch可以进行异步操作

绑定样式:

绑定class样式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KPx180KC-1659270417041)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220719211943528.png)]

绑定style样式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DgAEMmim-1659270417042)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220719212136060.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Y0UiBNe-1659270417042)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220719212149630.png)]

样式表style之所以是样式表,就是因为里面的东西不能自己去瞎写,都是有规定的

条件渲染:

v-if和v-show都是可以进行条件选择的然后去判断要不要去渲染,但是v-if是把整个div语句去掉,而v-show只是不去显示,所以在进行频繁操作的时候,v-show的效果要比v-show的效果要好很多

v-if这个命令值下面还有v-else-if以及v-else

v-if 如果执行成功的前提下就不去执行 下面的v-else-if的语句了

如果前面的判断语句都失效的前提下,可以去选择v-else不管v-else里面有没有语句都会去执行的

还有就是 v-if的判断语句中间如果加上了其他的div语句就会打断我们的if判断就不去执行后面的语句了

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>当前的数值是:{{n}}</h2>
        <button @click="n++">点击我进行n+1</button>
        <!-- 使用v-if做条件渲染
        <div v-if="n === 1">Angular</div>
        <div v-if="n === 2">React</div>
        <div v-if="n === 3">Vue</div> -->

        <!--使用v-show做条件渲染-->
        <div v-show="n === 1">Angular</div>
        <div v-show="n === 2">React</div>
        <div v-show="n === 3">Vue</div>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                n:0
            }
        })

    </script>
</body>
</html>

条件渲染:
(1)v-if
写法:
v-if="表达式”
v-else-if=“表达式”
v-else="表达式”
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意: v-if可以和:v-else-if、v-else起使用, 但要求结构不能被“打断”。

(2)V- show

写法: v-show=" 表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

(3)备注:使用v- if的时,元素可能无法获取到,而使用v-show 定可以获取到。

因为v-if的时候dom元素就不存在了,所以一般不会使用v-if

template模板标签配合v-if来使用可以不去破坏 原本代码的结构,配合v-show标签起不到效果

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h2>当前的数值是:{{n}}</h2>
        <button @click="n++">点击我进行n+1</button>
        <template v-if="n===1">
            <h2>你好</h2>
            <h2>尚硅谷</h2>
            <h2>北京</h2>
        </template>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data:{
                n:0
            }
        })
    </script>
</body>
</html>

列表渲染

v-for的使用:

v-for=“(person,index) in persons” :key

这里的key最好加上,并且index这里是默认的下标值,最好加上括号,这样显得更加规范一些

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <li v-for="(p,index) in persons" :key="p.id">
            姓名{{p.name}}---年龄{{p.age}}--{{index}}
        </li>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data() {
                return {
                    persons:[
                        {id:1,name:'wsy',age:18},
                        {id:2,name:'zl',age:15}
                    ]
                }
            },

        })
    </script>
</body>
</html>

:key为什么要使用唯一id的讲解:

如果使用index作为key会发生什么原理图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QU01ULMV-1659270417043)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220719224906494.png)]

但是使用id唯一标识的好处原理图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6bAYgyuz-1659270417043)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220719225248339.png)]

在不指定key的时候,默认选用的是index作为默认的参数,而不是唯一的id,索引是会自己去排序的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gXPLWbIi-1659270417044)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220719225638505.png)]

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <li v-for="(p,index) in persons" :key="p.id">
            姓名{{p.name}}---年龄{{p.age}}--{{index}}
            <input type="text">
        </li>
        <button @click="add">点击添加老刘</button>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data() {
                return {
                    persons:[
                        {id:1,name:'wsy',age:18},
                        {id:2,name:'zl',age:15}
                    ]
                }
            },
            methods: {
                add(){
                    this.persons.unshift({id:3,name:'xzz',age:11})
                }
            },

        })
    </script>
</body>
</html>

列表过滤:

filter()方法会创建一个新数组,原数组的每个元素传入回调函数中,回调函数中有return返回值,若返回值为true,这个元素保存到新数组中;若返回值为false,则该元素不保存到新数组中;原数组不发生改变。

使用监视属性来进行过滤:

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <input type="text" placeholder="请输入姓名" v-model="keyWord">
        <li v-for="(p,index) in filterPerson" :key="p.id">
            姓名{{p.name}}---年龄{{p.age}}--{{index}}
        </li>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data() {
                return {
                    persons:[
                        {id:1,name:'周冬雨',age:18},
                        {id:2,name:'马冬梅',age:15},
                        {id:3,name:'周杰伦',age:22},
                        {id:4,name:'温兆伦',age:1},
                        
                    ],
                    keyWord:'',
                    filterPerson:[]
                }
            },
            watch:{
                keyWord(val){
                    this.filterPerson = this.persons.filter(
                        (p)=>{
                            return p.name.indexOf(val) !== -1
                        }
                    )
                }
            }


        })
    </script>
</body>
</html>

利用computed计算属性来进行过滤:

<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <input type="text" placeholder="请输入姓名" v-model="keyWord">
        <li v-for="(p,index) in filterPerson" :key="p.id">
            姓名{{p.name}}---年龄{{p.age}}--{{index}}
        </li>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data() {
                return {
                    persons:[
                        {id:1,name:'周冬雨',age:18},
                        {id:2,name:'马冬梅',age:15},
                        {id:3,name:'周杰伦',age:22},
                        {id:4,name:'温兆伦',age:1},
                        
                    ],
                    keyWord:'',
                }
            },

            computed:{
                filterPerson(){
                    return this.persons.filter(
                        (p)=>{
                            return p.name.indexOf(this.keyWord) !== -1
                        }
                    )
                }
            }


        })
    </script>
</body>
</html>

列表排序:

arr.sort函数进行排序

const points = [40, 100, 1, 5, 25, 10];

// 按升序对数字进行排序:
points.sort(function(a, b){return a-b});

// points[points.length-1] = 100(最高值)
<!DOCTYPE html>
<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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <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 filterPerson" :key="p.id">
            姓名{{p.name}}---年龄{{p.age}}--{{index}}
        </li>

    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:'#root',
            data() {
                return {
                    persons:[
                        {id:1,name:'周冬雨',age:18},
                        {id:2,name:'马冬梅',age:15},
                        {id:3,name:'周杰伦',age:22},
                        {id:4,name:'温兆伦',age:1},
                        
                    ],
                    keyWord:'',
                    sortType:0
                }
            },

            computed:{
                filterPerson(){
                    const arr = this.persons.filter(
                        (p)=>{
                            return p.name.indexOf(this.keyWord) !== -1
                        }
                        
                    )
                    if(this.sortType !== 0){
                            return arr.sort((p1,p2)=>{
                                return this.sortType===2?p2.age-p1.age:p1.age-p2.age
                            })
                        }
                    
                    return arr
                }
            }


        })
    </script>
</body>
</html>

Vue检测数据变化的原理:

通过构造对象,将需要改变的数值,放在数组里来进行实现的

Vue.set的Api

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GsLZgeRv-1659270417045)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220720105002647.png)]

vm.set是有局限性的,只能给data里面已经含有的属性进行赋值,不可以给data进行赋值

vm.set(1,2,3)1这个不可以是vm也不可以是vm.data

在数组末尾进行操作 加入一个数值:push拿出一个数值:pop 在开头拿出一个shift 在开头放一个unshift splice sort

使用改变数组的这些方法,Vue才可以检测到,承认到修改了数组

原因是因为Vue自己包装了数组的一些api

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HpzeiGBr-1659270417045)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220720110952773.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yiIPuXXL-1659270417045)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220720111033732.png)]

有setter和getter是可以直接去修改的,数组因为是没有setter和getter的,所以没有办法去响应

splice的用法:

当第二个参数不为0的时候

    var arr = [2,4,6,7,8,9]; 
    console.log(arr);//[2,4,6,7,8,9]
    var n = arr.splice(2,3,5);//表示从下标为2的位置开始,删除3个项,在下标为2的位置添加一个数字为5的新项
    console.log(n);//[6, 7, 8]
    console.log(arr);//[2, 4, 5, 9]

总结:1.vue会检测data中所有层次的数据

​ 2.如何检测对象当中的数据?

​ 通过setter实现监视,且在new Vue 时就传入要检测的数据

​ (1).对象后追加的属性,vue不去做响应式处理

​ (2).如需要给后添加的对象去做响应式,需要以下的API:

​ Vue.set(target,propertyName/index,value)

​ Vue.$set(target,propertyName/index,value)

​ 3.如何检测数组中的数据?

​ (1).调用原生对应的方法进行数组的更新(2)重新去解析页面,进而更新模板

​ 4.在Vue进行修改数组的某个元素,一定要用到如下的方法:

​ 1.使用这些API:push(),pop(),shift(),unshift(),splice(),sort(),reverse()

​ 2.Vue.set()或者Vue.$set

数据劫持:

指的是在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果。
比较典型的是Object.defineProperty()和 ES2016 中新增的Proxy对象。数据劫持最著名的应用当属双向绑定,这也是一个已经被讨论烂了的面试必考题。例如 Vue 2.x 使用的是Object.defineProperty()(Vue 在 3.x 版本之后改用 Proxy 进行实现)。

收集表单数据:
若: ,则v-mode1收集的是value值,用户输入的就是value值。
若: , 则v -mode1收集的是value值,且要给标签配置value值。
若江
1.没有配置input的value属性,那么收集的就是checked (勾选or未勾选,是布尔值)
2.配置input的value属性:
(1)v-mode1的初始值是非数组,那么收集的就是checked (勾选or未勾选,是布尔值)
(2)v - mode1的初始值是数组,那么收集的的就是value组成的数组
备注: v-mode1的 三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过滤

表单:

<form id="root" @submit.prevent='dome'>
        账号:<input type="text" v-model.trim="account">
        <!-- trim 控制vue不收集空格 -->
        <br><br>
        密码:<input type="password" v-model="password">
        <br><br>
        年龄:<input type="number" v-model.number="age">
        <!-- number html中控制只能输入数字,vue中控制只能接收数字 -->
        性别:
        男<input type="radio" name="sex" value="man" v-model="sex"><input type="radio" name="sex" value="woman" v-model="sex">
        <br><br>
        爱好:
        学习<input type="checkbox" v-model="hobby" value="study">
        打游戏<input type="checkbox" v-model="hobby" value="play">
        吃饭<input type="checkbox" v-model="hobby" value="eat">
        <br><br>
        所属学校:
        <select v-model="school">
            <option value="">请选择校区</option>
            <option value="beijing">北京</option>
            <option value="shanghai">上海</option>
            <option value="shenzhen">深圳</option>
            <option value="wuhan">武汉</option>
        </select>
        <br><br>
        其他信息:
        <textarea cols="30" rows="5" v-model.lazy="other"></textarea>
        <!-- lazy修饰符 控制页面失去焦点后收集信息 -->
        <br><br>
        <input type="checkbox" v-model="gree">阅读并接受<a href="http://baidu.com">《用户协议》</a>
        <button>提交</button>
    </form>

Vue._data属性的配置:

注意看这里的hobby是个数组
data:{
            account:'',
            password:'',
            sex:'',
            hobby:[],
            school:'beijing',
            other:'',
            gree:'',
            age:[]
        }

Vue.js 允许你自定义过滤器,被用作一些常见的文本格式化。由"管道符"指示, 格式如下:

{{ message | filter}}

接下来通过一个具体是示例,分析Vue.Js中过滤器的简单使用,具体代码如下:

<template>
    <div class = "Demo1">
         <p>原字符:{{text}}</p>
         <p>无参数过滤替换:{{text|textFilter}}</p>
         <p>传参过滤替换:{{text|textFilter1("传参")}}</p>
         <p>首字母大写过滤:{{text|fanzhuangfilter}}</p>
         <!--过滤器还可以串联,使用多个管道符分割开多个过滤器即可-->
         <p>过滤器串联:{{text|textFilter|fanzhuangfilter}}</p>
    </div>
</template>
<script>
export default {
    name:"guolvqi",
    data(){
        return {
            text:"aabbbccc"
        }
    },
    methods:{
    },
    filters:{
            //定义一个字符替换的过滤器
            textFilter:function(value){
                value = value.toString()
                 //字符串的replace 方法的第一个参数,除了可写一个字符串之外,还可以定义一个正则表达式,g表示全局替换,不然只替换第一个a
                 return value.replace(/a/g,'d');
            },
            //定义一个可以传参的字符替换过滤器,根据传递的参数,指定替换,不用写死
            textFilter1:function(value,arg){
                value = value.toString()
                 return value.replace(/a/g,arg);
            },
            //定义一个第一个字符大写的过滤器
            fanzhuangfilter:function(value){
                //如果字符串为空,直接返回
                if(!value){
                    return value
                }
                value = value.toString();
                return value.charAt(0).toUpperCase()+value.slice(1);
            }
        }
}
</script>
<style scoped>
</style>

v-text指令:

v-text指令的作用是:设置标签的内容

v-text指令默认写法会替换标签的全部内容,使用插值表达式{{}}可以替换指定的内容

v-text指令内部支持表达式

<!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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root" v-text="name">标签内的内容无法展示直接被覆盖</div>
    <script type="text/javascript">
        const vm = new Vue(
           {
            el:'#root',
            data:{
                name:'zhoujielun'
            }
           }
        )
    </script>
    
</body>
</html>

v-html:

v-html 指令的作用:设置元素的innerHTML

内容中有html结构会被解析为标签

v-text指令无论内容是什么,只会解析为文本

解析文本使用v-text,需要解析html结构使用v-html

<!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">
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root" v-html="name">标签内的内容无法展示直接被覆盖</div>
    <script type="text/javascript">
        const vm = new Vue(
           {
            el:'#root',
            data:{
                name:'<h3>zhoujielun<h3>'
            }
           }
        )
    </script>
    
</body>
</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pcBwqCuU-1659270417046)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220720183237753.png)]

v-htm1指令:
1.作用:向指定节点中渲染包含htm1结构的内容。
2.与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2) .v- html可以识别html结构。
3.严重注意: v-html有安全性问题! ! ! !
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2).一定要在可信的内容上使用y-html,永不要用在用户提交的内容上!

v-cloak:

v-cloak的作用?

**v-cloak指令的作用:**防止页面加载时出现闪烁问题(解决插值表达式的闪烁问题);

为什么会有闪烁问题昵?

代码加载的时候先加载HTML,把插值语法当做HTML内容加载到页面上,当加载完js文件后才把插值语法替换掉,所以我们会看到闪烁问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2C1lTmmt-1659270417046)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220720190959635.png)]

v-once:

v-once 也是一个不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或 组件的所有子节点。首次渲染后,不再随数据的变化重新渲染,将被视为静态内容
  下面示例,原本是每一秒展示动态随机数,但是因为使用v-once 首次渲染后,就不在改变数字了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-21Ze7U8C-1659270417047)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220720191301654.png)]

v-pre:

v-pre指令说明:跳过这个元素和它的子元素的编译过程。可以用来显示原始标签。跳过大量没有指令的节点会加快编译。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XnBAes5j-1659270417047)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220720191648390.png)]

自定义指令:

函数式的自定义指令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xL5vFje4-1659270417047)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220722184511507.png)]

主要就是directives对象里面来写指令 element是元素,binding是绑定的对象,通过binding.value可以取出来数值

对象式的自定义指令:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-agbvhjCh-1659270417048)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220722185539978.png)]

其实函数式的就是没有inserted这个函数其他两个函数的简写,一般bind和update两个函数的逻辑是一样的

遇到想要写bigNumber这样的指令的时候,写成v-big-number这种形式,下面使用单引号修改一下格式比较好

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LyzRhffp-1659270417048)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220722185850378.png)]

Vue的生命周期

setInterval()函数里面有两个参数,一个是一个函数,一个是定时器的时间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YgFQeQ57-1659270417048)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220722191548809.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rPA7xCfr-1659270417049)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220722191320808.png)]

这些函数在Vue创建好模板,并且进行渲染的某个时机进行调用的,这些函数还有一个名字叫做Vue的生命周期

生命周期:
1.又名:生命周期回调函数、生命周期函数、生命周期钩子。
2.是什么:Vue在关键时刻帮我们调用的些特殊名称的函数。
3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
4.生命周期函数中的this指向是vm或组件实例对象。

挂载流程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FKKTOyKs-1659270417049)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723091034875.png)]

更新流程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KYxYQCnQ-1659270417050)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723091904712.png)]

销毁流程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PfSRWn56-1659270417050)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723091958450.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-epkahxNb-1659270417050)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723092349704.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hWbahqpp-1659270417051)(C:\Users\王率宇\AppData\Roaming\Typora\typora-user-images\image-20220723094606289.png)]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值