vue知识回顾总结

vue知识回顾总结,第1张

1.数据代理(2022.5.1) 1.1数据代理 通过一个对象代理对另一个对象中属性的 *** 作(读写)**
   <script>
       
        let obj = {
            x: 100
        };
        let obj2 = {
            y: 200
        }
        Object.defineProperty(obj2, 'x', {
            //当有人访问obj2.x属性,调用get() getter函数,且返回obj.x的值
            get() {
                console.log('我跟随obj.x 的修改');
                return obj.x
            },
            //当有人修改obj2.x属性,调用set() setter函数,且返回value的值
            set(value) {
                console.log('我修改了obj2.x的值,并返回给obj.x');
                //obj.x = value;
            }
        })
1.2 Object.defineProperty()
  • Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
  • 参数 Object.defineProperty(obj, prop, descriptor)
    1.obj 要定义属性的对象
    2.prop 要定义或修改的属性的名称
    3.descriptor 要定义或修改的属性描述符(配置项)
  • 返回值 传递给方法的对象
<script>
        let number = 18;
        let person = {
                name: '尚硅谷',
                sex: '男',
                //age: 18
            }
            //Object.defineProperty 向对象添加属性
            // object 属性名 {value}
        Object.defineProperty(person, 'age', {
                //value: 18,
                //enumerable: true, //控制属性是否可以被枚举(遍历),默认是false
                //writable: true, //控制属性是否可以被修改,默认是false
                //configurable: true, //控制属性是否可以被删除,默认是false

                //当有人访问person.age属性,调用get() getter函数,且返回age的值
                get: function() {
                    console.log('有人读取age属性了');
                    return number
                },

                //当有人修改person.age属性,调用set() setter函数,且返回value的值
                set(value) {
                    console.log('有人要修改age的值,且值是' + value);
                    number = value;

                }
            })
            /*    for (let k in person) {
                    console.log(person[k]);
                }*/
    </script>
1.3vue中的数据代理

Vue实例化的时候vm_data = option.data
数据代理时 name adderss 代理 vm_data
1.Vue中的数据代理:

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

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

    更加方便的 *** 作data中的数据

3.基本原理:

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

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

vm_data=option.data

  <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                name: '尚硅谷',
                adderss: '北京科技园'
            },
        });
    </script>

2022.05.03-08点34分

2.事件处理
  • 使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名
  • 事件的回调需要配置在methods对象中,最终会在vm上
  • methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象
  • 不写参数,默认传递的是event; showInfo2($event,66),此时第一个参数是事件对象,第二个用户自定义
<body>
    <div class="root">

        <!-- <button v-on:click="showInfo">点击我提示信息(不传参)</button>-->
        <!-- 简写 -->
        <button @click="showInfo">点我提示信息</button>
        <!-- <button v-on:click="showInfo2($event,66)">点击我提示信息2</button> -->
        <button @click="showInfo2($event,66)">点击我提示信息2(传参)</button>
    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                name: '',
            },
            //回调函数
            methods: {
                showInfo(event) {
                    alert('你好,vue');
                },
                showInfo2(event, number) {
                    console.log(number);
                    alert('你好,vue22');
                },

            }

        });
    </script>

Vue中的事件修饰符

prevent:阻止默认事件(常用)
stop:阻止事件冒泡(常用)
once:事件只触发一次(常用)

<body>
    <div class="root">
        <!-- 事件修饰符 -->
        <!-- 1.阻止事件的默认行为 -->
        <a href="www.baidu.com" @click.prevent="showInfo">点击我</a>
        <!-- 2.阻止事件冒泡 -->

        <div class="demo" @click="showInfo2">
            <div class="demo1" @click.stop="showInfo2"></div>
        </div>
        <!-- 事件可以连写 -->
        <!-- <div class="demo1" @click.prevent.stop="showInfo2"></div> -->
        <!-- 3.事件只触发一次 -->
        <button @click.once="showInfo3">点击我</button>
    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                name: '',
            },
            methods: {
                showInfo() {
                    alert('阻止事件的默认行为');
                },
                showInfo2() {
                    alert('阻止事件冒泡');
                },
                showInfo3() {
                    alert('事件值触发一次');
                }
            }
        });
    </script>
</body>

键盘事件

