VUE(混入mixin、计算属性computed、监听watch)

混入mixin

  • 全局混入
    在vue实例外部通过Vue.mixin进行声明,可以让多个实例公用同一个数据
        // 全局混入
        Vue.mixin({
            data() {
                return {
                    name: "这是全局混入的data"
                }
            }
        })
  • 私有混入
    在vue实例中通过mixins进行声明,通过数组的形式(放入数组中的数据,需要在实例外部进行声明)
	 // 声明私有混入
        let mixin1 = {
            data() {
                return {
                    name: "这是私有1的data"
                }
            }
        };
        let mixin2 = {
            data() {
                return {
                    name: "这是私有2的data"
                }
            }
        }
	newVue({
 		mixins: [mixin1, mixin2]   // mixin1 mixin2 在外部进行声明  相同的变量,后面的覆盖前面的
	})
           
  • 混入总结
    混入就是封装一个vue属性,可以在多个实例上使用,实例首先在自身data数据中查找,接着再到私有混入中查找(数组中的多个混入,谁在后就用谁),最后再去全局混入中查找

计算属性 computed

计算属性是监听变量的变化,进行以下的操作

  1. 设置计算值
  2. 不需要事件触发,数据发生改变就触发
  3. 直接返回计算结果

计算属性return出结果不改变原来变量的值,计算属性是多对一的操作(多个变量得出一个变量)

    <div id="app">
        <input type="text" v-model="xing">
        <input type="text" v-model="ming">
        {{userName}} <br>
        <button @click="change">点击</button>
        {{users}}

    </div>
        <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    xing:"张",
                    ming:"三"
                }
            },
            computed:{
                userName(){    // userName可以直接当变量用
                    return this.xing+this.ming
                },
            }
        });
    </script>

计算属性中除了可以放函数,还可以写对象,而每个对象都有get和set两个方法。其实我们在计算属性放的函数其实就是放的一个对象,而这个对象默认使用的get方法,然后进行的一个简写,那么我们上面的案例可以这样完整地写出来

	                userName:{
                    get(){
                        return this.xing+this.ming;
                    }
                },

当我们想要使用事件,将我们通过计算得出的结果进行修改时,就要使用set方法,将原变量进行修改,才能将最后显示的数据进行修改

            methods: {
                change(){
                    this.users = (this.xing+this.ming).split("").reverse().join("");    // 通过事件改变计算属性,需要set进行配合
                }
            },
            computed:{

                users:{
                    get(){
                        return this.xing+this.ming
                    },
                    set(e){   
                        console.log(e);    // e是通过事件改变后的值
                        this.xing=e.split("")[0];   // 将改变后的值赋给原变量,也会让users的值进行改变
                        this.ming=e.split("")[1]
                    }
                }
            }
  • 计算属性总结
  1. 支持缓存,当依赖的变量发生改变时,计算结果也会发生相应的变化
  2. 不支持异步,当computed中有异步操作时,无法监听到数据的变化,无法正常进行计算
  3. computed属性值会默认进行缓存,计算属性是基于它们的响应式依赖进行缓存的(依赖数据发生改变,就会改变计算结果并进行缓存),
  4. 如果一个计算属性是由其他属性计算而来的,这个属性就是依赖于其他属性,是多对一的操作
  5. 如果computed属性值是函数,那么会默认走get方法,函数的返回值就是属性的属性值。在computed中,属性都有一个get和set方法,想要直接修改计算后的结果,就要调用set方法,让依赖的数据也进行改变

监听器 watch

当我们需要根据某个变量的变化进行不同的操作时,就可以使用监听器,监听它的变化,并且根据它不同的变化进行不同的操作


监听器的特点:

  1. 要监听谁就要将它设置为监听值
  2. 不需要事件触发
  3. 不需要返回值
  4. 没有依赖项,只监测自己设置的监听值
  5. 没有缓存

监听器要写在vue实例中

            watch:{
               // 监听值(newData,oldData){
                //    newData: 变化后的值
                 //   oldData: 变化前的值
                }
            }

我们要监听哪个变量就将谁设置为监听值,里面有两个参数,一个代表变化后的新的结果,一个是变化前的结果。


上面是监听单个变量,我们还可以监听对象格式的数据

                监听对象:{
                    handler(n,o){
                        n:变化后的对象
                        o:变化前的对象
                    },
                    deep:true,    // 设置深层次监听,默认为单层次监听
                    immediate:true    // 设置立即监听,默认为false,设置立即监听的话,进行页面时就进行监听,否则地话当数据发生改变后才会进行监听
                }

但是我们监听对象时,handler的两个参数返回的值都是一样的,所以暂时只能通过监听对象得知对象发生了改变

    <div id="app">
        <input type="text" v-model="userName">
        {{userName}}
        <br>
        这是修改后的值--{{newName}} <br>
        这是修改前的值-- {{oldName}} <br>
        <input type="text" v-model="obj.name">

    </div>
    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    userName:"这是初始值",
                    newName:"",
                    oldName:"",
                    obj:{
                        name:"胖中介",
                        age:"15",
                        family:[{
                            dad:"牛仔很会忙",
                            age:"28"
                        }]
                    }
                }
            },
            methods: {
            },
            // 设置监听
            watch:{   
                userName(n,o){   // 监听单个数据 
                    console.log(n,o);    // n 是修改后的值,o是原来的值
                    this.newName = n;
                    this.oldName = o
                },
                obj:{     // 监听对象
                    handler(n,o){
                        console.log(n,o);
                    },
                    deep:true
                }
            }
        });
    </script>

