Vue学习笔记二

一、监视属性

1、通过methods和computed实现属性变化

@XXX='XXX'中可以写一些简单的语句

<body>
    <div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click="isHot = !isHot">切换天气</button>
        <button @click="changeWeather">切换天气</button>
    </div>
</body>

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

const vm = new Vue({
    el: '#root',
    data: {
        isHot: true
    },
    computed: {
        info: {
            get() {
                return this.isHot ? '炎热' : '凉爽';
            },
            set(value) {
            }
        }
    },
    methods: {
        changeWeather() {
            this.isHot  = !this.isHot;
        }
    }
})
</script>

2、watch方法

1)isHot发生变化时,会调用handler方法

2)immediate,在初始化时让handler调用

<body>
    <div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click="isHot = !isHot">切换天气</button>
        <button @click="changeWeather">切换天气</button>
    </div>
</body>

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

const vm = new Vue({
    el: '#root',
    data: {
        isHot: true
    },
    computed: {
        info: {
            get() {
                return this.isHot ? '炎热' : '凉爽';
            },
            set(value) {
            }
        }
    },
    methods: {
        changeWeather() {
            this.isHot  = !this.isHot;
        }
    },
    watch: {
        isHot: {
            immediate: true,
            handler(newValue, oldValue) {
                console.log("isHot被改动", newValue, oldValue);
            }
        },
        info: {
            immediate: true,
            handler(newValue, oldValue) {
                console.log("info被改动", newValue, oldValue);
            }
        }
    }
})

3) watch的第二种写法,使用$watch

const vm = new Vue({
    el: '#root',
    data: {
        isHot: true
    },
    computed: {
        info: {
            get() {
                return this.isHot ? '炎热' : '凉爽';
            },
            set(value) {
            }
        }
    },
    methods: {
        changeWeather() {
            this.isHot  = !this.isHot;
        }
    }
})

vm.$watch('info', {
    immediate: true,
    handler(newValue, oldValue) {
        console.log("info被改动", newValue, oldValue);
    }
})

3、深度监视 

1)Vue是可以监测对象内部值的改变的,但watch默认不监测对象内部值的改变(一层),这是为了提高效率

2)配置deep:true可以监测象内部值的改变(多层)

<body>
    <div id="root">
        <h3>a的值是:{{numbers.a}}</h3>
        <button @click="numbers.a++">点击让a+1</button>
    </div>
</body>

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

const vm = new Vue({
    el: '#root',
    data: {
        numbers: {
            a: 1,
            b: 1
        }
    },
    watch: {
        // 如果只监视a,可以这么写
        'numbers.a': {
            immediate: true,
            handler(newValue, oldValue) {
                console.log("a被改动", newValue, oldValue);
            }
        },
        // 如果要监视number中任意属性的变化,就要开启深度监视
        numbers: {
            deep: true,
            handler(newValue, oldValue) {
                console.log("number被改动", newValue.a, oldValue);
            }
        }
    }
})
</script>

4、computed和watch的区别

  • computed能完成的功能,watch都能完成
  • watch能完成的功能,computed不一定能完成,例如watch可以进行异步操作

两个要注意的原则

  • 所有被Vue管理的函数,都不要写箭头函数,这样this指向才是vm
  • 所有不被Vue管理的函数,如定时器的回调函数、ajax的回调函数等,都要写箭头函数,这样this指向才是vm
<body>
    <div id="root">
        姓:<input type="text" v-model="firstName"><br><br>
        名:<input type="text" v-model="secondName"><br><br>
        全名:<span>{{fullName}}</span><br><br>
    </div>
</body>

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

const vm = new Vue({
    el: '#root',
    data: {
        firstName: '张',
        secondName: '三',
        fullName: '张-三'
    },
    watch: {
        firstName(val) {
            this.fullName = val + "_" + this.secondName;
        },
        secondName(val) {
            this.fullName = this.firstName + "_" + val;
        }
    }
})

二、绑定class样式

 通过:class,:style指定样式名,通过更改data中的属性值达到更改样式的效果

<body>
    <div id="root">
        <div :class="myClass" @click="changeMood">test</div> <br> <br>

        <div :style="{fontSize: fSize + 'px'}" @click="changeFont">test</div> <br> <br>

        <div :style="myStyle" @click="changeStyle">test</div> <br> <br>
    </div>
</body>

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

const vm = new Vue({
    el: '#root',
    data: {
        myClass: 'red',
        fSize: '30',
        myStyle: {
            fontSize: '30px',
            color: 'blue'
        }
    },
    methods: {
        changeMood() {
            this.myClass = 'green';
        },
        changeFont() {
            this.fSize = 50;
        },
        changeStyle() {
            this.myStyle.color = 'pink';
        }
    }
})
</script>

三、条件渲染

1、v-show与v-if

通过v-show或v-if来做条件渲染

2、v-if与v-else-if与v-else

注意,这3种标签之间不能中断,必须连续 

<body>
    <div id="root">
        <h2 v-show="show">欢迎,{{name}}</h2>
        <h2 v-if="show">欢迎,{{name}}</h2>

        <h2 v-if="a === 1">1</h2>
        <h2 v-else-if="a === 2">2</h2>
        <h2 v-else-if="a === 3">3</h2>
        <h2 v-else>4</h2>
    </div>