<body>
    <!-- 键盘事件语法糖:@keydown,@keyup

        Vue中常用的按键别名:

        回车 => enter
        删除 => delete
        退出 => esc
        空格 => space
        换行 => tab (特殊,必须配合keydown去使用)
        @keydown.keycode(自定义配置按键 不推荐) 
         Vue.config.keyCodes.键名 = 键码,可以定制按键
        可以组合按键enter.x 触发事件-->
    <div class="root">
        <label for="">欢迎来到{{name}}学习</label><br>
        <input type="text" @keydown.enter="showInfo">
    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                name: '尚硅谷',
            },
            methods: {
                showInfo(e) {
                    console.log(e.target.value);
                   
                }
            }
        });
    </script>
</body>
3.计算属性
        计算属性
        定义: 要用的属性不存在, 要通过已有属性计算得来
        原理: 底层借助了Objcet.defineProperty方法提供的getter和setter
   		 get函数什么时候执行?(1).初次读取时会执行一次(2).当依赖的数据发生改变时会被再次调用
   		   methods 每次读取都会调用一次,计算属性会把fullName缓存到内部,只要值不发生改变,就不会调用get
    	 优势: 与methods实现相比, 内部有缓存机制( 复用), 效率更高, 调试方便
        备注:
 	   计算属性最终会出现在vm上, 直接读取使用即可
  		如果计算属性要被修改, 那必须写set函数去响应修改, 且set中要引起计算时依赖的数据发生改变
<body>

    <div class="root">
        姓:<input type="text" v-model:value='firstName'> <br> 名:
        <input type="text" v-model="lastName"> <br> 姓名:
        <!-- 插值语法实现姓名案例 -->
        <!-- <span>{{firstName.slice(0,3)}}- {{lastName}}</span> -->

        <!-- 用回调函数实现姓名案例 -->

        <!-- 计算属性实现姓名案例 -->
        <!-- vm.fullName.get()会报错,与methods中函数不同 -->
        <span>{{fullName}}</span><br>
        <!-- <span>{{fullName}}</span><br>
        <span>{{fullName}}</span><br>
        <span>{{fullName}}</span><br>
        <span>{{fullName}}</span><br> -->



    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                firstName: '张',
                lastName: '三',
            },
            /*methods: {
                fullName() {
                    console.log('methods被调用了');
                    return this.firstName + '-' + this.lastName
                }
            }*/

            //计算属性
            // 定义: 要用的属性不存在, 要通过已有属性计算得来
            // 原理: 底层借助了Objcet.defineProperty方法提供的getter和setter
            // get函数什么时候执行?(1).初次读取时会执行一次(2).当依赖的数据发生改变时会被再次调用
            // 优势: 与methods实现相比, 内部有缓存机制( 复用), 效率更高, 调试方便
            // methods 每次读取都会调用一次,计算属性会把fullName缓存到内部,只要值不发生改变,就不会调用get
            // 备注:
            // 计算属性最终会出现在vm上, 直接读取使用即可
            // 如果计算属性要被修改, 那必须写set函数去响应修改, 且set中要引起计算时依赖的数据发生改变

            computed: {
                fullName: {
                    get() {
                        console.log('get被调用了');
                        //此时this 经过vue处理指向vm
                        return this.firstName + '-' + this.lastName
                    },
                    //此时的参数是修改后的新值
                    set(value) {
                        console.log('set', value)
                         //split 按照间隔符- 将字符串分成两个数组
                        const arr = value.split('-')
                        this.firstName = arr[0]
                        this.lastName = arr[1]

                    }
                }
            }
        });
    </script>
    </div>
</body>

4.监视属性
  • 用计算属性实现的监视属性也可以实现
<body>
    <div class="root">
        <span>今天的天气好{{Info}}</span><br>

        <button @click="changeWeather">点击切换天气</button>
    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                isHOT: true,
            },
            methods: {
                changeWeather() {
                    this.isHOT = !this.isHOT;
                    //console.log(this.isHOT);
                }
            },
            computed: {

                Info() {
                    return this.isHOT ? '炎热' : '凉快'
                }

            },
            //监视某一个属性值的变化 计算属性也可以监视
            //handler什么时候调用?当isHot发生改变时。
            watch: {
                isHOT: {
                    //初始化时执行一次handler 默认值是false
                    immediate: true,
                    handler(newvalue, oldvalue) {
                        console.log(newvalue, oldvalue);
                    }
                }
            }




        });

        //监视属性的第二种写法 开始不确定监视的属性
        /* vm.$watch('isHot', {
             immediate: true,
             handler(newvalue, oldvalue) {
                 console.log(newvalue, oldvalue);
             }
         })*/
    </script>
