07月01, 2019

VUE--VUE基础--基础指令(下)

基础指令-2

5、数组更新检测

5.1、变异方法

所谓变异方法,是指在调用了该方法后会改变原本的数组。Vue 包含一组观察数组的变异方法,它们将会触发视图更新。具体包含以下方法:

push():接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。
pop():从数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。
shift():移除数组中的第一个项并返回该项,同时数组的长度减 1。
unshift():在数组前端添加任意个项并返回新数组长度。
splice():删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员。
reverse():用于反转数组的顺序,返回经过排序之后的数组。
sort():调用每个数组项的 toString() 方法,然后比较得到的字符串排序,返回经过排序之后的数组。可以自己定义方法参数

下面我们来看一个具体的示例,如下:

<body>
    <div id='app'>
        <button @click="addLast">数组最后增加push</button>
        <button @click="delLast">数组最后删除pop</button>
        <button @click="addFirst">数组最前增加unshift</button>
        <button @click="delFirst">数组最前删除shift</button>
        <button @click="splice">删除并替换首元素splice</button>
        <button @click="reverse">反序数组内容reverse</button>
        <button @click="sort">根据id排序sort</button>
        <ul>
            <li v-for="obj in arr">
                {{obj}}
            </li>
        </ul>
    </div>
</body>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            arr: [{
                id: 12,
                name: "张三",
                age: 20
            }, {
                id: 2,
                name: "李四",
                age: 28
            }, {
                id: 34,
                name: "王五",
                age: 22
            }, {
                id: 4,
                name: "赵六",
                age: 34
            }]
        },
        methods: {
            addLast: function () {
                this.arr.push({
                    id: 5,
                    name: "周七",
                    age: 25
                })
            },
            delLast: function () {
                this.arr.pop()
            },
            addFirst: function () {
                this.arr.unshift({
                    id: 5,
                    name: "周七",
                    age: 25
                })
            },
            delFirst: function () {
                this.arr.shift()
            },
            reverse: function () {
                this.arr.reverse();
            },
            splice:function(){
                this.arr.splice(0,1,{id:11,name:"jack",age:29})
            },
            sort:function(){
                function idSort(){
                    return function(a,b){
                        return a.id - b.id;
                    }
                }
                this.arr.sort(idSort());
            }
        },
    })
</script>

v-for-3

5.2、替换数组

除了上面所列举的变异方法以外,JavaScript 中也存在不会改变原来数组的非变异方法。这个时候,我们可以使用新数组来替换旧数组。常见的非变异方法如下:

concat():先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。
slice():基于当前数组中一个或多个项创建一个新数组,接受一个或两个参数,即要返回项的起始和结束位置,最后返回新数组。
map():对数组的每一项运行给定函数,返回每次函数调用的结果组成的数组。
filter():对数组中的每一项运行给定函数,该函数会返回true的项组成的数组。

具体示例如下:

<body>
    <div id="app">
        <div>
            <button @click='concat'>concat</button>
            <button @click='slice'>slice</button>
            <button @click='map'>map</button>
            <button @click='filter'>filter</button>
        </div>
        <ul>
            <li v-for="item in items">
                {{ item }}
            </li>
        </ul>
    </div>
</body>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
    el: '#app',
    data: {
        items: ['刘备', '关羽', '张飞'],
        addValue: '赵云'
    },
    methods: {
        concat() {
            this.items = this.items.concat(this.addValue); // 拼接新的值
        },
        slice() {
            this.items = this.items.slice(1); // 移除第一个数据
        },
        map() {
            // 每一项数据前面拼接索引
            this.items = this.items.map(function (item, index, arr) {
                return "<h1>" + index + "--" + item + "</h1>";
            })
        },
        filter() {
            // 返回索引大于 0 的数据
            this.items = this.items.filter(function (item, index, arr) {
                return (index > 0);
            });
        }
    }
})
</script>

v-for-4

5.3、无法检测的数组变化

在 Vue 中无法检测到以下 2 种变异的形式:

  • 利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
  • 修改数组的长度时,例如:vm.items.length = newLength 不过,针对上面的 2 种情况,我们也有相应的对策。如果要设置数组某一个具体的项目,可以使用 Vue 实例的 set 方法或者splice带有三个参数的替换模式。而如果要改变数组的长度,可以使用 splice 来进行替代。

下面是一个具体的示例,如下:

