尚硅谷张天禹Vue2+Vue3笔记(待续)

news2024/11/20 20:32:54

简介

什么是Vue?

一套用于构建用户界面的渐进式JavaScript框架。将数据转变成用户可看到的界面。

什么是渐进式? 

Vue可以自底向上逐层的应用

简单应用:只需一个轻量小巧的核心库

复杂应用:可以引入各式各样的Vue插件

Vue的特点是什么?

1.采用组件化模式,提高代码复用率、且让代码更好维护。

2.声明式编码,让编码人员无需直接操作DOM,提高开发效率。

3.使用虚拟DOM+优秀的Diff 算法,尽量复用DOM节点

 Vue官网

vue2 

介绍 — Vue.js

vue3  

Vue.js - 渐进式 JavaScript 框架 | Vue.js

Vue2-html文件中写vue

下载安装 

 开发版本比较大,生产版本较小。

开发时推荐引入开发版本的vue,有提示。

我们下载下来源码并引用,甚至可用修改源码。

 下载Vue开发者工具

参考:vue devtools在谷歌浏览器安装使用,附vue,vue3devtools下载资源_vue3.js tools 谷歌_…咦的博客-CSDN博客

学习vue2,可参考vue2的文档API — Vue.js

外:shift+点击网页刷新,为强制刷新。

外:vscode的live server运行html,网页除了输入http://127.0.0.1:5h500/http://127.0.0.1:5500/Vue/Vue.htmlhttp://127.0.0.1:5500/还可输入http://127.0.0.1:5500/,然后选中文件夹

可在vsCoder中安装一个Vue 3 snippets插件。 写vue代码回有提示补全。

演示代码:

目录结构 

html代码 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>初识Vue</title>
    <script type="text/javascript" src="../js/vue.js">
    </script>