总结

今天学习了三块内容:混入、计算属性、监听。全局混入能让多个实例公用一组数据,我认为混入的作用主要就是在这一个方面,而私有混入的话,也只是相对于一个实例起作用,我暂时认为私有混入的作用是没有全局混入的作用大的,不过可能它在某一特定情况也会大放光彩的吧。计算属性能够将页面多个数据进行操作返回给一个变量,不过咱们一定要用好里面的get和set方法。监听是我认为作用比较大的,因为它可以观测到数据的变化,通过数据的变化进行响应的操作,但是里面的监听对象的变化是我认为作用不太大的。

实际案例

接下来上传一个案例:大麦网的查找案例。点击不同的类别,能够在下面调出相应的内容,这就是这个案例的核心操作
这个案例中引用了vue.js和一个弹性布局的css文件,没有放进去,如果复制直接使用的话,是无法正常使用的
html和js代码

    <div id="app">
        <div class="box">
            <!-- 城市 -->
                <div class="cityMenu">
                    <i>当前选中城市</i>
                    <span class="active" v-text="nowCity"></span>
                </div>
            <div class="flex">
                <div class="all">
                    <span :class="{active:cityIndex===-1}" @click="change4">全部</span>
                </div>
                <ul class="flex f_w">
                    <li v-for="(r,i) in cityList" :class="{active:cityIndex===i}" @click="cityChange(i)">
                        {{r}}
                    </li>
                </ul>
            </div>
            <!-- 分类 -->
            <div class="flex">
                <div class="all">
                    <span :class="{active:activeIndex===-1}" @click="change3">全部</span>
                </div>
                <ul class="flex f_w">
                    <li v-for="(r, i) in classList" @click="change(i)" :class="{active:activeIndex===i}">
                        {{r.name}}
                    </li>
                </ul>
            </div>
            <!-- 子类 -->
            <div class="flex">
                <div class="all">
                    <span :class="{active:secondIndex===-1}" v-show="activeIndex>-1" @click="secondIndex=-1">全部</span>
                </div>
                <ul class="flex f_w">
                    <li v-for="(r,i) in secondList" @click="change2(i)" :class="{active:secondIndex===i}">
                        {{r}}
                    </li>
                </ul>
            </div>
        </div>
    </div>
    <script>
        new Vue({
            el: '#app',
            data() {
                return {
                    activeIndex: -1,
                    secondIndex: -1,
                    cityIndex: -1,
                    cityList: ["南京", "北京", "天津", "济南", "合肥", "苏州", "泰州", "连云港", "广州", "淮安", "徐州", "滁州", "南宁", "南通",],
                    nowCity: "全国",
                    classList: [
                        {
                            name: "音乐会",
                            second: [11, 11, 11, 11, 11, 11, 11]
                        },
                        {
                            name: "话剧歌剧",
                            second: [22, 22, 22, 22, 22, 22]
                        },
                        {
                            name: "演唱会",
                            second: [33, 33, 33, 333, 333]
                        },
                        {
                            name: "曲苑杂坛",
                            second: [44, 444, 444, 444, 444, 444, 444]
                        },
                        {
                            name: "展览休闲",
                            second: [55, 5, 555, 555, 555, 55]
                        },
                        {
                            name: "舞蹈芭蕾",
                            second: [66, 6, 66, 6, 6, 666, 666]
                        },
                        {
                            name: "体育",
                            second: [77, 77, 77, 777, 77]
                        },
                        {
                            name: "其他",
                            second: [88, 88, 88, 88, 888, 888, 8]
                        },
                        {
                            name: "儿童亲子",
                            second: [9, 999, 999, 999, 9]
                        },
                    ],
                    secondList: [],
                }
            },
            methods: {
                change(i) {
                    this.activeIndex = i;
                    this.secondIndex = -1;
                },
                change2(i) {
                    this.secondIndex = i;
                },
                change3() {
                    this.activeIndex = -1;
                    this.secondList = [];   // 清空子类
                },
                change4() {
                    this.cityIndex = -1
                },
                cityChange(e) {
                    this.cityIndex = e
                }
            },
            watch: {
                activeIndex() {
                    this.secondList = this.classList[this.activeIndex].second;
                },
                cityIndex(n, o) {
                    if (n == -1) this.nowCity = "全国"    // 当更新后的cityIndex为-1时
                    else this.nowCity = this.cityList[this.cityIndex]
                }
            }
        });
    </script>

css代码

        * {
            margin: 0;
            padding: 0;
            list-style: none;
            user-select: none;
        }

        ul {
            margin: 15px 0;
            width: 600px;
        }

        li,
        .cityMenu>span {
            padding: 5px 15px;
            cursor: pointer;
            display: inline-block;
        }

        .active {
            background-color: #f00;
            color: #fff;
        }

        .box {
            width: 800px;
        }

        .cityMenu {
            margin: 15px 0;
        }

        .all {
            width: 80px;
            padding: 22px 0 15px;
            overflow: hidden;
        }

        .all>span {
            padding: 5px 15px;
            cursor: pointer;
        }

        .cityMenu>i {
            color: #666;
            margin-right: 8px;
        }
        .box{
            border: 1px solid;
            margin: 100px auto;
            padding: 10px;
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值