<body>
    <div id="app">
        <!-- 特别需要注意的是以下的数组变动方法是不支持的:
                通过索引直接设置项:app.books[2] = {...}
                修改数组长度:app.books.length = 1 -->
        <input type="text" name="" id="" placeholder="请输入书名" v-model='newBookName'>
        <input type="text" name="" id="" placeholder="请输入作者" v-model='newBookAuthor'>
        <button @click='editOne'>设置第一本书的信息</button>
        <p>购买的书如下:</p>
        <ul>
            <template v-for='(book,index) in books'>
                <li>序号:{{index}}</li>
                <li>书名:{{book.name}}</li>
                <li>作者:{{book.author}}</li>
                <li>-------------------------</li>
            </template>
        </ul>
        <button @click='remainOne'>只留下第一本书</button>
    </div>
</body>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            newBookName: '', // 和第一个文本框的数据相关联
            newBookAuthor: '', // 和第二个文本框的数据相关联
            books: [{
                    'name': '斗破苍穹',
                    'author': '天蚕土豆'
                },
                {
                    'name': '逆天邪神',
                    'author': '火星引力'
                },
                {
                    'name': '斗罗大陆',
                    'author': '唐家三少'
                },
                {
                    'name': '星辰变',
                    'author': '我吃西红柿'
                },
            ]
        },
        methods: {
            // 如果要设置数组某一个具体的项目,可以使用 Vue 实例的 set 方法
            // 或者splice的带三个参数的方法
            editOne: function () {
                Vue.set(this.books, 0, {
                    'name': this.newBookName,
                    'author': this.newBookAuthor
                });
                //第一个参数表示要替换的起始位置,第二个参数表示要替换几个,第三个参数表示要替换的值
                this.books.splice(0,1,{"name":this.newBookName,"author":this.newBookAuthor})
            },
            // 如果要改变数组的长度,可以使用splice来进行替代
            remainOne: function () {
                //如果splice只有一个参数表示删除,从参数位置开始,往后全部删除
                this.books.splice(1);
            }
        }
    });
</script>

v-for-5

6、v-on

v-on用来添加事件,前面我们已经用过很多次了,这个指令可以简写,我们绑定事件可以写成下面这样

<!-- 绑定点击事件 -->
<button @click=‘fn1’>点击1</button>
<!-- 绑定鼠标移入事件 -->
<div @mouseover='fn2'>点击2</div>

7、v-bind

v-bind用来绑定属性,它也有简写的形式

<!-- 绑定一个href属性
    注意单引号,因为vue绑定认为里面是一个变量的值
-->
<a v-bind:href="'http://www.baidu.com'">百度一下</a>
<!-- 可以简写成下面的形式 -->
<a :href="'http://www.baidu.com'">百度一下</a>

<!-- 绑定src属性 -->
<img :src="'images/xxx.jpg'">

8、v-model

v-model 可以在表单控件或者组件上创建双向绑定

<body>
    <div id='app'>
        <input type="text" v-model="message">
        <p>{{message}}</p>      
    </div>
</body>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            message:"Hello Vue!",
        } 
    })
</script>

再比如下面的示例:

<body>
    <div id='app'>
        <input type="text" v-model="url" style="width: 200px">
        <a :href="url">跳转</a>
        <p>{{url}}</p>      
    </div>
</body>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            url:"http://www.baidu.com"
        } 
    })
</script>

v-mode

9、v-pre

跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签(也就是{{}})。跳过大量没有指令的节点会加快编译。通俗的说,加了这个指令,元素和它的子元素将不会被编译

<span v-pre>{{ message }}</span>

10、v-cloak

如果网页显示较慢,{{}}在页面还未加载完成的时候,总会显示在页面上。如果想屏蔽掉这种情况,可以使用v-cloak

<body>
    <div id='app'>
        <input type="text" v-model="url" style="width: 200px" v-cloak>
        <a :href="url" v-cloak>跳转</a>
        <p v-cloak>{{url}}</p>      
    </div>
</body>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    setTimeout(() => {
        let vm = new Vue({
        el: '#app',
        data: {
            url:"http://www.baidu.com"
        } 
    })
    }, 3000);

</script>

v-cloak

11、v-once

只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

<body>
    <div id='app'>
        <p v-once>{{message}}</p>
        <button @click="change()">点击</button>
    </div>
</body>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            message:"Hello",
            arr: ["Hello Vue!","Hello Jack!","Hello World!","Hello Mr.Yan","Hello,Hello!"]
        },
        methods: {
            change:function(){
                let r = Math.floor(Math.random() * this.arr.length);
                this.message = this.arr[r];
            }
        },
    })
</script>

v-once

本文链接:http://www.yanhongzhi.com/post/vue-direct-2.html

-- EOF --

Comments