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

简介

什么是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.mfbz.cn/a/65434.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

常用抓包工具

Fiddler Fiddler 是一个很好用的抓包工具&#xff0c;可以用于抓取http/https的数据包&#xff0c;常用于Windows系统的抓包&#xff0c;它有个优势就是免费 Charles Charles是由JAVA开发的&#xff0c;可以运行在window Linux MacOS&#xff0c;但它是收费的&#xff0c;和…

怎么在JMeter中的实现关联

我们一直用的phpwind这个系统做为演示系统, 如果没有配置好的同学, 请快速配置之后接着往下看哦. phpwind发贴时由于随着登陆用户的改变, verifycode是动态变化的, 因此需要用到关联. LoadRunner的关联函数是reg_save_param, Jmeter的关联则是利用后置处理器来完成. 在需要查…

Spark官方调优三部曲之三:其它优化思路

前言 前面介绍了关于spark性能调优两个最重要的点: 数据序列化内存调优这两个方向都进行调优后,如果想进一步继续优化你的程序,可以参考下面的思路。 设置合理的并行度 除非将每个操作的并行级别设置得足够高,否则集群资源不会得到充分利用。Spark根据每个文件的大小自动…

互联网电影购票选座后台管理系统源码开发

搭建一个互联网电影购票选座后台管理系统需要进行以下步骤&#xff1a; 1. 需求分析&#xff1a;首先要明确系统的功能和需求&#xff0c;包括电影列表管理、场次管理、座位管理、订单管理等。 2. 技术选型&#xff1a;选择适合的技术栈进行开发&#xff0c;包括后端开发语言…

kettle之Switch/Case 插件

Switch/Case 插件存在于转换中&#xff0c;用于进行分支选择 插件运行下一步的表输入中执行hivesql需选上下面红色方框的&#xff0c;否则Switch/Case分支不生效!

Node.js |(三)Node.js API:path模块及Node.js 模块化 | 尚硅谷2023版Node.js零基础视频教程

学习视频&#xff1a;尚硅谷2023版Node.js零基础视频教程&#xff0c;nodejs新手到高手 文章目录 &#x1f4da;path模块&#x1f4da;Node.js模块化&#x1f407;介绍&#x1f407;模块暴露数据⭐️模块初体验⭐️暴露数据 &#x1f407;导入文件模块&#x1f407;导入文件夹的…

【二叉树】105. 从前序与中序遍历序列构造二叉树

链接: 105. 从前序与中序遍历序列构造二叉树 先序 能够确定谁是根 中序 知道根之后&#xff0c;能够确定左子树和右子树的范围 例子 根据先序的性质&#xff08;根左右&#xff09;&#xff0c;能够确定根&#xff0c;我们就能够从总序中找出根节点&#xff08;rooti所在…

C语言刷题------(2)

C语言刷题——————&#xff08;2&#xff09; 刷题网站&#xff1a;题库 - 蓝桥云课 (lanqiao.cn) First Question&#xff1a;时间显示 题目描述 小蓝要和朋友合作开发一个时间显示的网站。 在服务器上&#xff0c;朋友已经获取了当前的时间&#xff0c;用一个整数表…

pytest自动化测试框架之断言

前言 断言是完整的测试用例中不可或缺的因素&#xff0c;用例只有加入断言&#xff0c;将实际结果与预期结果进行比对&#xff0c;才能判断它的通过与否。 unittest 框架提供了其特有的断言方式&#xff0c;如&#xff1a;assertEqual、assertTrue、assertIn等&#xff0c;py…

Android 数据库之GreenDAO

GreenDAO 是一款开源的面向 Android 的轻便、快捷的 ORM 框架&#xff0c;将 Java 对象映射到 SQLite 数据库中&#xff0c;我们操作数据库的时候&#xff0c;不再需要编写复杂的 SQL语句&#xff0c; 在性能方面&#xff0c;greenDAO 针对 Android 进行了高度优化&#xff0c;…

Python爬虫的解析(学习于b站尚硅谷)

