Vue~props、嵌套生命周期、组件边界处理、动画、DOM加载

一,props自定义属性

组件传值的过程中,会涉及到自定义属性的使用;除了基本的数组格式之外,我们有多种使用方式

1, 子组件中,可以给自定义属性指定类型、指定默认数据

<template>
  <div class="c-container">
    <h3>子组件</h3>
    <p>接受的父组件基本类型数据:{{ msg }} </p>
    <p>接受的父组件数组数据:{{ techs }}</p>
  </div>
</template>

<script>
export default {
  // 1、基本语法
  // props: ['msg', 'techs']

  // 2、指定类型
  // props: {
  //   msg: String,
  //   techs: Array
  // }

  // 3、指定默认值:如果是数组或者对象,必须通过函数指定默认值
  props: {
    msg: {
      type: String,
      default: '默认数据'
    },
    techs: {
      type: Array,
      default: () => {
        return ['默认数组']
      }
    }
  }
}
</script>

<style>

</style>

2,props父组件传递给子组件数据,子组件默认不能修改父组件数据【单向数据流】

  • 默认情况下,父组件传递数据给子组件,单向数据流;子组件不能直接修改父组件传递的数据
  • 子组件中需要使用修改父组件传递的数据,可以在data选项中对自定义属性重新赋值,操作data数据
  • 子组件中需要父组件传递的数据参与运算,可以在computed选项中添加计算属性
<template>
  <div class="c-container">
    <h3>子组件</h3>
    <p>接受的父组件基本类型数据:{{ msg }} </p>
    <p>接受的父组件数组数据:{{ techs }}</p>
    <p>接受并赋值的数据:{{ myMsg }}</p>
    <p>接受并运算的数据:{{ transfer }}</p>
    <button @click="myMsg='new data'">修改父组件数据</button>
  </div>
</template>

<script>
export default {
  // 3、指定默认值:如果是数组或者对象,必须通过函数指定默认值
  props: {
    msg: {
      type: String,
      default: '默认数据'
    },
    techs: {
      type: Array,
      default: () => {
        return ['默认数组']
      }
    }
  },
  data() {
    return {
      // 如果只是要使用父组件数据,可以将父组件数据接收到自己的数据中
      myMsg: this.msg
    }
  },
  computed: {
    // 如果需要父组件数据参与运算,通过计算属性完成数据运算,不要直接修改父组件数据
    transfer() {
      return this.msg + "新数据处理"
    }
  }
}
</script>

<style>

</style>

二,嵌套生命周期

问题:当出现父子组件嵌套关系时,父子组件各自都有独立的生命周期,他们的生命周期执行顺序是什么样的?关注重点- 父组件的生命周期、子组件的生命周期 -- 混合

  • 父组件:beforeCreate()
  • 父组件:created()
  • 父组件:beforeMount()
    • 子组件:beforeCreate()
    • 子组件:created()
    • 子组件:beforeMount()
    • 子组件:mounted()
  • 父组件:mounted()
<template>
  <div class="c-container">
    <h2>父组件</h2>
    <Child2/>
  </div>
</template>

<script>
import Child2 from '../components/Child2.vue'
export default {
  components: {
    Child2
  },
  beforeCreate() {
    console.log("1.父组件 beforeCreate")
  },
  created() {
    console.log("2.父组件 created")
  },
  beforeMount() {
    console.log("3.父组件 beforeMount")
  },
  mounted() {
    console.log("4.父组件 mounted")
  },
  beforeUpdate(){},
  updated() {},
  beforeDestroy() {},
  destroyed() {}
}
</script>

<style>

</style>

三,组件边界处理

核心:数据访问和数据传递问题

1,$root,可以在任意组件中,直接访问根组件数据

