Day_03 Vue学习

Day_03 Vue学习

1.计算属性

1.1 定义:

要用的属性不存在,要通过已有属性计算得来。

1.2.原理:

底层借助了Objcet.defineproperty方法提供的getter和setter。

<body>
    <div id="root"> 姓:
        <input type="text" v-model="firstName"><br/> 名:
        <input type="text" v-model="lastName"><br/> 全名:
        <!--这里的fullname是计算属性中的fullName函数中get返回值名称-->
        <span>{{fullName}}</span><br/> 全名:
        <span>{{fullName}}</span><br/> 全名:
        <span>{{fullName}}</span><br/> 全名:
        <span>{{fullName}}</span><br/> 全名:
        <span>{{fullName}}</span>
    </div>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三'
            },
            //计算属性中,vm会自己去找到这个函数的get属性,
            //然后把返回值给到fullName,不用我们自己去调用get
            computed: {
                fullName: {
                    //get作用?
                    //当有人读取fullname时,get就会被调用,
                    //返回值就是fullName的值
                    get() {
                        //此处的this是vm,函数一定不写箭头函数
                        console.log('get被调用了');
                        return this.firstName + '-' + this.lastName;
                    },
                    //这个set不是必须的,什么时候调动,当fullName被修改的时候
                    set(value) {
                        console.log('set被调用了', value);
                        this.firstName = value.split('-')[0];
                        this.lastName = value.split('-')[1];
                    }
                }
            }
        })
    </script>
</body>
1.3.get函数什么时候执行?
  • 初次读取时会执行一次。
  • 当依赖的数据发生改变时会被再次调用。

在这里插入图片描述

1.4.优势:

与methods实现相比,内部有缓存机制,效率更高,调试方便。

<body>
    <div id="root"> 姓:
        <input type="text" v-model="firstName"><br/> 名:
        <input type="text" v-model="lastName"><br/> 全名:
        <!-- 当函数用作指令去调用的时候括号就是可写可不写的
        但是要是用作模板方法去取值的话,那就必须写括号了,这样才能得到返回值
        -->
        <span>{{fullName()}}</span><br/> 全名:
        <span>{{fullName()}}</span><br/> 全名:
        <span>{{fullName()}}</span><br/> 全名:
        <span>{{fullName()}}</span><br/> 全名:
        <span>{{fullName()}}</span>
        <!-- 只要data中的值发生变化那么vue一定会去重新解析模板 -->
    </div>
    <script>
        new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三'
            },
            methods: {
                // 这个里面没有任何缓存而言调用几次方法,这个方法就执行几次
                fullName() {
                    console.log('函数被调用了')
                    return this.firstName + '-' + this.lastName;
                }
            }
        })
    </script>
</body>

在这里插入图片描述

注意事项

  • 计算属性最终会出现在vm上,直接读取使用即可。
  • 如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生变化
1.5计算属性的简写形式
<body>
    <div id="root"> 姓:
        <input type="text" v-model="firstName"><br/> 名:
        <input type="text" v-model="lastName"><br/> 全名:
        <span>{{fullName}}</span><br/> 全名:
        <span>{{fullName}}</span><br/> 全名:
        <span>{{fullName}}</span><br/> 全名:
        <span>{{fullName}}</span><br/> 全名:
        <span>{{fullName}}</span>
    </div>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三'
            },
            computed: {
                //完整写法
                // fullName: {
                //   get() {
                //         console.log('get被调用了');
                //         return this.firstName + '-' + this.lastName;
                //     },
                //     set(value) {
                //         console.log('set被调用了', value);
                //         this.firstName = value.split('-')[0];
                //         this.lastName = value.split('-')[1];
                //     }
                // }
                //简写形式,只有考虑读取,不考虑修改的前提下才能简写
                fullName() {
                    console.log('get被调用了');
                    return this.firstName + '-' + this.lastName;

                }
            }
        })
    </script>
</body>

注意事项

  • 在用插值语法的时候一定要看清楚所取得的数据在哪里
  • data中的直接拿
  • 指令中的函数,可以加括号或不加括号,那就代表调用函数的时候传不传参数
  • 计算属性中的函数,一定不带括号,因为vue实例会自动去调用函数生成返回值,我们直接写函数名就可以取到值

2.监视属性:

2.1 监视属性watch

  1. 当被监视的属性变化时,回调函数自动调用,进行相关操作

  2. 监视的属性必须存在,才能进行监视!!
    记算属性不存在也不报错,只是新旧值都是undefined

  3. 监视的两种写法:

    (1).new Vue时传入watch配置

    (2).通过vm.$watch监视

<body>
    <div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click='changeWeather'>切换天气</button>
    </div>
