VueJs中的闪烁问题/v-if/v-show区别/嵌套循环和遍历数组中相同项/绑定事件

场景:vuejs在解析时出现闪烁

原因:
在使用vuejs、angularjs开发时,经常会遇见在如Chrome这类能够快速解析的浏览器上出现表达式({{ express }} ),或者是模块(div)的闪烁。对于这个问题由于JavaScript去操作DOM,都会等待DOM加载完成(DOM ready)。对于vuejs、angularjs这些会在DOM ready完会才回去解析html view Template,所以对于Chrome这类快速的浏览器你会看见有闪烁的情况出现。而对于IE7,8这类解析稍慢的浏览器大部分情况下是不会出现这个问题的。

解决方法
在vuejs、angularjs中为我们提供了v-cloak、ng-cloak来实现防止闪烁的方案,同时对于bing文字({{ express }} )我们也可以改为v-bind、ng-bind来实现避免。

下面以vuejs为例:

#v-cloak
用法:

这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

~~~

1.Vue中的闪烁问题 #

1.1 v-text绑定属性 #

<div v-text="hello"></div>

1.2 v-clock解决闪烁 #

增加样式(隐藏表达式)

[v-cloak]{
    display:none;
}

设置需要防止闪烁的dom元素上,在数据绑定后移除v-cloak属性

<div v-cloak>{{hello}}</div>

在使用vue时会出现加载渲染页面时闪烁,一般有以下两个情况:

1.使用了{{}},解决方案使用v-bind

2.使用v-if,出现原先要隐藏的元素先出现然后在隐藏从而造成了闪烁的问题。

以上两个问题都可以使用以下的方案来解决。

在css中定义

[v-cloak] {
   display:none;

}

在v-if中加上v-cloak即可解决.

2.v-if/v-show/v-else #

2.1 v-if #

v-if条件不成立移除dom元素,可以与v-else连用

<div v-if="false">hello</div>
<div v-else>world</div>

可以使用vue自带的template标签,解决多余标签问题

<template v-if="false">hello</template>
<div v-else>world</div>

2.2 v-show #

v-show 是简单的切换元素的 CSS 属性 display,可以与v-else连用

<div v-show="false">hello</div>
<div v-else>world</div>

不能使用template语法

2.3 v-if/v-show区别 #

一般来说,v‐if 有更高的切换消耗而 v‐show 有更高的初始渲染消耗。因此,如果需要频繁切换 v‐show 较好,如果在运行时条件不大可能改变 v‐if 较好

  • v-if当条件成立的时候会将元素加上,不成立,就会移出dom,并且内部的指令不会执行
  • v-show只是简单的隐藏和显示

1.共同点

都是动态显示DOM元素

2.区别

(1)手段:
v-if是动态的向DOM树内添加或者删除DOM元素;
v-show是通过设置DOM元素的display样式属性控制显隐;
(2)编译过程:
v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;
v-show只是简单的基于css切换;
(3)编译条件:
v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载);
v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留;
(4)性能消耗:
v-if有更高的切换消耗;
v-show有更高的初始渲染消耗;
(5)使用场景:
v-if适合运营条件不大可能改变;
v-show适合频繁切换。

3.v-for循环 #

基于源数据将元素或模版块重复

3.1 遍历对象 #

<template v-for="(key,value) in data">
    {{$index}}:{{value}}{{key}}:{{$key}} <br>
</template>
data:{
    data:{
        name:'zfpx',
        age:7,
    }
}

3.2 遍历数组 #

<template v-for="(key,value) in data">
    {{key}}:{{value.name}}:{{value.type}} <br>
</template>
data:{
    data:[
        {name:'zfpx',type:['backbone']},
        {name:'zfpx1',type:['jquery','react','angularjs']},
        {name:'zfpx2',type:['nodejs','angularjs','vuejs']},
    ]
}

3.3 嵌套循环 #

<template v-for="(key,value) in data">
    <template v-for="(childKey,t) in value.type">
        {{key}}{{childKey}}{{t}} <br>
    </template>
</template>

3.4 遍历数组中相同项 #

<template v-for="(key,value) in data" track-by="$index">
    {{value}}
</template>
var vm = new Vue({
    el:'#app',
    data:{
        data:[
            '苹果','苹果','苹果','苹果'
        ]
    }
})

如果没有唯一的键供追踪 尽量使用track-by

看看下面的代码

<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>
vuejs 嵌套循环、if判断
</title>
<style type="text/css">
[v-cloak] { display: none }
</style>
</head>

<body>
<div id="app">

<table>
<tr>
<td >id</td>
<td >姓名</td>
<td >手机号</td>
<td >城市</td>

<td >通过审核</td>
<td >我的学生</td>
<td >操作</td>
</tr>
<tr v-for="(item,index) in list ">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.tel}}</td>