</head>
<body>
    <!-- 总结:
        初识Vue:
        1.想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
        2.root容器里的代码依然符合html规范。只不过混入了一些特殊的Vue语法;
        3.root容器里的代码被称为【Vue模板】;
        4.Vue实例和容器是一一对应的;
        5.真实开发中只有一个Vue实例,并且会配合着组件一起使用;
        6.{{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;
        7.一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;
     -->
    <!-- 准备好一个容器 -->
    <div id="root">
        <h1>hello,kdy</h1>
        <!-- {{}}中的需要为一个js表达式(表达式最终计算出一个值的),而不是js代码 -->
        <p>{{name.toUpperCase()}}--{{new Date()}}</p>
    </div>
    <p>{{name}}</p><!--//容器外,data无效-->
   <script type="text/javascript">
    Vue.config.productionTip=false
    // 在配置下方写vue实例
    /*const x = */new Vue({
        el:"#root",  //element元素,让vue实例和容器之间建立联系,指定当前实例为哪个容器服务.里面传递选择器,可id可class.,若class就".root"
        data:{  //data中用于存储数据,数据供el所指定的容器去使用。
            name:"kdy"
        }
    })
   </script> 
</body>
</html>

注意:vue实例和容器之间是一对一的:若两个class为root容器对于一个绑定.root的vue实例,则第二个容器中不生效。若一个id为root的容器绑定两个new Vue的cl为“#root”的实例,则第二个new的vue实例不生效。

模板语法

1、插值语法{{}}:位于标签体中

2、指令语法v-bind:位于标签属性

代码演示: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板语法</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <!-- 
        Vue模板语法有2大类:1.插值语法:
        功能:用于解析标签体内容。
        写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。2.指令语法:
        功能:用于解析标签(包括:标签属性、标签体内容、绑定事件.....) 。
        举例:v-bind:href="xxx”或简写为:href="xxx",xxx同样要写js表达式,
        且可以直接读取到data中的所有属性。
        备注: Vue中有很多的指令,且形式都是: v-????,此处我们只是拿v-bind举个例子。
     -->
    <div id="app">
        <p>{{message}}</>
        <p>{{user.name}}</>
        <p>{{user.age}}</><br/>
            <!-- 指令语法v-bind: 可指定任何一个属性-->
        <a v-bind:href="url">百度</a>
        <div :x="hello"></div>
    </div>
    <script type="text/javascript">
        new Vue({
            el:"#app",
            data:{
                message:"插值语法",
                url:"http://www.baidu.com",
                hello:"你好",
                user:{
                    name:"王五",
                    age:20
                }
            },
        })
    </script>
</body>
</html>

数据绑定

单向数据绑定v-bind:,data->模板页面

代码案例  数据绑定.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据绑定</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <!-- 
        Vue中有2种数据绑定的方式:
        1.单向绑定(v-bind):数据只能从data流向页面。
        2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
        备注:
        1.双向绑定一般都应用在表单类元素上(如: input、select等)
        2.v-model:value可以简写为v-model,因为v-model默认收集的就是value值。
     -->
    <div id="app">
        单向数据绑定:<input type="text" v-bind:value="msg"/><br/>
        双向数据绑定:<input type="text" v-model:value="msg2"/><br/>
        双向数据绑定:<input type="text" v-model="msg2"/>
        <!-- 如下代码是错误的,v-model只能绑定在表单类的元素(输入元素)上 
        input\单选框\多选框\select框\多行输入
        -->
        <!-- <h2 v-model:x="msg2">你好啊</h2> -->
    </div>
    <script type="text/javascript">
        new Vue({
            el:"#app",
            data:{
                msg:"hello123",
                msg2:"hello123"
            },
        })
    </script>
</body>
</body>
</html>

  el与data的两种写法

代码展示: el与data的两种写法.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>el与data的两种写法</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <!-- 

        data与el的2种写法
        1.el有2种写法
        ( 1).new Vue时候配置el属性。
        (2).先创建Vue实例,随后再通过vm. $mount( ' #root ')指定el的值。
        2.data有2种写法
        (1).对象式(2).函数式
        如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。
        3.一个重要的原则:
        由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。
     -->
    <div id="root">
        <h1>你好,{{name}}</h1>
    </div>
    <script type="text/javascript">
/*        const v = new Vue({
            //el:"#root",
            data:{
                name:"王五"
            }
        })
        console.log(v)//打印出vue实例.发现有很多$开头的内容,这些$开头的内容就是给程序员使用的./
        //el就可通过v.$mount("#root"),这种方式比较灵活.
        v.$mount("#root")
        */
        new Vue({
            el:"#root",
            //data的第一种写法:对象式
            /*data:{
                name:"王五"
            },*/
            //data的第二种写法:函数式  以后学习组件的时候,必须使用该函数式的data
            data:function(){
                console.log(this)//此处的this是vue实例对象
                return{
                    name:"王六"
                }
            },
            /*data函数式不能写箭头函数,以下写法是错误的,必须老老实实的写上面的function的这种.
            data:()=>{
                console.log(this)//箭头函数由于没有自己的this,就找到了最外层的data即windows
            }*/

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

MVVM模型

vue参考了MVVM:

1.M:模型(Model) :对应data中的数据
2.V:视图(View):模板
3.VM:视图模型(ViewModel) : Vue 实例对象

 文档中常用vm代表vue实例。

vm实例中的所有东西都可写在{{}}中

代码演示:vue中的MVVM.html: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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>
    <!-- 
        观察发现:
        1.data中所有的属性,最后都出现在了vm身上。
        2.vm身上所有的属性及 Vue原型上所有属性,在Vue模板中都可以直接使用。
     -->
    <div id="root">
        <p>{{name}}</p>
        <!-- vue实例中的东西都可在{{}}中 -->
        <P>{{$options}}</P>
        <P>{{$emit}}</P>
        <!-- view -->
    </div>
    <script type="text/javascript">
        const vm = new Vue({ //  ViewModel
            el:"#root",
            data:{//  model
                name:"张三"
            }
        })
        console.log(vm)//data中写的内容会出现在vm上,也就是vue实例上.
    </script>
</body>
</html>

回顾js的Object.defineproperty方法

代码演示:Object.defineproperty.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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:"张三",
            sex:"男"
        }
        Object.defineProperty(person,'age', {   //给person增加一个属性
            //value:18,
            //enumerable:true,  //控制属性是否可以枚举,默认值是false
            //writable:true,  //控制属性是否可以被修改,默认值是false
            //configurable:true,  //控制属性是否可以被删除,默认值是false
            //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
            get:function(){   //get:function()也可简写为get()
                console.log('有人读取age属性了')
                return number
            }, 
            set(value){
                console.log('有人修改了age属性,且值是',value)
                number=value
            }
        })

        console.log(person)
        console.log(Object.keys(person))
        for(let key in person){
            console.log('@',person[key])
        }
    </script>
</body>
</html>

运行后在f12控制台中person.age和person.age = 150这样设置。 

数据代理

代码演示:何为数据代理.html 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>何为数据代理</title>
</head>
<body>
    <script type="text/javascript" >
        let obj = {x:100}
        let obj2 = {y:200}
        Object.defineProperty(obj2,'x',{
            get(){
                return obj.x
            },
            set(value){
                obj.x = value
            }
        })
    </script>
</body>
</html>

运行后在f12控制台中obj.x和obj2.x和其set。 

就是通过vm读取或写入data中的数据: 

vm将data中的数据放到了_data中(_data里的数据做了数据劫持)

Vue中的数据代理.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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>
    <!-- 
        1.vue中的数据代理:
        通过vm对象来代理data对象中属性的操作(读/写)
        2.Vue中数据代理的好处:
        更加方便的操作data中的数据3.基本原理:
        通过object.defineProperty()把data对象中所有属性添加到vm上.为每一个添加到vm上的属性,都指定一个getter/setter。
        在getter/setter内部去操作(读/写)data中对应的属性。
     -->
    <div id="app">
        <h2>姓名:{{name}}</h2>
        <!-- vue对象的属性可直接在插值表达式中 -->
        <h2>姓名:{{_data.name}}</h2>
        <h2>年龄:{{age}}</h2>
    </div>
    <script type="text/javascript">
        let data={
            name:"张三",
            age:20
        }
        const vm = new Vue({
            el:"#app",
            data
        })
    </script>
</body>
</html>

live server运行后,f12控制台测试为:

 vm.name
'张三'
vm.name="王五"
'王五'
vm.name
'王五'
vm._data.name="张柳"
'张柳'
vm.name
'张柳'
vm._data==data
true

如果vue没有做数据代理,f12控制台只能访问vm._data.name了,加上数据代理,就可以vm.name使用了。

数据代理,就是把_data中的东西放到vm对象身上。

 事件处理

事件的基本使用.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件的基本使用</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <!-- 
        事件的基本使用:
        1.使用v-on : xxx或@xxx绑定事件,其中xxx是事件名;
        2.事件的回调需要配置在methods对象中,最终会在vm上;
        3.methods中配置的函数,不要用箭头函数!否则this就不是vm了;
        4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm或组件实例对象
        5.@click="demo”和L@click="demo($event)”效果一致,但后者可以传参;
     -->
    <div id="root">
        <h2>欢迎来到{{name}}学习</h2>
        <button v-on:click="showInfo">点我显示提示信息</button><br/>
        <!-- 也可写成@click -->
        <button @click="showInfo2">点我显示提示信息2</button><br/>
        <!-- 事件传递参数进入 一个参数直接写,如果要用到event,需要$event占位-->
        <button @click="showInfo3(66,'你好',$event)">点我显示提示信息3</button>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:"#root",
            data:{
                name:"尚硅谷",
                //虽然方法也可写在data中,但会增加vue负担,会也做数据代理和数据劫持
            },
            methods:{
                showInfo(event){
                    console.log(event.target.innerText)//点我显示提示信息
                    console.log(this)//此处的this是vue对象
                    alert("你好")
                },
                showInfo2:(event)=>{
                    console.log(this)//此处的this没有自己的this,就找到了全局的Window
                },
                //所以推荐所有被vue管理的函数要写成普通函数,不用写箭头函数
                showInfo3(num,hello,event){
                    console.log(num)
                    console.log(hello)
                    console.log(event)
                },
            }
        })

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

天气案例.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>天气案例</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <div id="root">
        <h3>今天天气很{{info}}</h3>
        <button @click="changeWeather">切换天气</button><br/>
        <!-- 简单的@click事件可如下这样写 -->
        <button @click="isHot=!isHot">切换天气</button><br/>
        <!-- 甚至vm中data中可以把window也引过来,但不推荐这样写哈 -->
        <button @click="window.alert('你好')">切换天气</button>
    </div>
</body>
<script type="text/javascript">
    new Vue({
        el:"#root",
        data:{
            isHot:true,
            window
        },
        computed:{
            info(){
                return this.isHot? "炎热":"寒冷"
            }
        },
        methods: {
            changeWeather(){
                this.isHot = !this.isHot
            }
        },
    })
</script>
</html>

事件修饰符

阻止默认行为、阻止冒泡、事件只触发一次. . . 

demo.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件修饰符</title>
    <script type="text/javascript" src="../js/vue.js"></script>
    <style>
        *{
            margin-top: 20px;
        }
        .demo1{
            height: 50px;
            background: blanchedalmond;
        }
        .box1{
            background-color: aqua;
            padding: 10px;
        }
        .box2{
            padding: 10px;
            background-color: rgb(213, 221, 123);
        }
        .list{
            width: 200px;
            height: 200px;
            background-color:coral;
            /* 形成滚动条 */
            overflow: auto;
        }
        li{
            height: 100px;
        }
    </style>
</head>
<body>
    <!-- Vue中的事件修饰符:
        1.prevent: 阻止默认事得(常用);
        2.stop:阻止事件冒泡(常用);
        3.once:事件只触发一次(常用);
        4.capture:使用事件的捕获模式;
        5.self:只有event.target是当前操作的元素是才触发事件;
        6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕; -->
    <div id="root">
        <h2>欢迎来到{{name}}学习</h2>
        <a href="http://www.baidu.com" @click="showInfo">百度</a><br/>
        <!-- 阻止了事件的默认行为方式2 .prevent就是事件修饰符-->
        <a href="http://www.baidu.com" @click.prevent="showInfo2">百度2</a>
        <!-- 阻止事件冒泡  @click.stop -->
        <div class="demo1" @click="showInfo2">
            <button @click.stop="showInfo2">点我提示信息</button>
        </div>
        <!-- 事件只触发一次 -->
        <button @click.once="showInfo2">点我提示信息</button>
        <!-- 使用事件的捕获模式 -->
        <div class="box1" @click="showMsg(1)">
            div1
            <div class="box2" @click="showMsg(2)">
                div2
            </div>
        </div>
        <!-- 当上面div2点击后,控制台先打印2,再打印1,如果给外面盒子div1加上捕获capture,就会先捕获在处理了,就先打印1,再打印2了 -->
        <div class="box1" @click.capture="showMsg(1)">
            div1
            <div class="box2" @click="showMsg(2)">
                div2
            </div>
        </div>
        <!-- 只有event.target是当前操作的元素是才触发事件; -->
        <div class="demo1" @click.self="showInfo3">
            <button @click="showInfo3">点我提示信息</button>
            <!--外层div事件修饰符不加self:f12控制台打印了两边按钮的元素,说明还是这个按钮的事件,所以给外层div加上一个事件修饰符self也从某种意义上阻止了事件冒泡
                <button>点我提示信息</button>
                <button>点我提示信息</button>
            -->
        </div>
        <!-- passive:事件的默认行为立即执行,无需等待事件回调执行完毕; -->
        <ul @wheel.passive="demo" class="list">
            <!--@scroll滚轮和拖曳滚动条均可 @whell是仅滚轮滚动 -->
            <!-- 绑定的demo函数中有个很繁琐的for循环,默认会等demo函数完全执行完之后才会执行滚轮的默认事件,加上passive,就会不用等demo函数执行完就执行滚轮的默认事件向下滚动了。passive进行优化的,如移动端手机或平板肯恶搞会使用一下。 -->
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:"#root",
            data:{
                name:"尚硅谷"
            },
            methods:{
                showInfo(event){
                    event.preventDefault()//阻止了事件的默认行为方式1
                    alert("你好")
                },
                showInfo2(event){
                    //event.stopPropagation();
                    alert("你好")
                },
                showMsg(msg){
                    console.log(msg)
                },
                showInfo3(event){
                    console.log(event.target)
                },
                demo(){
                    for(let i=0;i<100000;i++){
                        console.log("#")
                    }
                    console.log("累坏了")
                }

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

事件修饰符,也可以连着写,@click.stop.prevent=showInfo()

键盘事件

键盘事件.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>键盘事件</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <!-- 
        1.Vue中常用的按键别名:
        回车 => enter 删除=> delete(捕获"删除”和“退格”键)  退出=>esc
        空格=> space换行=> tab 上 => up 下=> down  左=>left  右=> right
        2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
        3.系统修饰键(用法特殊):ctrl、alt、 shift、meta即win键
        (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
        (2).配合keydown使用:正常触发事件。
        4.也可以使用keyCode去指定具体的按键(不推荐)
        5.Vue.config. keyCodes.自定义键名=键码,可以去定制按键别名
     -->
    <div id="root">
        <input type="text" placeholder="按下回车键提示输入" @keyup="showInfo"/><br/>
        <!-- vue给常用的按键起了别名 Enter别名enter -->
        <input type="text" placeholder="按下回车键提示输入" @keyup.enter="showInfo2"/><br/>
        <!-- Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名) -->
        <input type="text" placeholder="按下caps-lock键提示输入" @keyup.caps-lock="showInfo2"/><br/>
        <!-- 对于tab,必须使用keydown,不能使用keyup -->
        <input type="text" placeholder="按下tab键提示输入" @keydwon.tab="showInfo2"/><br/>
        <!-- 
            3.系统修饰键(用法特殊):ctrl、alt、 shift、meta即win键
            (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
            (2).配合keydown使用:正常触发事件。
         -->
        <input type="text" placeholder="按下shift键提示输入" @keydown.shift="showInfo2"/><br/>
        <!-- 4.也可以使用keyCode去指定具体的按键(不推荐)可读性差 -->
        <input type="text" placeholder="按下回车键提示输入" @keydown.13="showInfo2"/><br/>   
        <!-- Vue.config. keyCodes.自定义键名=键码,可以去定制按键别名 -->
        <input type="text" placeholder="按下回车键提示输入" @keydown.huiche="showInfo2"/><br/>   
        <!-- 查看键盘按键的key和keyCode -->
        <input type="text" placeholder="按下键提示输入" @keyup="showInfo3"/><br/>
    </div>
    <script type="text/javascript">
        //5.Vue.config. keyCodes.自定义键名=键码,可以去定制按键别名
        Vue.config.keyCodes.huiche = 13
        const vm  =new Vue({
            el:"#root",
            data:{
                name:"张三"
            },
            methods:{
                showInfo(e){
                    if(e.keyCode!=13) return
                    console.log(e.keyCode)
                    console.log(e.target.value)
                },
                showInfo2(e){
                    console.log(e.target.value)
                },
                showInfo3(e){
                    console.log(e.key,e.keyCode)
                    /*
                    Control 17
                    Shift 16
                    CapsLock 20
                    */
                }
            }
        })
    </script>
</body>
</html>

如果需要按下shift+y时触发事件:@keydown.shift.y="showInfo2"    连写

不用计算属性,使用{{方法()}}

计算属性

计算属性.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>姓名案例-插值语法实现</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>    
    <!-- 
        计算属性:
        1.定义:要用的属性不存在,要通过已有属性计算得来,不能是脱离vue的变量。
        2.原理:底层借助了objcet.defineproperty方法提供的getter和setter。
        3.get函数什么时候执行?
        (1).初次读取时会执行一次。
        (2).当依赖的数据发生改变时会被再次调用。
        4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
        5.备注:
        1.计算属性最终会出现在vm上,直接读取使用即可。
        2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生
     -->
<div id="root">
    姓:<input type="text" v-model="firstName"><br/><br/>
    名:<input type="text" v-model="lastName"><br/><br/>
    <!-- {{计算属性无括号}} -->
    全名:<span>{{ fullName }}</span><br/>
    全名:<span>{{ fullName }}</span><br/>
    全名:<span>{{ fullName }}</span><br/>
    全名:<span>{{ fullName2 }}</span><br/>
    全名:<span>{{ fullName3 }}</span><br/>
    <!-- 即使引用了多个fullName,实际上fullName的get方法也只是被执行了一次,然后缓存了 -->
</div>
    <script type="text/javascript">
        const vm = new Vue({
            el:"#root",
            data:{
                firstName:"张",
                lastName:"三"
            },
            computed:{ //vm区找fullName的get方法,拿到返回值赋值给fullName
                fullName:{
                    /*
                        l、get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
                        2、get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。
                    */
                    get(){
                        return this.firstName+"-"+this.lastName
                    },
                    //set不是必须写的,当fullName被修改时调用
                    set(value){
                            const arr = value.split('-')
                            this.firstName = arr[0]
                            this.lastName = arr[1]
                    }
                    //f12中vm.fullname= "李-四"
                },
                //计算属性简写
                fullName2:function(){
                    return this.firstName+"-"+this.lastName
                },
                //计算属性简写
                fullName3(){
                    return this.firstName+"-"+this.lastName
                }
            }
        })
    </script>
</body>
</html>

监视属性

监视属性也叫侦听属性。

天气案例-监视属性.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>天气案例</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <!-- 
        监视属性watch:
        1.当被监视的属性变化时,回调函数自动调用,进行相关操作
        2.监视的属性必须存在,才能进行监视!!
        3.监视的两种写法:
        ( 1).new Vue时传入watch配置(2).通过vm.$watch监视
     -->
    <div id="root">
        <h3>今天天气很{{info}}</h3>
        <button @click="changeWeather">切换天气</button><br/>
    </div>
</body>
<script type="text/javascript">
    const vm = new Vue({
        el:"#root",
        data:{
            isHot:true,
        },
        computed:{
            info(){
                return this.isHot? "炎热":"寒冷"
            }
        },
        methods: {
            changeWeather(){
                this.isHot = !this.isHot
            }
        },
        watch:{
            isHot:{
                /*handler(){
                    console.log('isHot被修改了')
                }*/
                // handler什么时候调用?当isHot发生改变时。
                handler(newValue,oldValue){
                    console.log('isHot被修改了',newValue,oldValue)
                },
                immediate:true  //初始化时让handler调用一下,默认false f12刷新王爷后立即 isHot被修改了 true undefined
            },
            //简写方式  当只有handler时可以开始简写形式
            /*isHot(newValue,oldValue){
                console.log('isHot被修改了',newValue,oldValue)
            },*/
        }
    })
    // 监视属性也可这样写
    /*vm.$watch('isHot',{
        // handler什么时候调用?当isHot发生改变时。
        handler(newValue,oldValue){
            console.log('isHot被修改了',newValue,oldValue)
        },
        immediate:true 
    })*/
    //监视属性$watch的简写  仅有handler时可简写
     /*vm.$watch('isHot',function(newValue,oldValue){
        console.log('isHot被修改了',newValue,oldValue)})*/
</script>
</html>

深度监视

深度监视.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>天气案例</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <!-- 
        深度监视:
        (1).vue中的watch默认不监测对象内部值的改变(一层)。
        (2).配置deep:true可以监测对象内部值改变(多层)。
        备注:
        (1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
        (2).使用watch时根据数据的具体结构,决定是否采用深度监视。
     -->
    <div id="root">
        <h3>今天天气很{{info}}</h3>
        <button @click="changeWeather">切换天气</button><br/>
        <hr/>
        <h3>a的数据是{{numbers.a}}</h3>
        <button @click="numbers.a++">点我让a加1</button><br/>
        <hr/>
        <h3>b的数据是{{numbers.b}}</h3>
        <button @click="numbers.b++">点我让a加1</button><br/>
    </div>
</body>
<script type="text/javascript">
    const vm = new Vue({
        el:"#root",
        data:{
            isHot:true,
            numbers:{
                a:1,
                b:1
            }
        },
        computed:{
            info(){
                return this.isHot? "炎热":"寒冷"
            }
        },
        methods: {
            changeWeather(){
                this.isHot = !this.isHot
            }
        },
        watch:{
            isHot:{
                handler(newValue,oldValue){
                    console.log('isHot被修改了',newValue,oldValue)
                }
            },
            'numbers.a':{//监视多级结构中某个属性的变化,只监视a不监视b
                handler(){
                    console.log("a改变了")
                }
            },
            //再提要求,监视numbers中b属性的变化,c属性的变化,d、e、f...一百多个属性的变化,总不能一个个的写吧
            numbers:{
                deep:true,//监视多级结构中所有属性的变化
                handler(){
                    console.log("numbers改变了")
                }
            }
        }
    })
</script>
</html>

watch对比computed

watch对比computed.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>计算属性和watch</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>    
    <!-- 
        computed和watch之间的区别:
        1.computed能完成的功能,watch都可以完成。
        2.watch能完成的功能,computed不一定能完成,例如: watch可以进行异步操作。
        两个重要的小原则;
        1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
        2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等),最好写成箭头函数,这样thi的指向才是vm或组件实例对象。        
     -->
<div id="root">
    姓:<input type="text" v-model="firstName"><br/><br/>
    名:<input type="text" v-model="lastName"><br/><br/>
    全名:<span>{{ fullName }}</span><br/>
</div>
    <script type="text/javascript">
        const vm = new Vue({
            el:"#root",
            data:{
                firstName:"张",
                lastName:"三",
                fullName:"张-三"
            },
            computed:{ 
                /*fullName(){
                    return this.firstName+"-"+this.lastName
                }*/
            },
            watch:{
                firstName(newValue){//相比计算属性赋值,watch中方法还可以使用函数,如计时器。而计算属性中由于依赖返回值,不能开启异步任务维护数据,不能使用计时器
                    setTimeout(() => {//因为定时器的回调不受vue控制,js引擎调的,所以可以且必须写成箭头函数
                        //因为不受vue管理,this就往外找,找到了firstName中的this,时vue管理的,所以下面的this.fullName又受vue管理了。倘若不写箭头函数而写普通函数,那this由于不受vue管理,而受window管理,就变成了window.fullName了
                        this.fullName=newValue+"-"+this.lastName
                    }, 1000);
                },
                lastName(val){
                    this.fullName=this.firstName+"-"+val
                }
            }
        })
    </script>
</body>
</html>

绑定class样式

f12元素中可直接编辑,失去焦点就会运用

绑定样式.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>绑定样式</title>
    <script type="text/javascript" src="../js/vue.js"></script>
    <style>
        .basic{
            width: 200px;
            height: 200px;
            border-style: solid;
            border-color: blue;
        }
        .happy{
            background-color: rgb(233, 236, 30)
        }
        .sad{
            background-color: rgb(30, 236, 191)
        }
        .normal{
            background-color: rgb(128, 211, 19)
        }
        .style1{
            background-color: rgb(211, 153, 19)
        }
        .style2{
            font-size: 50px;
        }
        .style3{
            border-radius: 20%;
        }
    </style>
</head>
<body>
    <!-- 
        绑定样式:
        1.class样式
        写法:class="xxx"xxx可以是字符串、对象、数组。
        字符串写法适用于:类名不确定,要动态获取。
        对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
        数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用.
        2. style样式
        :style="{fontsize: xxx}"其中xxx是动态值。: style="[a,b]"其中a、b是样式对象。        
     -->
    <div id="root">
        <!-- <div class="basic normal" id="demo" @click="changeMod">{{name}}</div> -->
        <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
        <div class="basic" :class="mod"  @click="changeMod">{{name}}</div><br/><br/>
        <!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
        <div class="basic" :class="arr" >{{name}}</div><br/><br/>
        <!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 -->
        <div class="basic" :class="classObj" >{{name}}</div><br/><br/>
        <!-- css的烤肉串变成驼峰命名 -->
        <div class="basic" :style="{fontSize: fsize+'px'}" >{{name}}</div><br/><br/>
        <!-- 绑定style样式--对象写法 -->
        <div class="basic" :style="styleObj" >{{name}}</div><br/><br/>
        <!-- 绑定style样式--数组写法 -->
        <div class="basic" :style="[styleObj,styleObj2]" >{{name}}</div><br/><br/>
        <div class="basic" :style="styleArr" >{{name}}</div><br/><br/>
    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el:"#root",
            data:{
                name:"张三",
                mod:"normal",
                arr:["style1","style2","style3"],
                /*
                可在f12控制台中:
                vm.arr.shift()
                'style1'
                vm.arr.shift()
                'style2'
                vm.arr.shift()
                'style3'
                vm.arr.push("style1")
                1
                vm.arr.push("style2")
                2
                vm.arr.push("style3")
                */
                classObj:{
                    style1:false,
                    style2:false
                },
                fsize:30,
                styleObj:{
                    fontSize: '30px'  //css的烤肉串变成驼峰命名
                },
                styleObj2:{
                    backgroundColor: "orange"  //css的烤肉串变成驼峰命名
                },
                styleArr:[
                {
                    fontSize: '30px'  //css的烤肉串变成驼峰命名
                },
                {
                    backgroundColor: "orange"  //css的烤肉串变成驼峰命名
                }
                ]
            },
            methods: {
                changeMod(){
                    //document.getElementById("demo").className='basic happy'//传统的js切换class
                    //this.mod="happy"
                    const arr=["happy","sad","normal"]
                    const index = Math.floor(Math.random()*3)    //0-1,乘以3,向下取整
                    this.mod=arr[index]
                }
            },
        })
    </script>
</body>
</html>

条件渲染

条件渲染.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>条件渲染</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
    <!-- 
        条件渲染:
        1.v-if
        写法:
        (1).v-if="表达式"
        (2).v-else-if="表达式"(3).v-else="表达式"适用于:切换频率较低的场景。
        特点:不展示的DOM元素直接被移除。
        注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被"“打断”。
        2.v-show
        写法:v-show="表达式"
        适用于:切换频率较高的场景。
        特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
        3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。        
     -->
    <div id="root">
        <!-- 使用v-show做条件渲染,如果为false,就为display:none掉 切换频率高推荐使用v-show-->
        <h2 v-show="a">欢迎你:{{name}} </h2>
        <h2 v-show="1==1">欢迎你:{{name}} </h2>
        <!-- 使用v-if做条件渲染,如果为false,v-if标记的整个组件都不存在了 切换频率低的推荐使用v-if-->
        <h2 v-if="a">欢迎你:{{name}} </h2>
        <h2 v-if="1==1">欢迎你:{{name}} </h2>
        <h2>当前的n值为:{{n}}</h2>
        <button @click="n++">点我n+1</button>
        <div v-show="n==1">Angular</div>
        <div v-show="n==2">React</div>
        <div v-show="n==3">Vue</div>
        <!-- if成立的话,else-if就不执行了,效率更高一些 -->
        <div v-if="n==1">Angular</div>
        <div v-else-if="n==2">React</div>
        <div v-else-if="n==3">Vue</div>
        <div v-else="n==4">哈哈</div>
        <!-- v-else不需要写条件,如果写条件了也不生效 -->
        <!-- v-if、v-else-if、v-else,v-if为最开始的,且结构体不可被打断,打断后面的代码不生效了 -->
        <!-- <template>只能配合v-if,不影响结构 -->
        <template v-if="n==1">
            <h2>你好</h2>
            <h2>happy</h2>
            <h2>hello</h2>
        </template>
    </div>
    <script type="text/javascript">
        new Vue({
            el:"#root",
            data:{
                name:"张三",
                a:false,
                n:0
            }
        })
    </script>
</body>
</html>

列表渲染

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/851395.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TCP/IP四层模型对比OSI七层网络模型的区别是啥?数据传输过程原来是这样的

一、TCP/IP四层模型对比OSI七层模型 它们两个定义的一些功能和协议都是差不多的。TCP/IP四层协议模型比我们的七层少了三层&#xff0c;把我们的数据链路层和物理层放在一层里面了&#xff0c;叫做数据链路层&#xff08;网络接口层&#xff09;&#xff0c;对应网络协议也没有…

在 Android 上使用机器学习套件检测人脸

须知事项 此 API 需要 Android API 级别 19 或更高级别。确保应用的 build 文件使用的 minSdkVersion 值不小于 19。 请务必在您的项目级 build.gradle 文件中的 buildscript 和 allprojects 部分添加 Google 的 Maven 代码库。 将 Android 版机器学习套件库的依赖项添加到模…

SpringMVC的架构有什么优势?——控制器(三)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

Python练习 linux系统资源监控

yum install python3 yum -y install python3-pip yum -y install epel-release yum -y install gcc python-devel pip install --trusted-host pypi.tuna.tsinghua.edu.cn psutil 初版&#xff1a; import os import sys import time import platform import subprocess …

Lombok 中 @EqualsAndHashCode注解的使用

Lombok 中 EqualsAndHashCode注解的使用 EqualsAndHashCode注解的作用 EqualsAndHashCode注解的作用就是自动实现model类的equals方法和hashcode方法。我们在实际工作中经常会使用lombok来简化我们的开发&#xff0c;例如我们可以在定义的model类上添加Data注解&#xff0c;从…

Go 异步任务

Go 异步任务 异步任务在开发中很常见&#xff0c;用来做解耦。本文介绍一下异步队列的实现的几个问题&#xff0c;并且结合三方库实现来分析。 有下面的几个关键点: 用户代码&#xff08;任务&#xff09;如何封装数据的存放&#xff08;数据存放在哪里&#xff1f;就是一个…

Java——基础语法(二)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

【SpringBoot】| ORM 操作 MySQL(集成MyBatis)

目录 一&#xff1a;ORM 操作 MySQL 1. 创建 Spring Boot 项目 2. MapperScan 3. mapper文件和java代码分开管理 4. 事务支持 一&#xff1a;ORM 操作 MySQL 使用MyBatis框架操作数据&#xff0c; 在SpringBoot框架集成MyBatis&#xff0c;使用步骤&#xff1a; &#x…

恒压恒流模式的工作原理及直流电源的应用

直流电源的两种基本工作模式为恒压、恒流&#xff0c;恒压输出时&#xff0c;电压恒定&#xff0c;随着负载发生变动&#xff0c;电流随之改变&#xff0c;当电流到达设定的阈值时&#xff0c;切换到恒流模式&#xff0c;维持目标电流为恒定值。 下面给出直流电源的伏安特性曲…

【数据结构与算法】十大经典排序算法-快速排序

&#x1f31f;个人博客&#xff1a;www.hellocode.top &#x1f3f0;Java知识导航&#xff1a;Java-Navigate &#x1f525;CSDN&#xff1a;HelloCode. &#x1f31e;知乎&#xff1a;HelloCode &#x1f334;掘金&#xff1a;HelloCode ⚡如有问题&#xff0c;欢迎指正&#…

Spring中的循环依赖问题

文章目录 前言一、什么是循环依赖&#xff1f;二、三级缓存三、图解三级缓存总结 前言 本文章将讲解Spring循环依赖的问题 一、什么是循环依赖&#xff1f; 一个或多个对象之间存在直接或间接的依赖关系&#xff0c;这种依赖关系构成一个环形调用&#xff0c;有下面 3 种方式…

根据数组中各值是否满足指定条件决定是否将其按指定规则计算更新numpy.putmask()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 根据数组中各值是否满足指定条件 决定是否将其按指定规则计算更新 numpy.putmask() 选择题 以下程序的运行结果是? import numpy as np xnp.array([1,2,3,4,5]) print("【显示】x:\n&quo…

【Spring】如果你需要使用重试机制,请使用Spring官方的Spring Retry

文章目录 前言Spring Retry的基本使用第一步&#xff0c;引入Spring Retry的jar包第二步&#xff0c;构建一个RetryTemplate类第三步&#xff0c;使用RETRY_TEMPLATE注意事项 拓展方法降级操作重试策略&#xff1a;时间策略重试策略&#xff1a;指定异常策略 前言 Spring Retr…

Vue3 第五节 一些组合式API和其他改变

1.provide和inject 2.响应式数据判断 3.Composition API的优势 4.新的组件 5.其他改变 一.provide和inject 作用&#xff1a;实现祖与后代组件间通信 套路&#xff1a;父组件有一个provide选项来提供数据&#xff0c;后代组件有一个inject选项来开始使用这些数据 &…

centos 7镜像(iso)下载图文教程(超详细)

声明&#xff1a;本教程为本人学习笔记&#xff0c;仅供参考 文章目录 前言一、阿里云镜像站下载centos 7 二、清华源下载centos 7小结 前言 声明&#xff1a;本教程为本人学习笔记&#xff0c;仅供参考 本教程将提供两种方式下载centos 7 系统镜像 1、阿里巴巴开源镜像站 2、…

Unity之ShaderGraph 节点介绍 Procedural节点

程序化 噪声Gradient Noise&#xff08;渐变或柏林噪声&#xff09;Simple Noise&#xff08;简单噪声&#xff09;Voronoi&#xff08;Voronoi 噪声&#xff09; 形状Ellipse&#xff08;椭圆形&#xff09;Polygon&#xff08;正多边形&#xff09;Rectangle&#xff08;矩形…

VM虚拟机和主机互相ping不通,但是ssh能连上,也能访问外网

直接还原默认设置&#xff0c;然后点确定 注意&#xff0c;你还原设置以后ip也会变&#xff0c;ifconfig自己重新看一下

大数据-玩转数据-Sink到Kafka

一、添加Kafka Connector依赖 pom.xml 中添加 <dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-kafka_${scala.binary.version}</artifactId><version>${kafka.version}</version></dependency&g…

IMV4.0

背景内容&#xff1a; 经历了多个版本&#xff0c;基础内容在前面&#xff0c;可以使用之前的基础环境&#xff1a; v1&#xff1a; https://blog.csdn.net/wtt234/article/details/132139454 v2&#xff1a; https://blog.csdn.net/wtt234/article/details/132144907 v3&#…

Docker mysql+nacos单机部署

docker 网络创建 由于nacos需要访问mysql的数据&#xff0c;因此mysql容器和nacos容器之间需要进行通信。容器间通信有很多方式&#xff0c;在这里采用同一网络下的方式进行实现。因此需要创建网络。创建网络的命令如下&#xff1a; docker network create --driver bridge n…