</body>
<script>
    const vm = new Vue({
        el: '#root',
        data: {
            isHot: true

        },
        //计算属性
        computed: {
            info() {
                return this.isHot ? '炎热' : '凉爽';
            }
        },
        methods: {
            changeWeather() {
                this.isHot = !this.isHot;
            }
        },
        //配置监视第一种方式
        // watch: {
        //      isHot: {
        //          //什么时候调用呢,当ishot发生改变时
        //          handler(newValue, oldValue) {
        //              console.log('ishot修改了', newValue, oldValue)
        //          },
        //          //默认是false,初始化时handler调用一下
        //          immediate: true
        //      },
        //监视info和isHot都是一样的
        //     info: {
        //         handler(newValue, oldValue) {
        //             console.log('info修改了', newValue, oldValue)
        //         },
        //     }
        // }
    })
    //配置监视第二种方式
    vm.$watch('isHot', {
        handler(newValue, oldValue) {
            console.log('ishot修改了', newValue, oldValue)
        }
    })
</script>

2.2深度监视:

  • Vue中的watch默认不监测对象内部值的改变(一层)。
  • 配置deep:true可以监测对象内部值改变(多层)。
<body>
    <div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click='changeWeather'>切换天气</button>
        <hr>
        <h3>a的值是:{{numbers.a}}</h3>
        <button @click="numbers.a++">点我a+1</button>
        <h3>b的值是:{{numbers.b}}</h3>
        <button @click="numbers.b++">点我b+1</button>
    </div>
</body>
<script>
    const vm = new Vue({
        el: '#root',
        data: {
            isHot: true,
            numbers: {
                a: 1,
                b: 1
            }
        },
        computed: {
            info() {
                return this.isHot ? '炎热' : '凉爽';
            }
        },
        methods: {
            changeWeather() {
                this.isHot = !this.isHot;
            }
        },
        //配置监视
        watch: {
            isHot: {
                handler(newValue, oldValue) {
                    console.log('ishot修改了', newValue, oldValue)
                }
            },
            //监视多级结构中某个属性的变化
            // 'numbers.a': {
            //     handler() {
            //         console.log('a被改变了')
            //     }
            // }
            //监视多级结构中所有的属性的变化
            numbers: {
                deep: true,//深度监测
                handler() {
                    console.log('numbers被改变了')
                }
            }
        }
    })
</script>

注意事项:

(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watchI时根据数据的具体结构,决定是否采用深度监视。

2.3监视属性的简写

<body>
    <div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click='changeWeather'>切换天气</button>
    </div>
</body>
<script>
    const vm = new Vue({
        el: '#root',
        data: {
            isHot: true
        },
        computed: {
            info() {
                return this.isHot ? '炎热' : '凉爽';
            }
        },
        methods: {
            changeWeather() {
                this.isHot = !this.isHot;
            }
        },
        watch: {
            // 完整写法
            // isHot: {
            //     // immediate: true, //初始化时让hander调用一下
            //     // deep: true, //深度监视
            //     handler(newValue, oldValue) {
            //         console.log('ishot修改了', newValue, oldValue)
            //     },
            // },

            //简写,只有当配置项只有handler的时候才能用
            isHot(newValue, oldValue) {
                console.log('ishot修改了', newValue, oldValue);
            }
        }
    })

    // //完整写法
    // vm.$watch('isHot', {
    //     immediate: true, //初始化时让hander调用一下
    //     deep: true, //深度监视
    //     handler(newValue, oldValue) {
    //         console.log('ishot修改了', newValue, oldValue)
    //     },
    // })

    //简写

    // vm.$watch('isHot', function(newValue, oldValue) {
    //     console.log('ishot修改了', newValue, oldValue)
    // })
</script>

注意事项:

所有vue管理的函数都要写成普通函数,否则vue中的this就是window了

2.4计算属性和监听属性比较

<!--姓名案例_computed实现:-->
<body>
    <div id="root"> 姓:
        <input type="text" v-model="firstName"><br/> 名:
        <input type="text" v-model="lastName"><br/> 全名:
        <span>{{fullName}}</span>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三'
            },
            computed: {
                fullName() {
                    console.log('get被调用了');
                    return this.firstName + '-' + this.lastName;
                }
            }
        })
    </script>
</body>
<!--姓名案例_watch实现:-->
<body>
    <div id="root"> 姓:
        <input type="text" v-model="firstName"><br/> 名:
        <input type="text" v-model="lastName"><br/> 全名:
        <span>{{fullName}}</span>
    </div>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三',
                fullName: '张-三'
            },
            //可以开启一个异步任务
            watch: {
                firstName(val) {
                    setTimeout(() => {
                        this.fullName = val + '-' + this.lastName
                    }, 1000)
                },
                lastName(val) {
                    this.fullName = this.firstName + '-' + val
                }
            }
        })
    </script>
</body>        

注意事项:

这个时候很明显计算属性比监测属性好用的多

需求:如果想当姓改变之后,全名1秒之后才改变

//计算属性只能这样写,那问题是:
//1.这样的话计算属性就没有返回值了,所以fullName就没有值啦
//2.这里的return相当于是箭头函数的返回值了
fullName() {
    console.log('get被调用了');
    setTimeout(() => {
        return this.firstName + '-' + this.lastName;
    }, 1000)

}

