Vue学习笔记(3)

目录

第一章:使用Vue脚手架

1.1 初始化脚手架

1.1.1 说明

1.1.2 具体步骤

1.1.3 项目模板结构

1.1.4 案例

1.2 有关render函数

1.3 修改默认配置

第二章:refs与props

2.1 refs

2.2 props

第三章:mixins混入

第四章:插件

 第五章:scoped样式

 第六章:自定义事件

6.1 使用

6.2 解绑自定义事件

6.3 一个注意点

6.4 总结 

第七章:全局事件总线(GlobalEventBus)

第七章:消息订阅与发布(pubsub)

第八章:过渡与动画


第一章:使用Vue脚手架

1.1 初始化脚手架

1.1.1 说明

1. Vue脚手架是Vue官方提供的标准化开发工具(开发平台)

2. 文档:https://cli.vuejs.org/zh/

1.1.2 具体步骤

第一步(仅第一次执行):全局安装@vue/cli

npm install -g @vue/cli

 第二步:切换到要创建项目的目录,然后使用命令创建项目

vue create xxxx

第三步:启动项目

npm run serve 

备注:

1. 如果出现下载缓慢,就配置 npm 淘宝镜像:

npm config set registry
https://registry.npm.taobao.org

2. Vue 脚手架隐藏了所有webpack相关的配置,如果想查看具体的 webpack 配置,执行:

vue inspect > output.js 

1.1.3 项目模板结构

├── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── component: 存放组件
│ │ └── HelloWorld.vue
│ │── App.vue: 汇总所有组件
│ │── main.js: 入口文件
├── .gitignore: git 版本管制忽略的配置
├── babel.config.js: babel 的配置文件
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件

1.1.4 案例

把Vue学习笔记(2)最后面中的案例在脚手架环境执行 ,现在组件的名字不能只用一个单词,所以我把Student改成了MyStudent,把School改成MySchool

1.2 有关render函数

在main.js文件中,使用render函数来使用App组件,是因为引入Vue的时候引入的是残缺版的vue,即'vue.runtime.xxx.js',使用template标签会报错,比如说按照下面的方式来使用App组件,控制台报错

new Vue({
  el: '#app',
  template: `<App></App>`,
  components:{
    App
  }
})

当创建项目之后,默认的main.js文件就是下面这个样子 

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

总结:
        1. vue.js 和 vue.runtime.xxx.js 的区别:

                1)vue.js 是完整版的Vue,包含:核心功能 + 模板解析器

                2)vue.runtime.xxx.js 是运行版的Vue,只包含:核心功能,没有模板解析器

        2. 因为 vue.runtime.xxx.js 没有模板解析器,所以不能使用 template 配置项,需要使用render函数接收到的createElement函数去指定具体内容

1.3 修改默认配置

如果想要修改默认的入口文件,或者其它一些webpack设置的默认配置,可以在vue.config.js来修改,下面这个案例设置了修改入口文件,并且将保存就检查错误关闭

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
  pages: {
    index: {
      // 入口
      entry: 'src/peiqi.js',
    }
  },
})

这样子修改main.js名字为peiqi.js也可以执行了,其他的一些配置可以去官网上查看

第二章:refs与props

2.1 refs

当给标签添加了ref属性后,在这个组件的实例对象上就有了refs属性,这里面保存了设置ref属性的DOM元素

如下面这个案例,分别给h1标签、button按钮、school子组件分别设置ref标签,点击按钮后输出

<template>
  <div>
    <h1 ref="title">{{msg}}</h1>
    <button ref="btn" @click="showDOM">点击获取DOM元素</button>
    <School ref="school"></School>
  </div>
</template>

<script>
import School from './components/School.vue'
export default {
  name: 'App',
  components: {
    School,
  },
  data(){
    return {
      msg: '欢迎学习Vue'
    }
  },
  methods:{
    showDOM(){
      console.log(this.$refs.title);
      console.log(this.$refs.btn);
      console.log(this.$refs.school);
    }
  }
}
</script>