5.绑定class样式
<style>
        .basic {
            width: 200px;
            height: 100px;
            border: 1px solid black;
        }
        
        .happy {
            background-color: pink;
        }
        
        .sad {
            background-color: green;
        }
        
        .normal {
            background-color: blue;
        }
        
        .atguigu1 {
            background-color: pink;
        }
        
        .atguigu2 {
            border-radius: 30px;
        }
        
        .atguigu3 {
            border: 10px solid skyblue;
        }
    </style>
</head>

<body>
    <div class="root">
        <!-- 绑定class样式--字符串写法,适用于class的类名不确定,需要动态指定 -->
        <!-- <div class="basic" :class="mood" @click="changeMood">{{name}}</div><br><br> -->


        <!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定  -->
        <!-- 可以使用数组方法 arr.shift arr.push 增加或者删除样式 -->
        <div class="basic" :class="moodArr">{{name}}</div><br><br>

        <!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 -->
        <div class="basic" :class="moodObj">{{name}}</div><br><br>
    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                name: '尚硅谷',
                mood: 'normal',
                moodArr: ['atguigu1', 'atguigu2', 'atguigu3'],
                moodObj: {
                    atguigu1: false,
                    atguigu2: false,
                    atguigu3: true
                }
            },
            methods: {
                changeMood() {
                    const MoodArr = ['happy', 'sad', 'normal'];
                    const index = Math.floor(Math.random() * 3);
                    console.log(index);
                    this.mood = this.MoodArr[index];

                },

            },
            watch: {}
        });
    </script>
</body>
6.条件渲染 1.1 v-if

写法:

(1).v-if=“表达式”

(2).v-else-if=“表达式”

(3).v-else=“表达式”

  • 适用于:切换频率较低的场景

  • 特点:不展示的DOM元素直接被移除

  • 注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”

  <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>哈哈</div>
1.2 v-show
  • 写法:v-show=“表达式”
  • 适用于:切换频率较高的场景
  • 特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉(display:none)
    <button @click="n++">点击让n++</button>
    <button @click="n--">点击让n--</button>
    <div class="test" v-show="n==2">欢迎来到{{name}}</div>
1.3 列表渲染 v-for指令
  • 用于展示列表数据
  • 语法:v-for=“(item, index) in xxx” :key=“yyy”
  • 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
  • v-for 的两个参数 一个是索引值 一个是索引号
<body>
    <div class="root">
     
        <!-- v-for 的两个参数 一个是索引值 一个是索引号 -->
        <!-- 遍历数组 -->
        <ul>{{name}}
            <li v-for="(p,index) in persons" :key="index">{{p.name}}--{{index}}</li>
        </ul>


        <!-- 遍历对象 第一个参数是value 第二个是键码 key -->
        <ul>

            <li v-for="(car,key) in cars">{{key}}--{{car}}</li>
        </ul>
    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                name: '人员列表',
                persons: [{
                    name: '张三',
                    id: 001,
                    age: 18
                }, {
                    name: '历史',
                    id: 002,
                    age: 19
                }, {
                    name: '王五',
                    id: 003,
                    age: 20
                }],
                cars: {
                    name: '奥迪A8',
                    price: '70万',
                    color: '黑色'
                },
                str: 'hello'
            },
            methods: {},
            watch: {}
        });
    </script>
</body>
虚拟DOM中key的作用
  • key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:

  • 旧虚拟DOM中找到了与新虚拟DOM相同的key:

  • ①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!

  • ②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。

  • 旧虚拟DOM中未找到与新虚拟DOM相同的key

  • 创建新的真实DOM,随后渲染到到页面。

用index作为key可能会引发的问题:
  • 若对数据进行:逆序添加、逆序删除等破坏顺序 *** 作:

  • 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。

