Vue学习笔记(二)组件、过渡

1.计算属性

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护,因此负责逻辑放在计算属性中来写,必须要有return,只能做同步,立即得到结果。

计算属性与函数的区别
计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。也就是只要 myName还没有发生改变,多次访问 reversedMessage计算属性会立即返回之前的计算结果,而不必再次执行函数。而函数则会调用几次就计算几次。

<div id="box">
    {{myComputedName}}
</div>
<script>
    new Vue({
        el: "#box",
        data: {
            myName: "abc"
        },
        computed: {
            myComputedName() {
            	//功能是将首字母大写
                return myName.substring(0, 1).toUpperCase() + myName.substring(1,);
            }
        }
    })
</script>

计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:

computed: {
    myComputedName: {
        // getter
        get: function () {
            return this.myName;
        },
        // setter
        set: function (newValue) {
            this.myName = newValue;
        }
    }
}

当在浏览器控制台上给myComputedName赋值时,setter会被调用,myName也会被更新。

2.侦听器

Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。如下例:myText是被监听的状态。

// 重视过程,监听一个值得改变,不用返回值,异步同步
watch: {
    myText(newval, oldval){ //新value值,老value值
        setTimeout(() => {
            this.list = this.dataList.filter(item => item.includes(newval))
        }, 2000)
    }
},

3.组件

注册组件

组件命名规范:

你给予组件的名字可能依赖于你打算拿它来做什么。当直接在 DOM 中使用一个组件 (而不是在字符串模板或单文件组件) 的时候,我们强烈推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)。这会帮助你避免和当前以及未来的 HTML 元素相冲突。

注意:

  1. 组件起名字若用驼峰写法,在html中调用的时候必须用 -连接
  2. template只能有一个根节点
  3. 组件之间是孤岛,无法直接访问组件的状态或方法
<script>
    // 全局定义navbar组件
    Vue.component("nav-bar", {
        // 定义html模板,只能写行内样式
        template: `<div style="background-color:red"></div>`,
        //data必须是函数写法 
        data() {
            return {
                myText: "1111"
            }
        },
        methods: {},
        computed: {},
        watch: {},
        // 给navbar定义子组件,只能在navbar中模板内调用
        components: {
            "child": {
                template: `<div style="background-color:yellow">child</div>`
            }
        }
    })
        
</script>

动态组件

动态选择组件,每次切换都会销毁切换钱的组件,没有复用 ,若有input框切换后不会保留输入的内容 <component :is="which"></component>这样写会保证不会销毁切换前的组件,输入的内容在切换后得以保存。

<div id="box">
        <button @click="which='list'">list</button>
        <button @click="which='home'">home</button>
        <button @click="which='bar'">bar</button>

        
        <keep-alive>
            <component :is="which"></component>
        </keep-alive>
    </div>
    <script>
        Vue.component("home", {
            template: `
                <div>
                    home
                    <input type="text">
                </div>`

        })

        Vue.component("list", {
            template: `
                <div>
                    list
                </div>`

        })

        Vue.component("bar", {
            template: `
                <div>
                    bar
                </div>`

        })

        // 根组件
        new Vue({
            el: "#box",
            data: {
                which: "home"

            }
        })
    </script>

组件间通信

每个组件都是一座孤岛,组件之间不能直接传递信息,但是可通过间接通信传递信息。

父组件传信息给子组件,是通过使用子组件时定义一个属性,再由子组件props接收。所有的 props都使得其父子 props 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。

类型检查中 type 可以是下列原生构造函数中的一个:

String
Number
Boolean
Array
Object
Date
Function
Symbol

<div id="box">
    <navbar myname="aaa" :istrue="true"></navbar>
    <navbar myname="bbb" :istrue="false"></navbar>
</div>
<script>
    // 全局定义navbar组件
    Vue.component("navbar", {
        // navbar子组件接收父组件(根组件)传来的属性myName
        // props:["myname"],

        // 类型验证方法
        // props: {
        //     myname:Boolean
        // },

        //属性验证,默认属性
        props: {
            myname: String,
            default: true
        },
        // 定义html模板,只能写行内样式
        template: `<div style="background-color:red">
                        <button @click="left" v-show="istrue">left</button>
                        {{myname}}
                        {{myText}}
                        123
                        </div>`,
        //data必须是函数写法 
        data() {
            return {
                myText: "1111",
                istrue: ""
            }
        },
        methods: {
            left() {
                console.log("left");
            }
        },
    })

    // 根组件
    new Vue({
        el: "#box"
    })
</script>

子组件给父亲传递信息,是通过在使用子组件时绑定一个事件。使用$emit(“父组件中事件名”, 返回参数)

<div id="box">
    <navbar @show="handleshow"></navbar>
