Vue2学习之路 · 四:监视的原理、收集表单数据、过滤器

71 阅读3分钟

Vue监视数据的原理

1、vue会监视data中所有层次的数据

2、如何监视对象中的数据? 通过set函数实现监视,并且要在new Vue时就传入要检测的数据

对象中后追加的属性,Vue默认不做响应处理

如果需要给后添加的属性做响应式,就要使用以下的API:参数1:要添加的地方,参数二:要添加的属性名,参数三:属性值

Vue.set(target, propertyName/index, value)

vm.$set(target, propertyName/index, value)

3、如何监视数组中的数据?通过包裹数组更新元素的方法实现,本质上就是做了两件事

调用原生对应的方法对数组进行更新

重新解析模板,进而更新页面

4、在Vue中修改数组中的某个元素一定要使用以下的方法

使用这些API:push()、pop()、unshift()、shift()、sort()、splice()

使用Vue.set()

使用vm.$set()

5、注意

Vue.set和vm.$set()不能给vm或是vm的根数据对象添加属性,vm就是Vue的实例对象,vm的根数据对象就是_data

<div id="root">
        <h2>学生信息</h2>

        <button @click="student.age++">年龄+1岁</button>
        <button @click="addSex">添加性别属性,默认值为:男</button>
        <button @click="addFriend">在列表首位添加一个朋友</button>
        <button @click="setFirstFriendName">修改第一个朋友的名字为:张三</button>
        <button @click="addFirstHobby">添加一个爱好</button>
        <button @click="setFirstHobby">修改第一个爱好为:开车</button>
        <button @click="filterHobbySomke">过滤掉爱好中的抽烟</button>

        <h3>姓名:{{student.name}}</h3>
        <h3>年龄:{{student.age}}</h3>
        <h3>性别:{{student.sex}}</h3>
        <h3>爱好:</h3> 
        <ul>
            <li v-for="(h,index) in student.hobby" :key="index">
                {{h}}
            </li>
        </ul>
        <h3>朋友:</h3>
        <ul>
            <li v-for="(f,index) in student.firends" :key="index">
                {{f.name}} -- {{f.age}}
            </li>
        </ul>   
    </div>
    <script>
        new Vue({
            el:'#root',
            data:{
                student:{
                    name:'赵云',
                    age:18,
                    hobby:['抽烟','喝酒','烫头'],
                    firends:[
                        {name:'刘备',age:50},
                        {name:'张飞',age:40}
                    ]
                }
            },
            methods:{
                addSex(){
                    this.$set(this.student,'sex','男')
                },
                addFriend(){
                    this.student.firends.unshift({name:'曹操',age:99});
                },
                setFirstFriendName(){
                    this.student.firends[0].name='张三';
                    this.student.firends[0].age= 100;
                },
                addFirstHobby(){
                    this.student.hobby.push('打游戏');
                },
                setFirstHobby(){
                    this.student.hobby.splice(0,1,'开车');
                },
                filterHobbySomke(){
                    this.student.hobby = this.student.hobby.filter((h)=>{
                        return h != '抽烟'
                    })
                }
            }
        })
    </script>

收集表单数据

1、< input type="text"/>:则v-model收集的是value值,用户输入的就是value值

2、< input type="radio"/>:则v-model收集的是value值,需要给标签配置value值

3、< input type="chackbox" />:

没有配置input的value属性:就会收集checked属性的值,就是一个布尔值,选中就是true,未选中就是false

配置了input的value属性:如果v-model的初始值是一个数组,那么收集的就是value值组成的数组; 如果v-model的初始值不是一个数组,那么收集的还是checked属性的值,就是一个布尔值,选中就是true,未选中就是false

4、v-model有三个修饰符

lazy:失去焦点再收集数据

number:把输入的字符串转化为有效的数字

trim:过滤输入的字符串中前后的空格,不会过滤字符串中间的空格

<div id="root">
        <form @submit.prevent="demo">
            账号:<input type="text" v-model.trim="userInfo.account"><br>
            密码:<input type="password" v-model.trim="userInfo.password"><br>
            年龄:<input type="number" v-model.number="userInfo.age"><br>
            性别:<input type="radio" name="sex" v-model="userInfo.sex" value="male"><input type="radio" name="sex" v-model="userInfo.sex" value="female"><br>
            爱好:
                <input type="checkbox" v-model="userInfo.hobby" value="stady">学习
                <input type="checkbox" v-model="userInfo.hobby" value="listen">听音乐
                <input type="checkbox" v-model="userInfo.hobby" value="eat">吃饭<br>
            所属校区:
                <select v-model="userInfo.city">
                    <option value="">请选择校区</option>
                    <option value="beijing">北京</option>
                    <option value="shanghai">上海</option>
                    <option value="shenzhen">深圳</option>
                    <option value="guangzhou">广州</option>
                </select>
                <br>
            其它信息:<textarea v-model.lazy="userInfo.other"></textarea><br>
            <input type="checkbox" name="read" v-model="userInfo.read">阅读并接受<a href="JavaScript:;">《用户协议》</a><br>
            <button>提交</button>
        </form>
    </div>
    <script>
        new Vue({
            el:'#root',
            data:{
                userInfo: {
                    account:'',
                    password:'',
                    age:18,
                    sex:'',
                    hobby:[],
                    city:'',
                    other:'',
                    read:''
                }
            },
            methods:{
                demo(){

                }
            }
        })
    </script>

过滤器

定义:对要显示的数据进行特定格式化后再显示,适用于一些简单逻辑的处理

语法:

注册过滤器:Vue.filter(过滤器名, callback) 或 new Vue(filters:{ 过滤器名(){ } })

使用过滤器:{{ xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"

注意:

过滤器也可以接收额外参数,多个过滤器可以串联

不会该改变原本的数据,而是产生新的对应的数据

v-model不能使用过滤器

<div id="root">
        <h2>显示格式化后的时间</h2>
        <!-- 计算属性实现 -->
        <h3>现在时间是:{{fmtTime}}</h3>
        <!-- methods实现 -->
        <h3>现在时间是:{{getFmtTime()}}</h3>
        <!-- 过滤器实现 -->
        <h3>现在时间是:{{time | timeFormater}}</h3>
        <!-- 过滤器(传参)实现 -->
        <h3>现在时间是:{{time | timeFormater('YYYY*MM*DD')}}</h3>
        <!-- 过滤器套过滤器实现 -->
        <h3>现在时间是:{{time | timeFormater('YYYY*MM*DD') | mySlice}}</h3>
        <h3 :x="msg | mySlice">{{msg}}</h3>
    </div>
    <div id="div02">
        <h3>{{msg | mySlice}}</h3>
    </div>
    <script>
        // 全局过滤器,必须写在vue实例之前
        Vue.filter('mySlice',function(val){
            return val.slice(0,4);
        })
        new Vue({
            el:'#root',
            data:{
                time:Date.now(),
                msg:'你好呀世界'
            },
            computed:{
                fmtTime(){
                    return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss');
                }
            },
            methods:{
                getFmtTime(){
                    return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss');
                }
            },
            // 过滤器配置属性(局部的)
            filters:{
                timeFormater(val,str='YYYY-MM-DD HH:mm:ss'){
                    return dayjs(val).format(str);
                },
                mySlice(val){
                    return val.slice(0,4);
                }
            }
        })
        new Vue({
            el:'#div02',
            data:{
                msg:'123456789'
            }
        })
    </script>