vue2(1)

发布于:2023-01-20 ⋅ 阅读:(325) ⋅ 点赞:(0)

目录

vue简介

初始Vue

 模板语法

数据绑定

data与el的2种写法

MVVM模型

Object.defineProperty方法

数据代理

事件的基本使用

事件修饰符

键盘事件

姓名案例

计算属性

计算属性简写


vue简介

定义

一套用于构建用户界面的`渐进式JS框架`

 

 特点

  1. 采用`组件化`模式,提高代码复用率,且让代码更好维护
  2. 声明式编码,让编码无需直接操作DOM,提高开发效率
  3. 使用`虚拟DOM+优秀的Diff算法`,尽量复用DOM节点

 要掌握的JS基础知识

ES6语法规范,ES6模块化,包管理器,原型、原型链,数组常用方法,axios,promise

初始Vue

  1. 想让Vue工作,就必须创建一个`Vue实例`,且要传入一个配置对象
  2. root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法
  3. root容器里的代码被称为vue模板
  4. Vue实例和容器是一一对应的
  5. 真实开发中只用一个Vue实例,并且会配合着组件一起使用
  6. {{XXX}}中的XXX要写js表达式,且XXX可以自动读取到data中的所有属性
  7. 一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    
</head>
<body>
    <div id="root">
        <h1>hello,{{name}}</h1>
    </div>
    <script>
        Vue.config.productionTip=false;//阻止vue在启动生成生产提示
        new Vue({
            el:'#root',//el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串
            data:{//data用于存储数据,数据供el所指定的容器去只用,值暂时先写成一个对象
                
                name:'尚硅谷'
            }
        })
    </script>
    
</body>
</html>

注意区分:js表达式和js代码(语句)

1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方

 2.js代码(语句)

 模板语法

两大类

1.插值语法

  • 功能:用于`解析标签体内容`
  • 写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性

2.指令语法

  • 功能:用于`解析标签`(包括:标签属性,标签体内容,绑定事件。。。)
  • 备注:Vue中有很多的指令,且形式都是:v-???
<!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="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    
</head>
<body>
    <div id="root">
        <h1>插值语法</h1>
        <h3>你好,{{name}}</h3>
        <hr>
        <h1>指令语法</h1>
        <a :href="school.url.toUpperCase()" x="hello">点我去{{school.name}}学习1</a>
        <a v-bind:href="school.url">点我去{{school.name}}学习2</a>
    </div>
    <script>
        Vue.config.productionTip=false
        new Vue({
            el:'#root',
            data:{
                name:'jack',
                school:{
                    name:'shangguigu',
                    url:'http://www.atguigu.com',
                }
            }
        })
    </script>
</body>
</html>

数据绑定

2种方式

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