</body>

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

const vm = new Vue({
    el: '#root',
    data: {
        show: true,
        name: '高大俊',
        a: 2
    }
})
</script>

v-show和v-if二者的区别,v-show是添加display样式,v-if是直接注释掉代码

 3、v-if与template配合使用

<template v-if="a === 1">
    <h2>A</h2>
    <h2>B</h2>
</template>

四、列表渲染

1、基本列表

使用v-for遍历数组或对象,用于展示数据

<body>
    <div id="root">
        <h2>人员列表1(遍历数组)</h2>
        <ul>
            <li v-for="p in persons" :key="p.id">
                姓名:{{p.name}},年龄:{{p.age}}
            </li>
        </ul>

        <h2>人员列表2(遍历数组)</h2>
        <ul>
            <li v-for="(p,index) in persons" :key="p.id">
                姓名:{{p.name}},年龄:{{p.age}},序号:{{index}}
            </li>
        </ul>

        <h2>汽车信息(遍历对象)</h2>
        <ul>
            <li v-for="(value,index) in car" :key="index">
                {{index}}:{{value}}
            </li>
        </ul>
    </div>
</body>

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

const vm = new Vue({
    el: '#root',
    data: {
        persons: [
            {id:'001',name:'张三',age:18},
            {id:'002',name:'李四',age:19},
            {id:'003',name:'王五',age:20},
        ],
        car: {
            name:'奥迪A8',
            price:'70万',
            color:'黑色'
        }
    }
})
</script>

2、key的原理

1)生成初始数据,并在v-for遍历时,使用index作为key值

2)vue根据数据生成虚拟DOM,写入内存

3)vue将虚拟DOM转成真实DOM,也就是我们在页面上能看到的

4)生成了新数据,vue根据新数据生成虚拟DOM

5)将新生成的虚拟DOM和原来的虚拟DOM中,key相同的进行对比

6)对比时发现,key等于0的数据行中,张三和老刘这2个字段不匹配,input标签数据匹配,所以将老刘替换成原来的张三,input因为匹配所以不变动。key等于1、2、3的也同样操作,所以会发生页面上input框错乱的问题

用index作为key时,在对数据进行添加、删除时,会出现问题。当没有指明key时,vue会默认使用index来作为key。因此必须要使用唯一标识来作为key

 3、列表过滤

1)使用watch来实现对列表的过滤

<body>
    <div id="root">
        <h2>人员列表</h2>
        <input type="text" placeholder="请输入名字" v-model="keyWord">
        <ul>
            <li v-for="p in newPersons" :key="p.id">
                姓名:{{p.name}},年龄:{{p.age}}
            </li>
        </ul>
    </div>
</body>

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

const vm = new Vue({
    el: '#root',
    data: {
        keyWord:'',
        persons: [
            {id:'001',name:'马冬梅',age:18,sex:'女'},
            {id:'002',name:'周杰伦',age:19,sex:'男'},
            {id:'003',name:'周冬雨',age:20,sex:'女'},
            {id:'004',name:'温兆伦',age:21,sex:'男'}
        ],
        newPersons:[]
    },
    watch: {
        keyWord:{
            immediate: true,
            handler(val) {
                this.newPersons = this.persons.filter((p) => {
                    return p.name.indexOf(val) > -1;
                })
            }
        }
    }
})
</script>

2)用computed实现

// 用computed实现
const vm = new Vue({
    el: '#root',
    data: {
        keyWord:'',
        persons: [
            {id:'001',name:'马冬梅',age:18,sex:'女'},
            {id:'002',name:'周杰伦',age:19,sex:'男'},
            {id:'003',name:'周冬雨',age:20,sex:'女'},
            {id:'004',name:'温兆伦',age:21,sex:'男'}
        ]
    },
    computed: {
        newPersons() {
            return this.persons.filter((p) => {
                return p.name.indexOf(this.keyWord) > -1;
            })
        }
    }
})

4、列表排序

<body>
    <div id="root">
        <h2>人员列表</h2>
        <input type="text" placeholder="请输入名字" v-model="keyWord">
        <button @click="sortType = 2">年龄升序</button>
        <button @click="sortType = 1">年龄降序</button>
        <button @click="sortType = 0">原顺序</button>
        <ul>
            <li v-for="p in newPersons" :key="p.id">
                姓名:{{p.name}},年龄:{{p.age}}
            </li>
        </ul>
    </div>
</body>

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

const vm = new Vue({
    el: '#root',
    data: {
        keyWord:'',
        sortType: 0,    // 0:原顺序,1:降序,2:升序
        persons: [
            {id:'001',name:'马冬梅',age:18,sex:'女'},
            {id:'002',name:'周杰伦',age:19,sex:'男'},
            {id:'003',name:'周冬雨',age:20,sex:'女'},
            {id:'004',name:'温兆伦',age:21,sex:'男'}
        ]
    },
    computed: {
        newPersons() {
            const arrs = this.persons.filter((p) => {
                return p.name.indexOf(this.keyWord) > -1;
            });

            if (this.sortType == 0) {
                return arrs;
            } else {
                arrs.sort((a,b) => {
                    return this.sortType == 1 ? b.age - a.age : a.age - b.age
                });
                return arrs;
            }
        }
    }
})
</script>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值