<td>{{item.province}}_{{item.city}}</td>
<td v-if="item.status==1">是</td>
<td v-else-if="item.status==0">否</td>
<td >
<span v-for="stu in item.stu ">
{{stu.name}},
</span>
</td>
<td>
<button v-on:click="edit">修改</button>
<button v-on:click="del(index)">删除</button>
</td>
</tr>
</table>
</div>
</body>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js" charset="utf-8"></script>
<script src="https://cdn.bootcss.com/vue/2.3.0/vue.min.js" charset="utf-8"></script>
<script type="text/javascript">
$(function() {
new Vue({
el: '#app',
methods: {
del:function(index){
this.list.splice(index,1);
},
edit: function () {
alert('修改')
},
},
data: {
"list":[{
"id":"139",
"name":"王五",
"tel":"13681829898",
"status":"1",
"province":"省",
"city":"市",
"sex":"1",
"stu":[{
"id":"200",
"name":"学生1",
"tel":"13681829898",
},{
"id":"201",
"name":"学生2",
"tel":"13681829898",
}],
},
{
"id":"138",
"name":"麻子",
"tel":"13681829898",
"status":"0",
"province":"省",
"city":"市",
"sex":"0",
"stu":[{
"id":"300",
"name":"学生31",
"tel":"13681829898",
},{
"id":"301",
"name":"学生32",
"tel":"13681829898",
}],
},
{
"id":"137",
"name":"丽丽",
"tel":"15152882891",
"status":"0",
"province":"省",
"city":"市",
"sex":"1",
"stu":[{
"id":"400",
"name":"学生41",
"tel":"13681829898",
},{
"id":"401",
"name":"学生42",
"tel":"13681829898",
}],
},
{
"id":"136",
"name":"娜娜",
"tel":"15152882891",
"status":"0",
"province":"省",
"city":"市",
"sex":"0",
"stu":[{
"id":"500",
"name":"学生51",
"tel":"13681829898",
},{
"id":"501",
"name":"学生52",
"tel":"13681829898",
}],
}]
}
})
})
</script>
</html>

4.v-bind绑定动态数据 #

<img v-bind:src="src" alt="">
<a v-bind:href="href">官网</a>
var vm = new Vue({
    el:'#app',
    data:{
        src:'http://vuejs.org/images/logo.png',
        href:'http://vuejs.org'
    }
})

我们可以使用:号的方式进行简写,不要使用{{src}}进行设置链接

5.v-on绑定事件 #

<div v-on:click="sayHello">sayHello</div>
<div v-on:click="sayWorld('我',$event)">sayWorld</div>
var vm = new Vue({
    el:'#app',
    data:{
        hello:'hello',
        world:'world'
    },
    methods:{
        sayHello(e){
            console.log(e);//无参数时会传递事件源
            alert(this.hello);
        },
        sayWorld(who,e){
            console.log(e);//有参数时需要手动传递
            alert(who+'的'+this.world);
        }
    }
});

我们可以使用@符的方式进行简写

6.图书管理案例 #

html的结构

<div id="app">
    <div class="container">
        <table class="table table-bordered">
            <tr>
                <td>书的名字</td>
                <td>数的价格</td>
                <td>书的数量</td>
                <td>小计</td>
                <td>操作</td>
            </tr>
            <tr v-for="book in books">
                <td>{{book.name}}</td>
                <td>{{book.price}}</td>
                <td><input type="text" v-model="book.count"></td>
                <td>{{book.price*book.count}}</td>
                <td><button class="btn btn-danger" @click="remove(book)">删除</button></td>
            </tr>
            <tr>
                <td colspan="5">
                    总价格 {{total}}
                </td>
            </tr>
        </table>
        <div class="form-group">
            <label for="bookname" class="control-label">书名</label>
            <input type="text" v-model="list.name" id="bookname" class="form-control">
        </div>
        <div class="form-group">
            <label for="bookprice" class="control-label">价格</label>
            <input type="text" v-model="list.price" id="bookprice" class="form-control">
        </div>
        <div class="form-group">
            <label for="bookcount" class="control-label">数量</label>
            <input type="text" v-model="list.count" id="bookcount" class="form-control">
        </div>
        <button class="btn btn-primary" @click="add">添加</button>
    </div>

</div>

js代码

var books = [
    {name:'nodeJs',price:30,count:1},
    {name:'angularJs',price:20,count:2},
    {name:'vueJs',price:40,count:2}
];
var vm = new Vue({
    el:'#app',
    data:{
        books:books,
        list:{name:'',price:'',count:''
        }
    },
    computed:{
        total() {
            var sum = 0;
            this.books.forEach(function (a) {
                sum+=a.price* a.count
            });
            return sum;
        }
    },
    methods: {
        add() {
            this.books.push(this.list);
            this.list = {name:'',price:'',count:''
            }
        },
        remove(book){
            this.books.$remove(book);
        }
    }
});

~~~~

未经允许不得转载:WEB前端开发 » VueJs中的闪烁问题/v-if/v-show区别/嵌套循环和遍历数组中相同项/绑定事件

赞 (0)