2,$parent,允许子组件中直接通过该属性访问和修改父组件中的数据,一般不推荐

   问题:默认情况下,Vue中父组件给子组件传递数据,是单向数据流,那么子组件是否可以直接     修改父组件中的数据?

   父子组件传值时,如果通过自定义属性的方式传递给子组件数据,子组件不可以修改父组件数       据;但是边界传值中可以在子组件中直接通过$parent属性修改父组件中的数据,如果没有必要     不会推荐这样的操作,会导致数据管理比较混乱;项目中推荐子组件通过自定义事件方式让父组     件主动修改数据

3,ref,允许父组件可以直接操作子组件中的数据,推荐

   ref,允许父组件可以直接操作子组件中的数据,推荐

4,$forceUpdate,控制强制更新

<template>
  <div class="d-container">
    <h2>$forceUpdate数据强制更新</h2>
    <p>数据:{{ techs }}</p>
    <button @click='add1'>标准方式修改数据</button>
    <button @click='add2'>索引方式添加数据</button>
    <button @click='add3'>内建函数set完成索引更新</button>
  </div>
</template>

<script>
import Vue from 'vue'

export default {
  data() {
    return {
      techs: ['javascript']
    }
  },
  methods: {
    add1() {
      // 标准函数添加数据
      this.techs.push('nodejs')
    },
    add2() {
      // 索引方式添加数据
      this.techs[1] = 'express'
      console.log(this.techs)
      // 不依赖vue本身更新方式,强制更新
      this.$forceUpdate()
    },
    add3() {
      // 内建函数完成数据更新:只需要知道即可,Vue3中废弃
      // this.$set(this.techs, 1, 'java')
      // Vue原型对象上的set()函数,通过索引添加数据
      Vue.set(this.techs, 1, 'python')
    }
  }
}
</script>

<style>

</style>

四,动画

1,通用动画

VUE提供了一种简单的页面切换动画,内建了一些通用动画样式可以直接使用

.v-enter{}			进入前
.v-enter-active{}		进入中
.v-enter-to{}			进入后

.v-leave{}			离开前
.v-leave-active{}		离开中
.v-leave-to{}			离开后

上述样式会针对组件中出现的所有包含在<transition></transition>标签的单个元素产生动画效果

<transition>
	<component :is="page"></component>
</transition>

2,命名动画

可以针对不同的需要定制的动画,进行命名来区别

.myname-enter{}			进入前
.myname-enter-active{}		进入中
.myname-enter-to{}		进入后

.myname-leave{}			离开前
.myname-leave-active{}		离开中
.myname-leave-to{}		离开后

只会针对如下的节点产生动画效果

<transition name="myname">
	<component :is="page"></component>
</transition>

3,列表动画

如果需要动画效果的元素不是单元素;而是列表元素,此时可以通过如下方式进行操作:

<transition-group name="myname">
	<tr v-for="..." :key="...">...</tr>
</transition-group>

如果需要一些较为复杂的动画效果,可以借助第三方动画插件:animate.css

五,DOM加载

项目组件中,经常会遇到这样一种,需要指定节点的DOM加载成功后再去操作数据

1,延时加载

通过setTimeout()延时函数,产生一个加载时间差,让对应的DOM元素加载成功后设置对应的数据,即使不指定延时事件~函数的执行也是需要时间的,所以延时延时的操作可以给DOM元素设置数据的,但是不推荐

setTimeout(function() {
	this.$refs.input.value = "xxxx"
})

2,nextTick

Vue.nextTick()以及this.$nextTick()都是等待当前组件DOM更新结束后再去执行的函数,一般用于等待DOM更新结束后执行对应的操作,通过回调函数实现

// 1、this.$nextTick()不能在普通函数中,等待子组件加载完成再去执行

// 2、Dialog.nextTick()在组件上直接调用nextTick()不可行

// 3、通过缓存方式直接操作子组件DOM元素,不可行

原因:

nextTick()底层工作原理等待当前组件mounted()执行结束再去执行回调函数

  • 子组件在某个单击事件发生时,加载子组件;父组件nextTick()会等待自组件加载完成后再去执行代码吗?
  • nextTick()一般会在created()mounted()生命周期中使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值