备注:

  1. 双向绑定一般都应用在表单类元素上(如:input、select等)
  2. `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="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

</head>
<body>
    <div id="root">
        <!-- 普通写法 -->
        单向数据绑定:<input type="text" v-bind:value="name"><br>
        双向数据绑定:<input type="text" v-model:value="name"><br>
        <!-- 简写 -->
        单向数据绑定:<input type="text" :value="name"><br>
        双向数据绑定:<input type="text" v-model="name"><br>

        <hr>
        <!-- <h2 v-model:x="name">hello</h2> -->
    </div>
</body>
<script>
    Vue.config.productionTip=false//阻止vue在启动时生成生产提示
    new Vue({
        el:'#root',
        data:{
            name:'aaa'
        }

    })

</script>
</html>

data与el的2种写法

1.`el`

  1. new Vue时配置el属性
  2. 先创建Vue实例,随后再通过`vm.$mount('#root')`指定el的值

2.`data`

  1. 对象式
  2. 函数式

如何选择:目前都可以,以后学习组件时,data必须用函数式,否则会报错

3.一个重要的原则

  • 由Vue管理的函数,一定不要箭头函数,一旦写了箭头函数,this就不再是Vue实例了
<!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="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

</head>
<body>
    <div id="root">
        <h1>你好,{{name}}</h1>
    </div>
    
</body>
<script>
    Vue.config.productionTip=false//阻止vue在启动时生成生产提示
    const v=new Vue({
        el:'#root',//第一种写法
        data:{
            name:'尚硅谷'
        }
    })
    console.log(v);
    v.$mount('#root')//第二种写法

    //data的两种写法
    new Vue({
        el:'#root',
        // data:{
        //     name:'shang'
        // }
        // 第二种写法
        data(){//data:function(){}
            name:'shang'
        }
    })


</script>
</html>

MVVM模型

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

`data Bindings`:数据保存在Model中,要将数据表现在页面中,得将数据通过数据绑定传到View上

`DOM Listeners`:DOM监听,当在View中修改数据的时候,Model中的数据也会发生改变

 观察发现:

  1. data中所有的属性,最后都出现在了vm身上
  2. vm身上的属性及Vue原型上所有属性,在Vue模板中都可以直接使用

Object.defineProperty方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

</head>
<body>
    <script>
        let number=18
        let person={
            name:'张三',
            sex:'男'
        }

        Object.defineProperty(person,'age',{
            value:18,
            enumerable:true,//控制属性是否可以枚举,默认值是false
            writable:true,//控制属性是否可以被修改,默认值是false
            configurable:true,//控制属性是否可以被删除,默认值是false

            // 当有人读取person的age属性,get函数(getter)
            // 就会被调用,且返回值就是age的值
            get(){
                console.log('有人读取age属性了')
                return number
            },

            set(value){
                console.log('有人修改了age属性,且值是',value);
                number=value
            }

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

数据代理

通过一个对象代理对另一个对象中属性的操作(读/写)

<script>
        let obj={x:100}
        let obj2={y:200}

        Object.defineProperty(obj2,'x',{
            get(){
                return obj.x
            },
            set(value){
                obj.x=value
            }
        })
    </script>

 1.Vue中的数据代理

  • 通过vm对象来`代理data对象中属性`的操作(读/写)

2.Vue中的数据代理的好处

  • 更加方便的操作data中的数据

3.基本原理

  • 通过`Object.defineProperty()`把data对象中所有属性添加到vm中,为每一个添加到vm上的属性,都指定一个`getter/setter`内部去操作(读/写)data中对应的属性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

</head>
<body>
    <div id="root">
        <h1>学校名称:{{name}}</h1>
        <h1>学校地址:{{address}}</h1>
    </div>
</body>
<script>
    Vue.config.productionTip=false//阻止vue在启动时生成生产提示
    const vm=new Vue({
        el:'#root',
        data:{
            name:'atuigu',
            address:'北京'
        }

    })

</script>
</html>

事件的基本使用

  1. 使用`v-on:xxx`或`@xxx`绑定事件,其中xxx是事件名
  2. 事件是回调需要配置在methods对象中,最终会在vm中
  3. methods中配置的函数,不要用箭头函数!否则this就不是vm了
  4. `@click="demo"`和`@click="demo(e)"`效果一致,但是后者可以传参
<!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="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

</head>
<body>
    <div id="root">
        <h1>欢迎来到{{name}}</h1>
        <!-- <button v-on:click="showInfo">点我学习一下</button> -->
        <!-- 简写 -->
        <button @click="showInfo">点我学习一下1(不传参)</button>
        <button @click="showInfo2($event,666)">点我学习一下2(传参)</button>

    </div>
</body>
<script>
    Vue.config.productionTip=false//阻止vue在启动时生成生产提示
    const vm=new Vue({
        el:'#root',
        data:{
            name:'atguigu'
        },
        methods:{
            showInfo(event){
                // alert('同学你好')
                // console.log(a,b,c,d)
                // console.log(event.target.innerText);
                // console.log(event.target);
                console.log(this);//vm
                
            },
            showInfo2(event,number){
                alert('同学你好!!')
                console.log(number,event);
                // console.log(a,b,c,d)
                // console.log(event.target.innerText);
                // console.log(event.target);
                // console.log(this);//vm
                
            }
        }

    })

</script>
</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 src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

    <style>
        *{
            margin-top: 20px;

        }
        .demo1{
            height: 50px;
            background-color: #bfa;
        }
        .box1{
            height: 50px;
            background-color: #bfa;
        }
        .box2{
            height: 50px;
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <div id="root">
        <h2>欢迎来到{{name}}</h2>
        <!-- 组织默认事件(常见) -->
        <a href="http://www.atguigu.com" @click.prevent="showInfo">点我提示信息</a>
        
        <!-- 阻止事件冒泡(常见) -->
        <div class="demo1" @click="showInfo">
            <button @click.stop="showInfo">点我提示信息</button>
        </div>

        <!-- 事件只触发一次(常见) -->
        <div>
            <button @click.once="showInfo">点我提示信息</button>
        </div>
        
        <!-- 使用事件的捕获模式 -->
        <div class="box1" @click.capture="showMsg(1)">
            div1
            <div class="box2" @click="showMsg(2)">
                div2
            </div>
        </div>

        <!-- 只有event.target是当前操作的元素时才触发事件 -->
        <div class="demo1" @click.self="showInfo">
            <button @click.once="showInfo">点我提示信息</button>
        </div>

        <!-- 事件的默认行为立即执行,无需等待事件回调执行完毕 -->
        <ul @wheel.passive="demo" class="list">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
    </div>
</body>
<script>
    Vue.config.productionTip=false//阻止vue在启动时生成生产提示
    new Vue({
        el:'#root',
        data:{
            name:'guigu'
        },
        methods:{
            showInfo(e){
                alert('你好')
                // console.log(e.target);
            },
            showMsg(msg){
                console.log(msg);
            }
        }

    })

</script>
</html>

键盘事件

1.

Vue中常用的按键别名
回车 enter
删除 delete
退出 esc
空格 space
换行 tab
up
down
left
right

2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注定要转为kebab-case(短横线命名)

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

  1. 配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
  2. 配合keydown使用:正常触发事件

4.也可以使用`keyCode`去指定具体的按键(不推荐)

5.`Vue.config.keyCodes.自定义键名=键名`,可以去指定按键别名

<!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="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

</head>
<body>
    <div id="root">
        <h2>欢迎来到{{name}}</h2>
        <input type="text" placeholder="按下回车提示输入" @keyup.13 ="showInfo">
    </div>
</body>
<script>
    Vue.config.productionTip=false//阻止vue在启动时生成生产提示
    // Vue.config.keyCodes.huiche=13//定义了一个别名按键
    new Vue({
        el:'#root',
        data:{
            name:'花京院'
        },
        methods:{
            showInfo(e){
                // if(e.keyCode!==13) return
                console.log(e.key,e.keyCode);
                console.log(e.target.value);
            }
        }


    })

</script>
</html>

注意:

1.修饰符可以连续写

<!-- 阻止事件冒泡(常见) -->
        <div class="demo1" @click="showInfo">
            <a href="http://www.atguigu.com" @click.stop.prevent="showInfo">点我提示信息</a>
        </div>

2.连按两个键

<div id="root">
        <h2>欢迎来到{{name}}</h2>
        <input type="text" placeholder="按下回车提示输入" @keyup.ctrl.y ="showInfo">
    </div>

姓名案例

1.插值语法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

</head>
<body>
    <div id="root">
        姓:<input type="text" v-model:value="firstname"><br><br>
        <!-- 简写 -->
        名:<input type="text" v-model="lastname"><br><br>
        姓名:<span>{{firstname.slice(0,3)}}-{{lastname}}</span>
    </div>
</body>
<script>
    Vue.config.productionTip=false//阻止vue在启动时生成生产提示
    new Vue({
        el:'#root',
        data:{
            firstname:'张',
            lastname:'三'
        }

    })

</script>
</html>

2.methods实现

当数据发生改变,Vue会重新调用,重新解析

<!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="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

</head>
<body>
    <div id="root">
        姓:<input type="text" v-model:value="firstname"><br><br>
        <!-- 简写 -->
        名:<input type="text" v-model="lastname"><br><br>
        姓名:<span>{{fullname()}}</span>
    </div>
</body>
<script>
    Vue.config.productionTip=false//阻止vue在启动时生成生产提示
    new Vue({
        el:'#root',
        data:{
            firstname:'张',
            lastname:'三'
        },
        methods:{
            fullname(){
                return this.firstname+'-'+this.lastname
            }
        }

    })

</script>
</html>

计算属性

1.定义:要用的属性不存在,要通过已有属性计算得来

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

3.get什么时候调用?

  1. 初次读取fullName
  2. 所依赖的数据发生变化

4.get的作用:当有人读取fullName时,get就会被调用,且返回值就作为fullName的值

5.什么时候调用set?

  • 当fullName被修改

6.优势:与methods实现相比,内部有缓存机制(复用),效率更高,雕塑方便

5.备注

  1. 计算属性最终会出现再vm中,直接读取使用即可
  2. 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算式依赖的数据发生改变
<!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="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

</head>
<body>
    <div id="root">
        姓:<input type="text" v-model:value="firstname"><br><br>
        <!-- 简写 -->
        名:<input type="text" v-model="lastname"><br><br>
        姓名:<span>{{fullName}}</span><br><br>
        姓名:<span>{{fullName}}</span><br><br>
        姓名:<span>{{fullName}}</span><br><br>
        姓名:<span>{{fullName}}</span><br><br>
    </div>
</body>
<script>
    Vue.config.productionTip=false//阻止vue在启动时生成生产提示
    let a=1
    const vm=new Vue({
        el:'#root',
        data:{
            firstname:'张',
            lastname:'三',
            x:'你好'
        },
        methods:{
            demo(){

            }
        },
        computed:{
            fullName:{
                get(){
                    console.log('get被调用了');
                    // console.log(this);//vue
                    return this.firstname+'-'+this.lastname
                },
                set(value){
                    console.log('set',value);
                    const arr=value.split('-')
                    this.firstname=arr[0]
                    this.lastname=arr[1]
                }
            }
        }
    })

</script>
</html>

 

计算属性简写

只考虑读取不考虑修改

computed:{
            fullName(){
                console.log('get被调用了');
                return this.firstname+'-'+this.lastname
            }
        }

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到