总结:

        1. ref是被用来给元素或子组件注册引用信息(id的替代者)

        2. 应用在html标签上获取真实DOM元素,应用在组件标签上是组件实例对象

        3. 使用方式:

                打标识:<h1 ref="xxx">......</h1> 或 <School ref="xxx"></School>

                获取:this.$refs.xxx     

2.2 props

功能:让组件接收外部传过来的数据

        1)传递数据:

                <Demo name="xxx"/>

        2)接收数据:

                第一种方式(只接收):

                        props:[ 'name' ]

                第二种方式(限制类型):

                        props:{

                                name: Number

                        }

                第三种方式(限制类型、限制必要性、指定默认值):

                        props:{

                                name:{

                                        type:String,// 类型 

                                        required:true,// 必要性

                                        default:'老王' // 默认值

                                }

                        }

备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需要确实需要修改,那就复制props的内容到data中一份,然后去修改data中的数据 

 在下面这个案例中,Student组件接收name、sex和age属性,模拟业务需求要修改age,设置一个button按钮,点击让年龄++,在data中用myAge接收传过来的age,在结构中使用myAge属性

<template>
  <div>
    <h1>{{msg}}</h1>
    <h2>学生姓名:{{name}}</h2>
    <h2>学生性别:{{sex}}</h2>
    <h2>学生年龄:{{myAge + 1}}</h2>
    <button @click="myAge++">年龄++</button>
  </div>
</template>

<script>
export default {
  name: 'MyStudent',
  data() {
    return {
      msg: '我正在学习Vue',
      myAge: this.age
    }
  },
  // 简单声明接收
  // props:['name', 'sex', 'age']
  // 接收的同时对数据进行类型限制
  // props:{
  //   name: String,
  //   sex: String,
  //   age: Number
  // }
  // 接收的同时对数据进行类型限制 + 默认值的指定 + 必要性的限制
  props:{
    name: {
      type: String, // name 的类型是字符串
      required: true // name 是必要的
    },
    age:{
      type: Number,
      default: 99 // 默认值
    },
    sex: {
      type: String,
      required: true
    }
  }
}
</script>
<template>
  <div>
    <Student name="zs" sex="男" :age="18"></Student>
  </div>
</template>

<script>
import Student from './components/Student.vue'
export default {
  name: 'App',
  components: {
    Student
  }
}
</script>

第三章:mixins混入

功能:可以把多个组件公用的配置提取成一个混入对象

使用方式:

        第一步定义混合,例如:

                {

                        data(){......},

                        methods:{......}

                        ......

                }

        第二部使用混入,例如:

                1)全局混入:Vue.mixin(xxx)

                2)局部混入:mixins: [ 'xxx' ]

下面分别是Student和School组件

<template>
  <div>
    <h1>{{msg}}</h1>
    <h2 @click="showName">学生姓名:{{name}}</h2>
    <h2>学生性别:{{age}}</h2>
  </div>
</template>

<script>
import {hunru, hunru2} from '../mixin'
export default {
  name: 'MyStudent',
  data() {
    return {
      msg: '我正在学习Vue',
      name: '张三',
      age: 18
    }
  },
  mounted(){
    console.log('组件里面的mounted');
  },
  mixins:[hunru, hunru2]
}
</script>
<template>
  <div>
    <h2 @click="showName">学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
  </div>
</template>

<script>
import {hunru} from '../mixin'
export default {
  name: 'MySchool',
  data() {
    return {
      name: 'Vue',
      address: '上海',
    }
  },
   mixins:[hunru]
}
</script>

<style></style>

下面这个是共用的配置mixin.js

export const hunru = {
  methods:{
    showName(){
      alert(this.name)
    }
  },
  mounted() {
    console.log('hunru里面的mounted');
  },
}
export const hunru2 = {
  data(){
    return{
      age: 20
    }
  }
}

在这个共用的配置中,定义了showName函数,这样子导入hunru的组件都有了这个方法,定义mounted钩子,如果组件中也有钩子,此时先执行hunru的钩子,再执行组件中定义的钩子,如果定义了age属性,与组件中的age属性发生冲突,此时以组件中的为主,会覆盖掉hunru2里面的属性

