Vue学习第三天

163 阅读2分钟

Vue生命周期和生命周期的四个阶段和钩子函数

什么时候可以发送初始化渲染请求(越早越好)

什么时候可以开始操作dom(至少dom渲染的出来,也就是至少是挂载阶段)

Vue的生命周期:

也就是一个Vue实例从 创建销毁 的整个过程

四个阶段:

1.创建 2.挂载(渲染) 3.更新 4.销毁

Vue生命周期函数(钩子函数)

Vue生命周期过程中,会自动运行一些函数,被称为生命周期钩子——>让开发者可以在 特定阶段 运行自己的代码 ​

——created

发送请求

 async created () {
        // 1. 发送渲染请求获取数据
        const res = await axios.get('http://hmajax.itheima.net/api/news')
        // 2. 更新到 list 中,用于页面渲染 v-for
        this.list = res.data.data
      }

——mounted

一进入页面就自动获取焦点(其实就是修改dom)

<div class="container" id="app">
  <div class="search-container">
    <img src="https://www.itheima.com/images/logo.png" alt="">
    <div class="search-box">
      <input type="text" v-model="words" id="inp">
      <button>搜索一下</button>
    </div>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: '#app',
    data: {
      words: ''
    },
    // 核心思路:
    // 1. 等input框渲染出来 mounted 钩子
    // 2. 让input框获取焦点 inp.focus()
    mounted () {
      document.querySelector('#inp').focus()
    }
  })
</script>

小黑记账清单案例

功能需求:

1. 基本渲染

  • 一进页面立刻发送请求获取数据
  • 拿到数据,存到data的响应式数据中
  • 结合数据,进行页面渲染 v-for
  • 消费统计 ——>用计算属性

2. 添加功能

  • 收集表单数据用v-model
  • 给添加按钮注册表单事件,发送添加请求
  • 需要重新渲染

3. 删除功能

  • 注册点击事件,并且由于需要知道要删除的是哪一个,所以要传参,也就是id
  • 根据id发送删除的请求

4. 饼图渲染

  • 初始化一个饼图:echarts,需要等dom渲染完,也就是需要mounted钩子实现
  • 根据数据实时更新饼图
 <div id="app">
      <div class="contain">
        <!-- 左侧列表 -->
        <div class="list-box">

          <!-- 添加资产 -->
          <form class="my-form">
            <input type="text" v-model.trim="name" class="form-control" placeholder="消费名称" />
            <input type="text" v-model.number="price" class="form-control" placeholder="消费价格" />
            <button type="button" class="btn btn-primary" @click="add">添加账单</button>
          </form>

          <table class="table table-hover">
            <thead>
              <tr>
                <th>编号</th>
                <th>消费名称</th>
                <th>消费价格</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(item,index) in list" :key="item.id">
                <td>{{index+1}}</td>
                <td>{{item.name}}</td>
                <td :class="{red:item.price>500}">{{item.price}}</td>
                <td><a @click="del(item.id)" href="javascript:;">删除</a></td>
              </tr>
            </tbody>
            <tfoot>
              <tr>
                <td colspan="4">消费总计: {{totalPrice.toFixed(2)}}</td>
              </tr>
            </tfoot>
          </table>
        </div>
        
        <!-- 右侧图表 -->
        <div class="echarts-box" id="main"></div>
      </div>
    </div>
    <script src="../echarts.min.js"></script>
    <script src="../vue.js"></script>
    <script src="../axios.js"></script>
    <script>
      
       
      
      const app = new Vue({
        el: '#app',
        data: {
          list:[],
          name:'',
          price:''
        },
        created(){
          //发送渲染的请求
          //这部分注释掉,因为要多次渲染发请求,所以我们再方法里封装一个方法
          // const res = await axios.get('https://applet-base-api-t.itheima.net/bill',{
          //   params:{
          //     creator:'小黑'
          //   }
          // })
          // this.list=res.data.data
          this.getList()
        },
        mounted () {
          this.myChart = echarts.init(document.querySelector('#main'))
          this.myChart.setOption({
            // 大标题
            title: {
              text: '消费账单列表',
              left: 'center'
            },
            // 提示框
            tooltip: {
              trigger: 'item'
            },
            // 图例
            legend: {
              orient: 'vertical',
              left: 'left'
            },
            // 数据项
            series: [
              {
                name: '消费账单',
                type: 'pie',
                radius: '50%', // 半径
                data: [
                  // { value: 1048, name: '球鞋' },
                  // { value: 735, name: '防晒霜' }
                ],
                emphasis: {
                  itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                  }
                }
              }
            ]
          })
        },
        computed:{
          totalPrice(){
            return this.list.reduce((sum,item)=>sum+item.price,0)
          }
        },
        methods:{
          //发送添加的请求
          async getList(){
            const res = await axios.get('https://applet-base-api-t.itheima.net/bill',{
            params:{
              creator:'小黑'
            }
          })
          this.list=res.data.data

          //在这里实现实时更新图表
          this.myChart.setOption({

             // 数据项
             series: [
              {//之前上面数据项传过的都不需要再传了,所以这里只写data就可以
                //data: [
                  // { value: 1048, name: '球鞋' },
                  // { value: 735, name: '防晒霜' }
                //],   
                data: this.list.map(item => ({value:item.price , name:item.name}))
              }
            ]

          })
          },
          async add(){
            if(!this.name){
              alert("请输入消费名称")
              return
            }
            if(typeof this.price !=='number'){
              alert("请输入正确价格")
            }
            //现在发请求
            const res=await axios.post('https://applet-base-api-t.itheima.net/bill',{
              creator:'小黑',
              name:this.name,
              price:this.price
            })
            //重新渲染,直接调用
            this.getList() 

            this.name=''
            this.price=''
          },
          async del (id) {
            // 根据 id 发送删除请求
            const res = await axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`)
            // 重新渲染
            this.getList()
          }
        }
      })
    </script>

工程化开发和脚手架Vue CLI

安装使用步骤: 目录文件 组件化开发 & 根组件 App.Vue文件(单文件组件)的三个组成部分 普通组件的注册使用(局部/全局)

TIP: 一般都用局部注册,如果发现确实是通用组件,再抽离到全局

组件拆分的页面开发思路: