vue2.0——第四天(组件生命周期、组件之间的数据共享、ref引用、购物车案例)

目录

1、组件生命周期

1.1 生命周期 & 生命周期函数

1.2组件生命周期函数的分类

 1.3生命周期图示

1.4生命周期函数特点

1.4.1了解beforeCreate和created生命周期函数的特点

1.4.2了解beforeMount和mounted生命周期函数

1.4.3生命周期 - 组件运行阶段的生命周期函数

1.4.4生命周期 - 组件销毁阶段的生命周期函数

2、组件之间的数据共享

2.1. 组件之间的关系

2.2. 父子组件之间的数据共享

2.2.1 父组件向子组件共享数据

2.2.2 子组件向父组件共享数据

 2.3. 兄弟组件之间的数据共享

3、ref引用

3.1 什么是 ref 引用

3.2 使用 ref 引用 DOM 元素

3.3使用 ref 引用组件实例

3.4控制文本框和按钮的按需切换

3.4.1代码实现

3.4.2让文本框自动获得焦点

3.4.3this.$nextTick(cb) 方法

4、购物车案例


1、组件生命周期

1.1 生命周期 & 生命周期函数

  1. 生命周期Life Cycle)是指一个组件从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段
  2. 生命周期函数:是由 vue 框架提供的内置函数,会伴随着组件的生命周期,自动按次序执行
注意: 生命周期 强调的是 时间段 生命周期函数 强调的是 时间点

1.2组件生命周期函数的分类

 1.3生命周期图示

可以参考 vue 官方文档给出的“生命周期图示”,进一步理解组件生命周期执行的过程:
https://cn.vuejs.org/v2/guide/instance.html# 生命周期图示:

1.4生命周期函数特点

<template>
  <div class="test-container">
    <h3 id="myh3">Test.vue 组件 --- {{ books.length }} 本图书</h3>
    <p id="pppp">message 的值是:{{ message }}</p>
    <button @click="message += '~'">修改 message 的值</button>
  </div>
</template>

<script>
export default {
  props: ['info'],
  data() {
    return {
      message: 'hello vue.js',
      // 定义 books 数组,存储的是所有图书的列表数据。默认为空数组!
      books: []
    }
  },
  watch: {
    message(newVal) {
      console.log('监视到了 message 的变化:' + newVal)
    }
  },
  methods: {
    show() {
      console.log('调用了 Test 组件的 show 方法!')
    },
    // 使用 Ajax 请求图书列表的数据
    initBookList() {
      const xhr = new XMLHttpRequest()
      xhr.addEventListener('load', () => {
        const result = JSON.parse(xhr.responseText)
        console.log(result)
        this.books = result.data
      })
      xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
      xhr.send()
    }
  },
  // 创建阶段的第1个生命周期函数
  beforeCreate() {
    // console.log(this.info)
    // console.log(this.message)
    // this.show()
  },
  created() {
    // created 生命周期函数,非常常用。
    // 经常在它里面,调用 methods 中的方法,请求服务器的数据。
    // 并且,把请求到的数据,转存到 data 中,供 template 模板渲染的时候使用!
    this.initBookList()
  },
  beforeMount() {
    // console.log('beforeMount')
    // const dom = document.querySelector('#myh3')
    // console.log(dom)
  },
  // 如果要操作当前组件的 DOM,最早,只能在 mounted 阶段执行
  mounted() {
    // console.log(this.$el)
    // const dom = document.querySelector('#myh3')
    // console.log(dom)
  },
  beforeUpdate() {
    // console.log('beforeUpdate')
    // console.log(this.message)
    // const dom = document.querySelector('#pppp')
    // console.log(dom.innerHTML)
  },
  // 当数据变化之后,为了能够操作到最新的 DOM 结构,必须把代码写到 updated 生命周期函数中
  updated() {
    // console.log('updated')
    // console.log(this.message)
    // const dom = document.querySelector('#pppp')
    // console.log(dom.innerHTML)
  },
  beforeDestroy() {
    console.log('beforeDestroy')
    this.message = 'aaa'
    console.log(this.message)
  },
  destroyed() {
    console.log('destroyed')
    // this.message = 'aaa'
  }
}
</script>