如果定义了全局的混入,这样子所有的组件都有了混入里面定义的东西,不管是root还是App都是如此

比如说下面这个案例,定义了全局的混入里面的data有x和y,这样子Root、App、MySchool和MyStudent都有了x和y

Vue.mixin({
  data(){
    return{
      x: 100,
      y: 200
    }
  }
})

 

 

第四章:插件

功能:用于增强Vue

本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据

定义插件:

        对象.install = function (Vue, options) {

                // 1. 添加全局过滤器

                Vue.filter(......)

                // 2. 添加全局指令

                Vue.directive(......)

                // 3. 配置全局混入(合)

                Vue.mixin(......)

                // 4. 添加实例方法

                Vue.prototype.$myMethod = function () {......}

                Vue.prototype.$myProperty = xxxx

        }

使用插件:Vue.use()

下面这个案例,在src文件夹下创建一个plugins.js文件,作为一个插件,里面添加了全局的过滤器、全局指令、全局混入以及实例方法,这样子Vue可以直接使用里面定义的东西,在install函数中,第一个参数是Vue,后面的参数就是在导入了这个插件后可以传入的参数

export default {
  install(Vue, x, y, z) {
    console.log(Vue, x, y, z)

    // 全局过滤器
    Vue.filter('mySlice', function (value) {
      return value.slice(0, 4)
    })

    // 定义全局指令
    Vue.directive('fbind', {
      // 指令与元素成功绑定时
      bind(element, binding) {
        element.value = binding.value
      },
      // 指令所在的元素被插入页面时
      inserted(element) {
        element.focus()
      },
      // 指令所在的模板被重新解析时
      update(element, binding) {
        element.value = binding.value
      },
    })

    // 定义混入
    Vue.mixin({
      data(){
        return{
          age: 20
        }
      }
    })

    // 给原型上添加方法(Vue实例对象和组件实例对象就可以用了)
    Vue.prototype.hello = () => {
      alert('hello')
    }
  }
}

import install from './plugins'

Vue.use(install, 1, 2, 3)

在main.js中使用这个插件,并且传入参数,在控制台输出

 

 第五章:scoped样式

作用:让样式在局部生效,防止冲突

写法:<style scoped></style>

因为不同的组件中使用了相同的类名并且定义了样式,此时使用的时候可能会有冲突,加上了scoped之后,会在这个组件的标签里面添加一个属性,然后组件的样式就会添加一个属性选择器,比如说demo这个类,在添加了scoped就变成了 .demo[data-v-22321ebb],例如下面这个案例,不添加scoped,最重添加demo类的背景颜色就会取决于app组件中先导入了哪个组件,后面的样式会覆盖前面的

 

 给两个组件的style都加上scoped,此时就不会有冲突了,并且选择器后面都会添加上一个属性选择器

 

 第六章:自定义事件

6.1 使用

要实现子给父传递数据,有两种方式,一种是通过传递函数类型的prop实现,比如下面的案例,给School传送了getSchoolName的函数,在School组件中,通过点击事件触发传过来的函数,然后把它的name属性传递给父组件,实现了子给父传递数据;另一种是通过自定义事件,先在App组件里面定义一个getStudentName的函数,在Student的标签里面定义自定义事件,模板是 v-on:xxx="xxx" ,第一个xxxx是自定义的,第二个xxx是在自己组件定义的函数,然后在Student组件中,给按钮绑定点击事件,当点击了之后,触发sendStudentName函数,函数体是 “this.$emit('get', this.name)”,这里的get就是自定义的事件,是在App组件中定义的,通过组件实例对象的$emit触发get事件,后面是它的参数

// App.vue
<template>
  <div>
    <!-- 通过父组件给子组件传递函数类型的prop实现:子给父传递数据 -->
    <School :getSchoolName="getSchoolName"></School>
    <hr>
    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法:使用@或v-on) -->
    <Student v-on:get="getStudentName"></Student>
    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法:使用ref) -->
    <!-- <Student ref="student"></Student> -->
  </div>
</template>

