渲染指令 数据监测原理

条件渲染 | v-if、v-show

  1. v-if
    语法:
  1. v-if = ‘表达式’
  2. v-else-if = ‘表达式’
  3. v-else = ‘表达式’
    适用于:切换频率较低的场景
    特点:不展示的DOM元素直接被移除
    注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”
  1. v-show
    语法:
    v-show=‘表达式’
    适用于:切换频率较高的场景
    特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉(display:none)
    备注:使用 v-if 的时,元素可能无法获取到,而使用v-show一定可以获取到 v-if 是实打实地改变dom元素,v-show 是隐藏或显示dom元素
<div id="root">
    <h2>条件渲染</h2>
    <hr>
    <!-- v-show 可以接受布尔值/表达式作为属性值 -->
    <div v-show="true">{{ hello_name }}</div>
    <div v-show="0.1+0.2===0.3">{{ vue_name }}</div>
    <!-- v-if 可以接受布尔值/表达式作为属性值 -->
    <div v-if="n==1">{{ hello_name }}</div>
    <div v-else-if="n==2">{{ hello_name }}!</div>
    <div v-else-if="n==3">{{ hello_name }}!!</div>
    <div v-else-if="n>=3">{{ hello_name }} good</div>
    <button @click="n++">点击变换</button>
    <!-- v-if与template的配合使用 管理多个元素渲染 -->
    <template v-if="n==1">
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
    </template>
</div>
<script type="text/javascript">
    const x = new Vue({
        el: '#root',
        data: {
            hello_name: 'Vue',
            vue_name: 'Vue',
            n: 1
        }
    })
</script>

列表渲染 | v-for
v-for指令,用于展示列表数据
语法: v-for=“(item, index) in xxx” :key=“yyy”
可遍历元素:数组、对象、字符串(用的很少)、指定次数(用的很少)
数组: (item, index)
对象: (value, key)
字符串:(char, index)
指定次数:(number, index)

<div id="root">
    <h2>列表渲染</h2>
    <hr>
    <div>
        <!-- 遍历数组 -->
        <!-- <ul v-for="p in persion" :key="p.id"> -->
        <ul v-for="p of persion" :key="p.id">
            <li>{{p.name}} ,年龄:{{p.age}}</li>
        </ul>
        <!-- 遍历对象 -->
        <ul v-for="(value,key) of persion[0]" :key="key">
            <li>{{ value }}</li>
        </ul>
        <!-- 遍历字符串 -->
        <ul v-for="(char,index) of 'hello'" :key="index">
            <li>第{{index}}字母为:{{ char }}</li>
        </ul>
        <!-- 遍历指定次数 -->
        <ul v-for="(char,index) of 4" :key="char+index+Math.random()">
            <li>{{ char }} ,索引为 {{index}}</li>
        </ul>
    </div>
</div>
<script type="text/javascript">
    const x = new Vue({
        el: '#root',
        data: {
            persion: [
                { id: 'sk9G2O01avD', name: '张三', age: '12' },
                { id: 'k8F4Dl7m', name: '李四', age: '34' },
                { id: 'oB5vA0Qmm1p', name: '杰克', age: '22' }
            ]
        }
    })
</script>

key 的作用与原理
虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟
DOM】的差异比较,比较规则如下:
对比规则:

  1. 旧虚拟DOM中找到了与新虚拟DOM相同的key:
    ①若虚拟DOM中内容没变, 直接使用之前的真实DOM
    ②若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
  2. 旧虚拟DOM中未找到与新虚拟DOM相同的key创建新的真实DOM,随后渲染到到页面。
    用index作为key可能会引发的问题:
  1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作: 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低
  2. 如果结构中还包含输入类的DOM: 会产生错误DOM更新 ==>界面有问题
    开发中如何选择key:
  1. 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
  2. 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。

实现列表排序

<div id="root">
    <h2>列表排序</h2>
    <hr>
    <input type="text" v-model="inputKey" placeholder="检索姓名">
    <button @click="sortType = 1">年龄升序</button>
    <button @click="sortType = 2">年龄降序</button>
    <button @click="sortType = 0">原顺序</button>
    {{sortType}}
    <div>
        <ul v-for="p of filePersion" :key="p.id">
            <li>{{p.name}} ,年龄:{{p.age}}</li>
        </ul>
    </div>
</div>
<script type="text/javascript">
    new Vue({
        el: '#root',
        data: {
            sortType: 0, //0 原顺序 ,1 升序,2 降序
            inputKey: '',
            persion: [
                { id: 'dsadafds', name: '张三', age: '12' },
                { id: 'ewrsr23', name: '李四', age: '34' },
                { id: 'fdsa32424', name: '王五', age: '54' },
                { id: 'gdsbjryey', name: '张露西', age: '32' },
                { id: 'trevcdfhgtr', name: '贝克汉姆', age: '22' }
            ],
        },
        computed: {
            filePersion() {
                const arr = this.persion.filter((p) => {
                    return p.name.indexOf(this.inputKey) >= 0
                })
                // 判断是否需要排序
                if (this.sortType) {
                    arr.sort((p1, p2) => {
                        return this.sortType === 1 ? p1.age - p2.age : p2.age - p1.age
                    })
                } 
                return arr
            }
        }
    })
</script>

数据监测原理_对象
简单模拟vue更新数据原理

let data = {
name:'VUE',
address:'北京',
} f
unction Observer(obj){
//汇总 data 对象中所有的属性形成一个数组
const keys = Object.keys(obj)
//遍历 keys 数组,分别添加 getter 、 setter
keys.forEach((k) => {
Object.defineProperty(this, k, {
get() {
return obj[k]
},
set(val) {
console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....`)
obj[k] = val
}
})
})
} /
/创建一个监视的实例对象,用于监视(中转) data 中属性的变化
const obs = new Observer(data)
console.log(obs)
//准备一个vm实例对象
let vm = {}
vm._data = data = obs
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值