<style lang="less" scoped>
.test-container {
  background-color: pink;
  height: 200px;
}
</style>

1.4.1了解beforeCreate和created生命周期函数的特点


1.4.2了解beforeMount和mounted生命周期函数

1.4.3生命周期 - 组件运行阶段的生命周期函数

1.4.4生命周期 - 组件销毁阶段的生命周期函数

2、组件之间的数据共享

App.vue:

<template>
  <div class="app-container">
    <h1>App 根组件--{{countFromSon}}</h1>
    <p>{{userinfo}}</p>
    <hr />

    <div class="box">
      <!-- 渲染 Left 组件和 Right 组件 -->
      <Left :msg="message" :user="userinfo"></Left>
      <Right @numchange="getNewCount"></Right>
    </div>
  </div>
</template>

<script>
import Left from '@/components/Left.vue'
import Right from '@/components/Right.vue'

export default {
  data(){
    return{
      message:'sjf',
      userinfo:{name:'sjf',age:'18'},
      // 定义countFromSon,来接收子组件传递过来的数据
      countFromSon:0
    }
  },
  methods:{
    getNewCount(val){
      this.countFromSon=val
      console.log('numchange事件被触发了',val)
    }
  },
  components:{
    Left,
    Right
  }

}
</script>

<style lang="less">
.app-container {
  padding: 1px 20px 20px;
  background-color: #efefef;
}
.box {
  display: flex;
}
</style>

Left.vue:

<template>
  <div class="left-container">
    <h3>Left 组件</h3>
    <p>msg的值是:{{msg}}</p>
    <p>userinfo的值是:{{user}}</p>
    <!-- 不要修改props的值 -->
    <!-- <button @click="msg='123'">修改messsge</button> -->
    <button @click="send">把str发送给Right</button>
  </div>
</template>

<script>
// 1 导入eventBus.js
import bus from './eventBus.js'

export default {
  props:['msg','user'],
  data(){
    return{
      // 要发送的数据
      str:'你的报应就是我'
    }
  },
  methods:{
    send(){
      // 2 通过eventBus发送数据
      bus.$emit('share',this.str)
    }
  }
}
</script>

<style lang="less">
.left-container {
  padding: 0 20px 20px;
  background-color: orange;
  min-height: 250px;
  flex: 1;
}
</style>

 Right.vue:

<template>
  <div class="right-container">
    <h3>Right 组件--{{count}}</h3>
    <button @click="add">+1</button>
    <p>{{msgFromLeft}}</p>
  </div>
</template>

<script>
// 1 导入eventBus.js
import bus from './eventBus.js'

export default {
  data(){
    return{
      // 子组件自己的数据。将来希望把count值传给父组件
      count:0,
      msgFromLeft:''

    }
  },
  methods:{
  add(){
    this.count+=1;
    // 通过$emit出发自定义事件numchange
    this.$emit('numchange',this.count)
  }
  },
  created(){
// 2 为bus绑定自定义事件
bus.$on('share',(val)=>{
  console.log('在Right中定义的share被触发了',val)
  this.msgFromLeft=val
})
  }

}
</script>

<style lang="less">
.right-container {
  padding: 0 20px 20px;
  background-color: lightskyblue;
  min-height: 250px;
  flex: 1;
}
</style>

eventBus.js:

import Vue from 'vue'
// 创建一个Vue实例,并把它向外导出
export default new Vue()

2.1. 组件之间的关系

2.2. 父子组件之间的数据共享

2.2.1 父组件向子组件共享数据

父组件向子组件共享数据需要使用自定义属性。示例代码如下:

2.2.2 子组件向父组件共享数据