<script>
import Student from './components/Student.vue'
import School from './components/School.vue'
export default {
  name: 'App',
  components: {
    Student,
    School
  },
  methods:{
    getSchoolName(name){
      console.log('APP接收到了学校名', name);
    },
    getStudentName(name){
      console.log('APP接收到了学生姓名', name);
    }
  },
  mounted(){
    // this.$refs.student.$on('get', this.getStudentName)
  }
}
</script>

<style></style>
// School.vue
<template>
  <div class="demo">
    <h2>学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
    <button @click="sendSchoolName">点我获取学校名</button>
  </div>
</template>

<script>
export default {
  name: 'MySchool',
  props:['getSchoolName'],
  data() {
    return {
      name: 'Vue',
      address: '上海',
    }
  },
  methods:{
    sendSchoolName(){
      this.getSchoolName(this.name)
    }
  }
}
</script>

<style scoped>
  .demo{
    background-color: skyblue;
  }
</style>
// Student.vue
<template>
  <div class="demo">
    <h1>{{msg}}</h1>
    <h2>学生姓名:{{name}}</h2>
    <h2>学生性别:{{age}}</h2>
    <button @click="sendStudentName">点我获取学生名</button>
  </div>
</template>

<script>
export default {
  name: 'MyStudent',
  data() {
    return {
      msg: '我正在学习Vue',
      name: '张三',
      age: 18
    }
  },
  methods:{
    sendStudentName(){
      this.$emit('get', this.name)
    }
  }
}
</script>

<style scoped>
  .demo{
    background-color: pink;
  }
</style>

 自定义事件的v-on可以简写成@,除了这种方式外还有ref实现的,给Student加上ref属性,在mounted钩子中可以通过$refs获取这个对象然后通过$on的方式定义自定义函数‘get’,后面是当组件实例对象触发了get函数之后在App组件中调用的函数,通过这种方式会更加灵活,比如说可以绑定异步事件,定义5秒钟之后再绑定这个自定义事件......

<Student ref="student"></Student>
...
...
...
  mounted(){
    this.$refs.student.$on('get', this.getStudentName)
  }

除此之外,还有一个API可以让自定义事件只触发一次,就是once

// 这是第一种写法
<Student v-on:get.once="getStudentName"></Student>
// 这是第二种写法
this.$refs.student.$once('get', this.getStudentName)

6.2 解绑自定义事件

通过$off()解绑自定义事件,复用上面的Student组件,创建一个button按钮,点击后解绑get自定义事件

<template>
  <div class="demo">
    <h1>{{msg}}</h1>
    <h2>学生姓名:{{name}}</h2>
    <h2>学生性别:{{age}}</h2>
    <button @click="sendStudentName">点我获取学生名</button>
    <button @click="unbind">点我解绑get事件</button>
  </div>
</template>

<script>
export default {
  name: 'MyStudent',
  data() {
    return {
      msg: '我正在学习Vue',
      name: '张三',
      age: 18
    }
  },
  methods:{
    sendStudentName(){
      this.$emit('get', this.name)
    },
    unbind(){
      this.$off('get')
    }
  }
}
</script>

<style scoped>
  .demo{
    background-color: pink;
  }
</style>

如果要解绑多个自定义事件,传入要解绑的自定义事件的数组,如 this.$off(['xxx', 'yyy', 'zzz'])

如果要解绑所有的自定义事件,此时只要不传入参数即可,即 this.$off()

6.3 一个注意点

如果想要给一个组件绑定点击事件,本来的话应该写成

<Student ref="student" @click='xxx'></Student>

 但是这样写的话会认为‘click’是自定义事件的名称,如果想要给Student绑定点击事件,就在点击事件后面加上'.native',即

<Student ref="student" @click.native='show'></Student>

6.4 总结 

组件的自定义事件

1. 一种组件间通信的方式,适用于:子组件 ==> 父组件

2. 使用场景:A是父组件,B是子组件,那么B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中

3. 绑定自定义事件

        1)第一种方式,在父组件中:<Demo @xxx="test"/> 或 <Demo v-on:xxx="test"/>

        2)第二种方式,在父组件中:

                <Demo ref="demo" />

                ......

                mounted(){

                        this.$refs.demo.$on('xxx', this.test)

                }

        3)如果想让自定义事件只能触发一次,可以使用once修饰符,或$once方法