</div>
<script>
    // 父传子用属性
    // 子传父使用事件绑定,this.$emit("事件名",参数)触发事件
    // 注册navbar子组件
    Vue.component("navbar", {
        template: `<div>
                        <button @click="handleClick">点击</button>
                    </div>`,
        methods: {
            handleClick() {
                this.$emit("show", 10000);
            }
        }
    })
    // 根组件(父组件)
    new Vue({
        el: "#box",
        data: {
            isTrue: true
        },
        methods: {
            handleshow(value) {
                this.isTrue = !this.isTrue;
                console.log(value);
            }
        }
    })
</script>

插槽

当组件渲染的时候, 将会被替换为组件标签间的内容。插槽内可以包含任何模板代码,包括 HTML:

<div id="box">
    <child>
        <!-- 具名插槽,指定位置 -->
        <!-- <button slot="a">a</button> -->

        <!-- 无名插槽,将button全部塞进插槽-->
        <!-- <button>a</button>
            <button>b</button> -->

        <!-- 新版slot用法 -->
        <template>
            <button>a</button>
        </template>
    </child>
</div>
<script>
    Vue.component("child", {
        template: `
            <div>
                <slot name="a"></slot>
                <slot></slot>
            </div>`,
    })
    // 根组件
    new Vue({
        el: "#box",
    })
</script>

4.过渡

在进入/离开的过渡中,会有 6 个 class 切换。

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter被移除),在过渡/动画完成之后移除。
  4. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave被删除),在过渡/动画完成之后移除。

动画样式

<style>
    .w-enter-active {
        animation: test 1.5s;
    }
    .w-leave-active {
        animation: test 1.5s reverse;
    }
	//定义关键帧
    @keyframes test {
        0% {
            opacity: 0;
            transform: translateX(100px);
        }

        100% {
            opacity: 1;
            transform: translateX(0);
        }
    }
</style>

过渡普通写法

<transition enter-active-class="w-enter-active" leave-active-class="w-leave-active">
    <div v-show="isTrue">111111</div>
</transition>

简写,添加name后会在显示过渡时自动寻找w-enter-active类,离开时同样自动寻找w-leave-active

<transition name="w">
    <div v-show="isTrue">22222</div>
</transition>

增加默认效果,在页面加载完成的时候就显示过渡效果

<transition name="w" appear>
    <div v-show="isTrue">22222</div>
</transition>

多个过渡,只针对在同一时间只能显示一个, 必须加key或不同的标签才有过渡效果

<transition name="w">
    <div v-if="isTrue" key="1">333333</div>
    <div v-else key="2">444444</div>
</transition>

让过渡先进后出或先出后进mode=“in-out”/mode=“out-in”

<transition name="w" mode="in-out">
    <div v-if="isTrue" key="1">333333</div>
    <div v-else key="2">444444</div>
</transition>

多个组件之间切换添加过渡效果component

当有相同标签名的元素切换时,需要通过 key attribute 设置唯一的值来标记以让 Vue 区分它们,否则 Vue
为了效率只会替换相同标签内部的内容。

当多个组件切换时会销毁切换前的组件,若组件中有输入框并且输入了内容,那么切换别的组件再切换回去,输入的内容会丢失,而keep-alive标签是让切换前的标签继续存活,这样输入的内容就不会丢失了,提高了用户体验。

    <!-- 给组件切换添加动画 -->
    <keep-alive>
        <transition name="w" mode="out-in">
        	<!--此组件可通过动态绑定is属性改变使用的组件-->
            <component :is="which"></component>
        </transition>
    </keep-alive>

列表过渡

<!-- 方法一 -->
<!-- <ul v-show="dataList.length">
            <transition-group name="w">
                <li v-for="(data, index) in dataList" :key="data">
                    {{data}}
                    <button @click="handleDel(index)">del</button>
                </li>
            </transition-group>
        </ul> -->

<!-- 方法二 -->
<!-- 将transition-group改为ul标签 -->
<transition-group name="w" tag="ul" v-show="dataList.length">
    <li v-for="(data, index) in dataList" :key="data">
        {{data}}
        <button @click="handleDel(index)">del</button>
    </li>
</transition-group>

状态过渡

<div id="box">
  <input v-model.number="number" type="number" step="20">
  <p>{{ animatedNumber }}</p>
</div>
<script>
    new Vue({
        el: '#box',
        data: {
            number: 0,
            tweenedNumber: 0
        },
        computed: {
            animatedNumber: function () {
                return this.tweenedNumber.toFixed(0);
            }
        },
        watch: {
            number: function (newValue) {
                gsap.to(this.$data, { duration: 0.5, tweenedNumber: newValue });
            }
        }
    })
</script>

Tip

加油,兄弟们!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值