目录 一、xpath  1.xpath插件的安装  2. xpath的基本使用  &#xff08;1&#xff09;xpath的使用方法与基本语法&#xff08;路径查询、谓词查询、内容查询&#xff08;使用text查看标签内容&#xff09;、属性查询、模糊查询、逻辑运算&#xff09;  &#xff08;2&a…

Apache RocketMQ 命令注入

漏洞简介 RocketMQ 5.1.0及以下版本&#xff0c;在一定条件下&#xff0c;存在远程命令执行风险。RocketMQ的NameServer、Broker、Controller等多个组件外网泄露&#xff0c;缺乏权限验证&#xff0c;攻击者可以利用该漏洞利用更新配置功能以RocketMQ运行的系统用户身份执行命…

Linux6.35 Kubernetes Pod详解

文章目录 计算机系统5G云计算第三章 LINUX Kubernetes Pod详解一、Pod基础概念1.在Kubrenetes集群中Pod有如下两种使用方式2.pause容器使得Pod中的所有容器可以共享两种资源&#xff1a;网络和存储3.kubernetes中的pause容器主要为每个容器提供以下功能4.Kubernetes设计这样的P…

W6100-EVB-PICO作为TCP Client 进行数据回环测试(五)

前言 上一章我们用W6100-EVB-PICO开发板通过DNS解析www.baidu.com&#xff08;百度域名&#xff09;成功得到其IP地址&#xff0c;那么本章我们将用我们的开发板作为客户端去连接服务器&#xff0c;并做数据回环测试&#xff1a;收到服务器发送的数据&#xff0c;并回传给服务器…

svg使用技巧

什么是svg SVG 是一种基于 XML 语法的图像格式&#xff0c;全称是可缩放矢量图&#xff08;Scalable Vector Graphics&#xff09;。其他图像格式都是基于像素处理的&#xff0c;SVG 则是属于对图像的形状描述&#xff0c;所以它本质上是文本文件&#xff0c;体积较小&#xf…

HarmonyOS应用开发的新机遇与挑战

HarmonyOS 4已经于2023年8月4日在HDC2023大会上正式官宣。对广大HarmonyOS开发者而言&#xff0c;这次一次盛大的大会。截至目前&#xff0c;鸿蒙生态设备已达7亿台&#xff0c;HarmonyOS开发者人数超过220万。鸿蒙生态充满着新机遇&#xff0c;也必将带来新的挑战。 HarmonyO…

探析STM32标准库与HAL库之间的差异与优劣

引言&#xff1a; 在嵌入式开发领域&#xff0c;STMicroelectronics的STM32系列芯片广受欢迎。STM32提供了两种主要的软件库&#xff0c;即标准库和HAL库&#xff0c;用于开发各种应用。本文将探讨这两种库之间的差异&#xff0c;比较它们的优劣&#xff0c;并分析在选择库时需…

MFC计算分贝

分贝的一种定义是&#xff0c;表示功率量之比的一种单位&#xff0c;等于功率强度之比的常用对数的10倍&#xff1b; 主要用于度量声音强度&#xff0c;常用dB表示&#xff1b; 其计算&#xff0c;摘录网上一段资料&#xff1b; 声音的分贝值可以通过以下公式计算&#xff1…

用html+javascript打造公文一键排版系统14:为半角和全角字符相互转换功能增加英文字母、阿拉伯数字、标点符号、空格选项

一、实际工作中需要对转换选项细化内容 在昨天我们实现了最简单的半角字符和全角字符相互转换功能&#xff0c;就是将英文字母、阿拉伯数字、标点符号、空格全部进行转换。 在实际工作中&#xff0c;我们有时只想英文字母、阿拉伯数字、标点符号、空格之中的一两类进行转换&a…

TDengine + Telegraf + Grafana 实现图形化服务器状态监控

TDengine Telegraf Grafana 实现图形化服务器状态监控 技术栈环境搭建安装tdenginue下载安装包解压文件运行安装文件启动td运行 taosAdapter 安装Telegraf添加yum源安装生成配置文件修改配置文件启动telegraf 安装Grafana直接yum安装安装td数据源配置启动Grafana配置数据源导…
最新文章