4. 触发自定义事件:this.$emit('xxx',数据)

5. 解绑自定义事件:this.$off('xxx')

6. 组件上也可以绑定元素DOM事件,需要使用 native 修饰符

7. 注意:通过 this.$refs.xxx.$on('xxx', 回调) 绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this的指向会出问题! 

第七章:全局事件总线(GlobalEventBus)

1. 一种组件间通信的方式,适用于任意组件间的通信

2. 安装全局事件总线:

        new Vue({

                ......

                beforeCreate(){

                        Vue.prototype.$bus = this // 安装全局事件总线,$bus就是当前应用的vm

                }

                ......

        })

3. 使用事件总线:

        1)接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身

        methods:{

                demo(data) { ...... }

        }

        ......

        mounted() {

                this.$bus.$on('xxxx', this.demo)

        }

        2)提供数据: this.$bus.$emit('xxxx', 数据)

4. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件

在下面这个案例中,main.js中安装了全局事件总线,在School组件中,创建了自定义事件“hello”,接收传过来的数据,后面可以用methods中的函数或者使用箭头函数,在Student组件中,点击按钮后调用了$emit事件,传入自定义事件“hello”并且传过去参数,在School可以接受到;在School组件被销毁前,在beforeDestroy钩子中用$off解绑自定义事件

// main.js
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  beforeCreate(){
    Vue.prototype.$bus = this
  }
}).$mount('#app')
// School.vue
<template>
  <div class="demo">
    <h2>学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
  </div>
</template>

<script>
export default {
  name: 'MySchool',
  data() {
    return {
      name: 'Vue',
      address: '上海',
    }
  },
  mounted(){
    this.$bus.$on('hello', data => {
      console.log('我是School组件,收到了数据:' + data);
    })
  },
  beforeDestroy(){
    this.$bus.$off('hello')
  }
}
</script>

<style scoped>
  .demo{
    background-color: skyblue;
  }
</style>
// Student.vue
<template>
  <div class="demo">
    <h1>{{msg}}</h1>
    <h2>学生姓名:{{name}}</h2>
    <h2>学生性别:{{age}}</h2>
    <button @click="sendStudentName">把学生名传给School组件</button>
  </div>
</template>

<script>
export default {
  name: 'MyStudent',
  data() {
    return {
      msg: '我正在学习Vue',
      name: '张三',
      age: 18
    }
  }
  methods:{
    sendStudentName(){
      this.$bus.$emit('hello', this.name)
    }
  }
}
</script>

<style scoped>
  .demo{
    background-color: pink;
  }
</style>

第七章:消息订阅与发布(pubsub)

1. 一种组件间通信的方式,适用于任意组件间的通信

2. 使用步骤:

        1)安装pubsub:npm i pubsub-js

        2)引入:import pubsub from 'pubsub-js'

        3)接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身

                methods:{

                        demo(data) { ...... }

                }

                ......

                mounted() {

                        this.pid = pubsub.subscribe('xxx', this.demo) // 订阅消息

                }

        4)提供数据:pubsub.publish('xxx', 数据)

        5)最好在beforeDestroy钩子中,用 pubsub.unsubscribe(pid)取消订阅

在下面这个案例中,从Student组件向School传递数据, School组件通过pubsub.subscribe()的方式订阅消息‘hello’,后面的回调函数要么定义在methods中,要么使用箭头函数,如果使用function的话,函数内部的this是unefined;Student组件传递数据,通过pubsub.publish()的方式发送消息‘hello’,数据跟在后面

// School.js
<template>
  <div class="demo">
    <h2>学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
  </div>
</template>

<script>
import pubsub from 'pubsub-js'
export default {
  name: 'MySchool',
  data() {
    return {
      name: 'Vue',
      address: '上海',
    }
  },
  mounted(){
    // console.log('school', this.x);
    // this.$bus.$on('hello', data => {
    //   console.log('我是School组件,收到了数据:' + data);
    // })
    this.pubId = pubsub.subscribe('hello', (msgName, data) => {
      console.log('接收到了消息', msgName, data);
    })
  },
  beforeDestroy(){
    // this.$bus.$off('hello')
    pubsub.unsubscribe(this.pubId)
  }
}
</script>