//可以开启一个异步任务
watch: {
    firstName(val) {
        //vue里面的只要是vue不监管的函数一定要写成箭头函数
        //定时器的回调是js引擎帮我们调用的所以这里的this就是window
        setTimeout(() => {
            this.fullName = val + '-' + this.lastName
        }, 1000)
    },
    lastName(val) {
        this.fullName = this.firstName + '-' + val
    }
}

那这样的话监视属性就比计算属性好用

computed和watch之间的区别:

  1. computed能完成的功能,watch都可以完成。

  2. watch能完成的功能,computed不一定能完成,

    例如:watch可以进行异步操作。

两个重要的小原则:

  1. 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
  2. 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等),最好写成箭头函数。
  3. 这样this的指向才是vm 或 组件实例对象。

3 绑定样式

<body>
    <!-- 绑定class样式,--字符串写法,
        适用于:样式的类名不确定需要动态指定 
    -->
    <div id="root">
        <div class="basic" :class='mood' @click='changeMood'>
            {{name}}</div>
        <hr>

        <!-- 绑定class样式,--数组写法,
            适用于:要绑定的样式个数不确定,样式不确定 
        -->
        <div class="basic" :class='arr'>{{name}}</div>
        <hr>
        <!--  绑定class样式,--对象写法,
            适用于:要绑定的样式个数确定,名字确定 ,要动态决定用不用
        -->
        <div class="basic" :class='classObj'>{{name}}</div>
        <hr>
        <!-- 内联绑定样式 -->
        <div class="basic" :style="styleObj">{{name}}</div>
        <hr>
        <!-- 内联绑定数组对象 -->
        <div class="basic" :style="[styleObj,styleObj2]">{{name}}
          </div>
        <hr>
        <!-- 内联绑定数组对象2 -->
        <div class="basic" :style="styleArr">{{name}}</div>
    </div>
</body>
<script>
    const vm = new Vue({
        el: '#root',
        data: {
            name: '尚硅谷',
            mood: 'normal',
            arr: ['atguigu1', 'atguigu2', 'atguigu3'],
            classObj: {
                atguigu1: false,
                atguigu2: false
            },
            styleObj: {
                // 这里的key不能瞎写,就是css属性的小驼峰
                fontSize: '40px'
            },
            styleObj2: {
                color: 'red'
            },
            styleArr: [{
                // 这里的key不能瞎写,就是css属性的小驼峰
                fontSize: '40px'
            }, {
        // 没必要这样写,虽然也可以实现
        // methods: {
        //     changeMood() {
        //         const arr = ['happy', 'sad', 'normal'];
        //         const index = Math.floor(Math.random() * 3);
        //         this.mood = arr[index];
        //     }
        // },         this.mood = arr[index];
            }
        },
    })
</script>

绑定样式:
1.class样式
写法:class=“xxx” xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
2.style样式
:style="{fontSize:xxx}“其中xxx是动态值。
:style=”[a,b]"其中a、b是样式对象。

3.条件渲染

3.1v-if 写法:

(1).v-if=“表达式”

(2).v-else-if=“表达式”

(3).v-else=“表达式” 适用于:切换频率较低的场景。

<body>
    <div id='root'>
        <h2>当前的n值是{{n}}</h2>
        <button @click='n++'>点我n+1</button>
        <!-- 使用v-show做条件渲染,如果东西变化的频率高,那就用-->
        <h2 v-show="false"> 欢迎来到{{name}}</h2> 
        <h2 v-show="1===3"> 欢迎来到{{name}}</h2>

        <!--使用v-if做条件渲染,元素直接会不见了,频率低的用  -->
        <h2 v-if="false"> 欢迎来到{{name}}</h2> 
        <h2 v-if="1==1"> 欢迎来到{{name}}</h2> 
        <div v-if="n===1">Angular</div>
        <div v-else-if="n===1">你管我</div>
        <div v-if="n===2">React</div>
        <div v-if="n===3">Vue</div>
        <div v-else>哈哈哈</div>

        <!-- template只能配合v-if,不能配合v-show -->
        <template v-if='n===1'>
            <h2>你好</h2>
            <h2>尚硅谷</h2>
            <h2>北京</h2>
        </template>


    </div>
</body>
<script>
    const vm = new Vue({
        el: '#root',
        data: {
            name: '尚硅谷',
            // a: false,
            n: 1
        }
    })
</script>

特点:不展示的DOM元素直接被移除。

注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能断掉

3.2.v-show 写法:

(1)v-show=“表达式” 适用于:切换频率较高的场景。

特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。

<body>
    <div id='root'>
        <h2>当前的n值是{{n}}</h2>
        <button @click='n++'>点我n+1</button>
        <!-- 使用v-show做条件渲染,如果东西变化的频率高,那就用-->
        <h2 v-show="false"> 欢迎来到{{name}}</h2> 
        <h2 v-show="1===3"> 欢迎来到{{name}}</h2> 
    </div>
</body>
<script>
    const vm = new Vue({
        el: '#root',
        data: {
            name: '尚硅谷',
            // a: false,
            n: 1
        }
    })
</script>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值