- `<!-- 准备好一个容器-->
<div id="root">
    <!-- 遍历数组 -->
    <h2>人员列表(遍历数组)</h2>
    <button @click.once="add">添加一个老刘</button>
    <ul>
        <li v-for="(p,index) of persons" :key="index">
            {{p.name}}-{{p.age}}
            <input type="text">
        </li>
    </ul>
</div>

<script type="text/javascript">
	Vue.config.productionTip = false

	new Vue({
		el: '#root',
		data: {
			persons: [
				{ id: '001', name: '张三', age: 18 },
				{ id: '002', name: '李四', age: 19 },
				{ id: '003', name: '王五', age: 20 }
			]
		},
		methods: {
			add() {
				const p = { id: '004', name: '老刘', age: 40 }
				this.persons.unshift(p)
			}
		},
	});
</script>

初始数据

persons: [
{ id: ‘001’, name: ‘张三’, age: 18 },
{ id: ‘002’, name: ‘李四’, age: 19 },
{ id: ‘003’, name: ‘王五’, age: 20 }
]

vue根据数据生成虚拟 DOM

初始虚拟 DOM

<li key='0'>张三-18<input type="text"></li>
<li key='1'>李四-19<input type="text"></li>
<li key='2'>王五-20<input type="text"></li>

将虚拟 DOM 转为 真实 DOM

this.persons.unshift({ id: ‘004’, name: ‘老刘’, age: 40 })

在 persons 数组最前面添加上 { id: ‘004’, name: ‘老刘’, age: 40 }

新数据:

persons: [
​ { id: ‘004’, name: ‘老刘’, age: 40 },
​ { id: ‘001’, name: ‘张三’, age: 18 },
​ { id: ‘002’, name: ‘李四’, age: 19 },
​ { id: ‘003’, name: ‘王五’, age: 20 }
]

vue根据数据生成虚拟 DOM

新虚拟 DOM

<li key='0'>老刘-30<input type="text"></li>
<li key='1'>张三-18<input type="text"></li>
<li key='3'>李四-19<input type="text"></li>
<li key='4'>王五-20<input type="text"></li>

将虚拟 DOM 转为 真实 DOM
因为老刘被插到第一个,重刷了 key 的值,vue Diff 算法 根据 key 的值 判断 虚拟DOM 全部发生了改变,然后全部重新生成新的 真实 DOM。实际上,张三,李四,王五并没有发生更改,是可以直接复用之前的真实 DOM,而因为 key 的错乱,导致要全部重新生成,造成了性能的浪费。

结论:

最好使用每条数据的唯一标识作为key, 比如id、手机号、身份z号、学号等唯一值
如果不存在对数据的逆序添加、逆序删除等破坏顺序 *** 作,仅用于渲染列表用于展示,使用index作为key是没有问题的

正确使用key

2022-05-04-09点18分 7.获取表单元素的技巧

1.v-model默认收集的是value
2.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
3.男女信息收集标准做法 name=“sex”
4.多组checkbox收集,data用数组
v-model的三个修饰符

  • trim 去掉首尾的空格
  • lasy 失去焦点在收集数据
  • number 收集到数据是数字类型的 一般与 < input type=“number”>搭配使用
<!-- v-model的三个修饰符
     trim 去掉首尾的空格
     lasy 失去焦点在收集数据
     number 收集到数据是数字类型的 一般与<input type="number">搭配使用 -->

<body>
    <div class="root">
        <form action="" @submit.prevent="demo">
            <!-- v-model 默认收集的value -->
            <label>账号: <input type="text" v-model.trim="account"> </label><br><br>
            <label>密码: <input type="password" v-model.trim="password"> </label><br><br>
            <label>年龄: <input type="number" v-model.number="age"> </label><br><br>
            <label>性别::<input type="radio" name="sex" checked="checked" value="male" v-model="sex">
                 :<input type="radio" name="sex" value="female" v-model="sex"></label><br><br>
            <!-- 多组checkbox收集,data用数组  -->
            <label>爱好: 吃饭:<input type="checkbox" checked="checked" value="eat" v-model="hobbies"> 
                        睡觉:<input type="checkbox" value="sleep" v-model="hobbies">
                        打豆豆:<input type="checkbox" value="beatDou" v-model="hobbies">
                    </label><br><br>
            <!-- select收集数据在v-model绑定在select 不要写在option上 -->
            <select name="" id="" v-model="schAddress">
                    <option value="" >请选择你的校区</option>
                    <option value="beijing" >北京</option>
                    <option value="shanghai" >上海</option>
                    <option value="guangzhou" >广州</option>
                    <option value="shenzhen" >深圳</option>
                    
                </select><br><br>

            <label>其他信息: <textarea name="" id="input" class="form-control" rows="3" required="required" v-model.lazy="otherInfo">
               
                    
            </textarea></label><br><br>
            <!-- 此时不需要input 的value -->
            <input type="checkbox" v-model="agree"><span>阅读并接受 <a href="">《用户协议》</a></span><br><br>
            <button>提交</button>



        </form>
    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                account: '',
                password: '',
                age: '',
                sex: '',
                hobbies: [],
                schAddress: '',
                otherInfo: '',
                agree: ''

            },
            methods: {
                demo() {
                    console.log(JSON.stringify(this._data));
                }
            },
            computed: {},
            watch: {}
        });
    </script>
2022-5-5-09点46分 8.内置指令
  • v-text
    v-text指令:(使用的比较少)
    1.作用:向其所在的节点中渲染文本内容。
    2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
    3.v-text 不会解析html标签
<div class="root">
        <!-- v-text指令:(使用的比较少) -->
        <!-- 1.作用:向其所在的节点中渲染文本内容。 -->
        <!-- 2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。 -->
        <!-- 3.v-text 不会解析html标签 -->
        <div>你好,{{name}}</div>
        <div v-text="name">你好</div>

  • v-html

      1.作用:向指定节点中渲染包含html结构的内容。
      2.与插值语法的区别:
      v-html会替换掉节点中所有的内容,{{xx}}则不会。
      v-html可以识别html结构。
      3.严重注意:v-html有安全性问题!!!!
      在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
      一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
    
//此时会解析str中html标签
<div v-html="str">这是我原来的结构</div>
 <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                n: 0,
                name: '尚硅谷',
                str: '这是一个html 的h2标签'
            },
            methods: {},
            computed: {},
            watch: {}
        });
    </script>

  • v-once
    1. v-once所在节点在初次动态渲染后,就视为静态内容了。
    2. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
		//此时div中 n的值是第一次的值
		<div v-once>{{n}}</div>
        <button @click="n++">点击我让n++---{{n}}</button>
  • v-pre
    v-pre指令:(比较没用)
    跳过其所在节点的编译过程
    可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译
		<div v-pre>我没有使用vue</div>
       	<div>{{name}}</div>
9.自定义指令

配置项关键词 directives
简写形式不能进行复杂的调用

<body>
    <div class="root">
        <div v-text="n"></div>
        <!-- 自定义指令 使n数值放大十倍 -->
        <div v-big="n"></div>
        <button @click="n++">点击让n++</button><br>
        <input type="text" v-fbind:value="n">


    </div>
    <script>
        Vue.config.productionTip = false;
        const vm = new Vue({
            el: '.root',
            data: {
                n: 1,
                name: '',
            },
            methods: {},
            computed: {},
            watch: {},
            directives: {
                //big 函数何时被调用? 1.指令和元素绑定时(一上来,此时元素在内存中,还没有渲染到页面上)
                //                    2.指令所在的模板重新解析时(值发生变化就会重新解析)
                big(element, binding) {
                //参数1 真实dom元素 参数2指令
                    //console.log(a, b);
                    element.innerText = binding.value * 10;
                },
                /*fbind(element, binding) {
                    //此时input第一次不能获得焦点
                    //点击一次input被放到html 才能获得焦点
                    element.value = binding.value;
                    element.focus();
                    // console.log(binding);
                }*/
                fbind: {
                    //1.指令和元素绑定时
                    bing(element, binding) {
                        element.value = binding.value;
                        console.log("bind");
                    },
                    //2.指令所在元素被插入页面时
                    inserted(element, binding) {
                        element.focus();
                        console.log('inserted');
                    },
                    //3.指令所在的模板被重新解析时
                    update(element, binding) {
                        element.value = binding.value;
                        console.log('update');
                    }

                }
            }
        });
    </script>
</body>
  • 定义全局指令
    Vue.directive('fbind', {
        // 指令与元素成功绑定时(一上来)
        bind(element, binding){
            element.value = binding.value
        },
        // 指令所在元素被插入页面时
        inserted(element, binding){
            element.focus()
        },
        // 指令所在的模板被重新解析时
        update(element, binding){
            element.value = binding.value
        }
    })

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/800324.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存