<style scoped>
  .demo{
    background-color: skyblue;
  }
</style>
<template>
  <div class="demo">
    <h1>{{msg}}</h1>
    <h2>学生姓名:{{name}}</h2>
    <h2>学生性别:{{age}}</h2>
    <button @click="sendStudentName">把学生名传给School组件</button>
  </div>
</template>

<script>
import pubsub from 'pubsub-js'
export default {
  name: 'MyStudent',
  data() {
    return {
      msg: '我正在学习Vue',
      name: '张三',
      age: 18
    }
  },
  mounted(){
    // console.log('student', this.x);
  },
  methods:{
    sendStudentName(){
      // this.$bus.$emit('hello', this.name)
      pubsub.publish('hello', this.name)
    }
  }
}
</script>

<style scoped>
  .demo{
    background-color: pink;
  }
</style>

第八章:过渡与动画

1. 作用:在插入、更新或移除 DOM元素时,在合适的时候给元素添加样式类名。

2. 图示:

3. 写法:

       

  1. 准备好样式:

    • 元素进入的样式:

      1. v-enter:进入的起点

      2. v-enter-active:进入过程中

      3. v-enter-to:进入的终点

    • 元素离开的样式:

      1. v-leave:离开的起点

      2. v-leave-active:离开过程中

      3. v-leave-to:离开的终点

  2. 使用<transition>包裹要过度的元素,并配置name属性:

    <transition name="hello">
        <h1 v-show="isShow">你好啊!</h1>
    </transition>
  3. 备注:若有多个元素需要过度,则需要使用:<transition-group>,且每个元素都要指定key值。

下面三段代码分别是Test、Test2、Test3,在Test1中定义了一个动画,用transition包裹一个h1标签,当它进入的时候从左往右

Test2组件中,使用css样式来定义动画,使用tranrition-group,因为内部有两个标签,它们两个是交错显示的

Test使用了第三方组件库 animation.css ,最终的动画效果如下 

<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <transition appear>
      <h1 v-show="isShow" class="go">你好啊</h1>
    </transition>
  </div>
</template>

<script>
export default {
  name: 'MyTest',
  data(){
    return{
      isShow: true
    }
  }
}
</script>

<style>
  h1{
    background-color: pink;
  }

  .v-enter-active{
    animation: move 1s ;
  }

  .v-leave-active{
    animation: move 1s reverse;
  }
  
  @keyframes move {
    from{
      transform: translateX(-100%);
    }
    to{
      transform: translate(0);
    }
  }
</style>
<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <transition-group name="hello" appear>
      <h1 v-show="!isShow" class="go" key="1">你好啊</h1>
      <h1 v-show="isShow" class="go" key="2">你好啊</h1>
    </transition-group>
  </div>
</template>

<script>
export default {
  name: 'MyTest2',
  data() {
    return {
      isShow: true,
    }
  },
}
</script>

<style>
h1 {
  background-color: pink;
}

/* 进入的起点、离开的终点 */
.hello-enter,
.hello-leave-to {
  transform: translateX(-100%);
}

.hello-enter-active,.hello-leave-active {
  transition: 0.5s linear;
}

/* 进入的终点、离开的起点 */
.hello-enter-to,
hello-leave {
  transform: translateX(0);
}
</style>
<template>
  <div>
    <button @click="isShow = !isShow">显示/隐藏</button>
    <transition-group 
      appear 
      name="animate__animated animate__bounce" 
      enter-active-class="animate__bounceIn" 
      leave-active-class="animate__bounceOutDown"
    >
      <h1 v-show="!isShow" class="go" key="1">你好啊</h1>
      <h1 v-show="isShow" class="go" key="2">你好啊</h1>
    </transition-group>
  </div>
</template>

<script>
import 'animate.css'
export default {
  name: 'MyTest2',
  data() {
    return {
      isShow: true,
    }
  },
}
</script>

<style>
h1 {
  background-color: pink;
}
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值