子组件向父组件共享数据使用 自定义事件 。示例代码如下:

 2.3. 兄弟组件之间的数据共享

3、ref引用

App.vue:​​​​​​​

<template>
  <div class="app-container">
    <h1 ref="myh1">App 根组件</h1>
    <button @click="showThis">打印this</button>
    <button @click="onReset">重置Left的count</button>
    <hr />
    <input type="text" v-if="inputVisiable" @blur="showButton" ref="iptRef">
    <button v-else @click="showInput">展示输入框</button>
    <div class="box">
      <!-- 渲染 Left 组件和 Right 组件 -->
      <Left ref="comeLeft"></Left>
    </div>
  </div>
</template>
<script>
import Left from '@/components/Left.vue'

export default {
  data(){
    return{
      // 默认值为false,表示展示按钮,隐藏输入框
      inputVisiable:false
    }
  },
  methods:{
    // 点击按钮,显示输入框
    showInput(){
      // 切换布尔值,把文本框展示出来
      this.inputVisiable=true
      // 让展示出来的文本框自动获得焦点
      // 为什么this.$emit.iptRef是undefined?
      // 因为:this.inputVisiable=true执行完之后,数据变成了最新,但是页面还没来得及渲染,页面中还没有文本框
      console.log(this.$refs.iptRef)
      this.$refs.iptRef.focus()
      // this.$nextTick(()=>{
      //   this.$refs.iptRef.focus()
      // })

    },
    // 输入框失去焦点,显示按钮
    showButton(){
      this.inputVisiable=false
    },
    showThis(){
      // 当前App组件的实例对象
       console.log(this)
      // console.log(this.$refs.myh1)
      this.$refs.myh1.style.color='red'
    },
    onReset(){
      // this.$refs.comeLeft.rsetCount()
      this.$refs.comeLeft.count=0
    }
  },
  components:{
    Left
  }
}
</script>

<style lang="less">
.app-container {
  padding: 1px 20px 20px;
  background-color: #efefef;
}
.box {
  display: flex;
}
</style>

 Left.vue:

<template>
  <div class="left-container">
    <h3>Left 组件---{{count}}</h3>
    <button @click="count+=1">+1</button>
    <button @click="rsetCount">重置</button>
  </div>
</template>

<script>
export default {
  data(){
    return{
      count:0
    }
  },
  methods:{
    rsetCount(){
      this.count=0
    }
  }
}
</script>

<style lang="less">
.left-container {
  padding: 0 20px 20px;
  background-color: orange;
  min-height: 250px;
  flex: 1;
}
</style>

3.什么是 ref 引用

  1. jquery简化了程序员操作DOM的过程
  2. vue优势:MWM    在vue中,程序员不需要操作 DOM。程序员只需要把数据维护好即可! (数据驱动视图)
  3. 结论:在vue项目,强烈不建议大家安装和使用jQuery! !
  4. 假设:在vue中,需要操作 DOM了,需要拿到页面上某个 DOM元素的引用,此时怎么办?

3.2 使用 ref 引用 DOM 元素

 通过refs获取页面元素的DOM:

3.3使用 ref 引用组件实例

3.4控制文本框和按钮的按需切换

3.4.1代码实现

3.4.2让文本框自动获得焦点

以上代码在执行的时候会出现一个问题:

为什么this.$emit.iptRef是undefined?

因为:this.inputVisiable=true执行完之后,数据变成了最新,但是页面还没来得及渲染,页面中还没有文本框。

解决办法:this.$nextTick(cb) 方法

3.4.3this.$nextTick(cb) 方法

4、购物车案例

4.1复习回顾

4.1.1数组中的方法 - some循环

forEach方法:循环一旦开始,无法在中间被停止

some方法:在找到对应的项之后,可以通过 return true 固定的语法,来终止 some 循环

 4.1.2数组中的方法 - every循环

4.1.3数组中的方法 - reduce的基本用法
​​​​​​​

5、总结

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大炮不想学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值