• vue基础知识和原理(一)


    🎗 接下篇

    1.1 Vue简介

    • 让Vue工作,就须创建一个Vue实例,且要传入一个配置对象
    • demo容器里的代码符合html规范,只不过混入了一些特殊的Vue语法
    • demo容器里的代码被称为【Vue模板】
    • Vue实例和容器是一一对应的
    • 真实开发中只有一个Vue实例,并且会配合着组件一起使用
    • {{xxx}}是Vue的语法:插值表达式,{{xxx}}可以读取到data中的所有属性
    • 一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新(Vue实现的响应式)
    
    <div id="demo">
    	<h1>Hello,{{name.toUpperCase()}},{{address}}h1>
    div>
    
    <script type="text/javascript" >
    	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
    
    	//创建Vue实例
    	new Vue({
    		el:'#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。
    		data:{ //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。
    			name:'hello,world',
    			address:'北京'
    		}
    	});
    
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    1.2 模板语法

    (1)插值语法

    功能:用于解析标签体内容

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

    (2)指令语法:

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

    举例:v-bind:href=“xxx” 或 简写为 :href=“xxx”,xxx同样要写js表达式,且可以直接读取到data中的所有属性

    <div id="root">
    	<h1>插值语法h1>
    	<h3>你好,{{name}}h3>
    	<hr/>
    	<h1>指令语法h1>
        
    	<a :href="school.url.toUpperCase()" x="hello">点我去{{school.name}}学习1a>
    	<a :href="school.url" x="hello">点我去{{school.name}}学习2a>
    div>
    
    <script>
        new Vue({
    		el:'#root',
    		data:{
    			name:'jack',
    			school:{
    				name:'百度',
    				url:'http://www.baidu.com',
    			}
            }
    	})
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    1.3 数据绑定

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

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

    1.双向绑定一般都应用在表单类元素上(如:input、select等)

    2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值

    <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/>
    div>
    
    <script>
        new Vue({
    		el:'#root',
    		data:{
    			name:'jack',
            }
    	})
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    1.4 el与data的两种写法

    (1)el有2种写法

    • new Vue时候配置el属性

    • 先创建Vue实例,随后再通过vm.$mount(‘#root’)指定el的值

    <script>
       	// 第一种 
    	const vm = new Vue({
    		el:'#root',
    		data:{
    			name:'jack',
            }
    	})
        
        // 第二种
        vm.$mount('#root')
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    (2)data有2种写法

    • 对象式

    • 函数式

      在组件中,data必须使用函数式

    <script>
        new Vue({
    		el:'#root',
            // 第一种
    		data:{
    			name:'jack',
            }
            
            // 第二种
            data() {
            	return {
                    name: 'jack'
                }
        	}
    	})
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    1.5 Vue中的MVVM

    • M:模型(Model) :data中的数据
    • V:视图(View) :模板代码
    • VM:视图模型(ViewModel):Vue实例

    1.6 数据代理

    了解数据代理需要js的一些知识:Object.defineProperty(),属性标志,属性描述符,getter,setter

    属性标志:

    对象属性(properties),除 value 外,还有三个特殊的特性(attributes),也就是所谓的“标志”

    • writable — 如果为 true,则值可以被修改,否则它是只可读的
    • enumerable — 如果为 true,则表示是可以遍历的,可以在for… .in Object.keys()中遍历出来
    • configurable — 如果为 true,则此属性可以被删除,这些特性也可以被修改,否则不可以

    Object.getOwnPropertyDescriptor(obj, propertyName)

    这个方法是查询有关属性的完整信息 obj是对象, propertyName是属性名

    let user = {
      name: "John"
    };
    
    let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
    
    
    console.log(descriptor)
    
    /* 属性描述符:
    {
      "value": "John",
      "writable": true,
      "enumerable": true,
      "configurable": true
    }
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Object.defineProperty(obj, prop, descriptor)

    obj:要定义属性的对象。

    prop:要定义或修改的属性的名称

    descriptor:要定义或修改的属性描述符

    let user = {
      name: "John"
    };
    
    Object.defineProperty(user, "name", {
      writable: false
    });
    
    user.name = "Pete";
    
    // 打印后还是显示 'John',无法修改name值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其他的属性标志就不演示了,接下来看重点:访问器属性。

    访问器属性:

    本质上是用于获取和设置值的函数,但从外部代码来看就像常规属性。

    访问器属性由 “getter” 和 “setter” 方法表示。在对象字面量中,它们用 getset 表示:

    let obj = {
        get name() {
            // 当读取 obj.propName 时,getter 起作用
        },
        set name() {
            // 当执行 obj.name = value 操作时,setter 起作用
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    更复杂一点的使用

    let user = {
    	surname: 'gao',
        name: 'han'
        
        get fullName() {
            return this.name + this.surname;
        }
    }
    
    console.log(user.fullName)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    从外表看,访问器属性看起来就像一个普通属性。这就是访问器属性的设计思想。我们不以函数的方式 调用 user.fullName,我们正常 读取 它:getter 在幕后运行。

    截至目前,fullName 只有一个 getter。如果我们尝试赋值操作 user.fullName=,将会出现错误:

    user.fullName = "Test"; // Error(属性只有一个 getter)
    
    • 1

    user.fullName 添加一个 setter 来修复它:

    let user = {
    	surname: 'gao',
        name: 'han'
        
        get fullName() {
            return this.name + ' ' + this.surname;
        }
    
    	set fullName(value) {
            // 这个用到了新语法 结构赋值
            [this.surname, this.name] = value.split(' ');
        }
    }
    
    user.fullName = 'Li Hua'
    
    console.log(user.name);
    console.log(user.surname);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    数据代理

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

    例:
    let obj = {
        x: 100
    }
    
    let obj2 = {
        y: 200
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    需求:我们想要访问 obj 中的 x 的值,但我们最好不要直接去访问 obj ,而是想要通过 obj2 这个代理对象去访问。

    这时候就可以用上 Object.defineProperty(),给 obj2 添加上访问器属性(也就是getter和setter)

    代码

    let obj = {
        x: 100
    }
    
    let obj2 = {
        y: 200
    }
    
    Object.defineProperty(obj2, 'x', {
        get() {
            return obj.x;
        },
        set(value) {
            obj.x = value;
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Vue中的数据代理

    • Vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)
    • Vue中数据代理的好处:更加方便的操作data中的数据
    • 基本原理:
      • 通过Object.defineProperty()把data对象中所有属性添加到vm上。
      • 为每一个添加到vm上的属性,都指定一个getter/setter。
      • 在getter/setter内部去操作(读/写)data中对应的属性。
    
    <div id="root">
    	<h2>学校名称:{{name}}h2>
    	<h2>学校地址:{{address}}h2>
    div>
    
    <script>
    	const vm = new Vue({
            el: '#root',
            data: {
                name: '浙江师范大学',
                address: '浙江金华'
            }
        })
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    我们在控制台打印 new 出来的 vm

    在这里插入图片描述

    可以看到,写在配置项中的 data 数据被 绑定到了 vm 对象上,我先来讲结果,是 Vue 将 _data 中的 name,address 数据 代理到 vm 本身上。

    🙄🙄🙄

    先来解释下_data 是啥, _data 就是 vm 身上的 _data 属性,就是下图那个

    在这里插入图片描述

    这个 _data 是从哪来的?

    <script>
        
    	const vm = new Vue({
            el: '#root',
            // 我们在Vue 初始化的配置项中写了 data 属性。
            data: {
                name: '浙江师范大学',
                address: '浙江金华'
            }
        })
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    new Vue 时, Vue 通过一系列处理, 将匹配项上的 data 数据绑定到了 _data 这个属性上,并对这个属性进行了处理(数据劫持),但这个属性就是来源于配置项中的 data,我们可以来验证一下。

    <script>
        
        let data1 = {
            name: '浙江师范大学',
            address: '浙江金华'
        }
        
    	const vm = new Vue({
            el: '#root',
            // 我们在Vue 初始化的配置项中写了 data 属性。
            data: data1
        })
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    这一切都是通过 Object.defineProperty() 来完成的,我来模拟一下这个过程

    Object.defineProperty(vm, 'name', {
        get() {
            return vm._data.name;
        },
        set(value) {
            vm._data.name = value
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在插值语法中,{{ name }} 取到的值就相当于 {{ vm.name }},不用数据代理的话,在插值语法就要这样去写了。

    1.7 事件处理

    事件的基本使用:

    • 使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名
    • 事件的回调需要配置在methods对象中,最终会在vm上
    • methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象
    
    <div id="root">
        <h2>欢迎来到{{name}}学习h2>
        
        <button @click="showInfo1">点我提示信息1(不传参)button>
        
        <button @click="showInfo2($event,66)">点我提示信息2(传参)button>
    div>
    
    <script>
    	const vm = new Vue({
            el:'#root',
            data:{
                name:'vue',
            },
            methods:{
                // 如果vue模板没有写event,会自动传 event 给函数
                showInfo1(event){
                    // console.log(event.target.innerText)
                    // console.log(this) //此处的this是vm
                    alert('同学你好!')
                },
                showInfo2(event,number){
                    console.log(event,number)
                    // console.log(event.target.innerText)
                    // console.log(this) //此处的this是vm
                    alert('同学你好!!')
                }
            }
    	});
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    Vue中的事件修饰符

    • prevent:阻止默认事件(常用)
    • stop:阻止事件冒泡(常用)
    • once:事件只触发一次(常用)
    <div id="root">
        <h2>欢迎来到{{name}}学习h2>
        
    	<a href="http://www.baidu.com" @click.prevent="showInfo">点我提示信息a>
        
        <div class="demo1" @click="showInfo">
            <button @click.stop="showInfo">点我提示信息button>
            
            
        div>
        
        <button @click.once="showInfo">点我提示信息button>
    div>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    数学小抄: 概率角度推导Kalman Filter
    Vue-路由嵌套
    AQS之ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue阻塞队列特性及源码分析
    讲讲如何用IDEA开发java项目——本文来自AI创作助手
    笔试选择题-图
    关于前端传值,springboot后端的参数处理方式汇总
    【FFmpeg】AVFrame结构体
    猿创征文|Redis新增数据类型
    当技术人成长为 CEO,应该修改哪些“Bug”?
    【赠书活动】AI时代项目经理必备技能
  • 原文地址:https://blog.csdn.net/m0_61016904/article/details/126212889