当前位置: 首页 > article >正文

Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)

01.生命周期

Vue生命周期:就是一个Vue实例从创建 到 销毁 的整个过程

生命周期四个阶段:① 创建 挂载更新 销毁

1.创建阶段:创建响应式数据

2.挂载阶段:渲染模板

3.更新阶段:修改数据,更新视图

4.销毁阶段:销毁Vue实例

02.生命周期钩子

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

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>

  <div id="app">
    <h3>{{ title }}</h3>
    <div>
      <button @click="count--">-</button>
      <span>{{ count }}</span>
      <button @click="count++">+</button>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        count: 100,
        title: '计数器'
      },
      beforeCreate(){
        console.log('beforeCreate',this.count)        
      },
      // 创建响应数据之后,已经能获取到响应数据
      // ****** 进入页面就要请求数据的就放到这个钩子函数里面
      created(){
        console.log('beforeCreate',this.count)   
      },
      
      // 挂载阶段 - 相应数据挂载到标签之前
      beforeMount(){
        console.log('beforeMount',document.querySelector('h3'))
      },
      // 响应数据挂载到标签上面了
      // ****************** 操作标签
      mounted(){
        console.log('mounted',document.querySelector('h3'))
      },

      // 数据更新阶段
      // 修改了响应式数据,没有完全更新到视图
      beforeUpdate(){
        console.log('beforeUpdate',this.count,document.querySelector('h3'))
      },
      updated(){
        console.log('updated',this.count,document.querySelector('h3'))
      },

      // 销毁 → 关闭浏览器
      beforeDestory(){
        console.log('销毁前')        
      },
      destroyed(){
        console.log('销毁后') 
      }
    })
  </script>
</body>
</html>

 代码示例:

created应用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      list-style: none;
    }
    .news {
      display: flex;
      height: 120px;
      width: 600px;
      margin: 0 auto;
      padding: 20px 0;
      cursor: pointer;
    }
    .news .left {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      padding-right: 10px;
    }
    .news .left .title {
      font-size: 20px;
    }
    .news .left .info {
      color: #999999;
    }
    .news .left .info span {
      margin-right: 20px;
    }
    .news .right {
      width: 160px;
      height: 120px;
    }
    .news .right img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  </style>
</head>
<body>

  <div id="app">
    <ul>
      <li class="news" v-for="(item,index) in list" :key="item.id">
        <div class="left">
          <div class="title">{{ item.title }}</div>
          <div class="info">
            <span>{{ item.source }}</span>
            <span>{{ item.time }}</span>
          </div>
        </div>
        <div class="right">
          <img :src="item.img" alt="">
        </div>
      </li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    // 接口地址:http://hmajax.itheima.net/api/news
    // 请求方式:get
    const app = new Vue({
      el: '#app',
      data: {
        list: []
      },
     async created(){
       const res = await axios.get('http://hmajax.itheima.net/api/news')
       console.log(res)       
       this.list = res.data.data
      }
    })
  </script>
</body>
</html>

mounted应用


<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>示例-获取焦点</title>
  <!-- 初始化样式 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset.css@2.0.2/reset.min.css">
  <!-- 核心样式 -->
  <style>
    html,
    body {
      height: 100%;
    }
    .search-container {
      position: absolute;
      top: 30%;
      left: 50%;
      transform: translate(-50%, -50%);
      text-align: center;
    }
    .search-container .search-box {
      display: flex;
    }
    .search-container img {
      margin-bottom: 30px;
    }
    .search-container .search-box input {
      width: 512px;
      height: 16px;
      padding: 12px 16px;
      font-size: 16px;
      margin: 0;
      vertical-align: top;
      outline: 0;
      box-shadow: none;
      border-radius: 10px 0 0 10px;
      border: 2px solid #c4c7ce;
      background: #fff;
      color: #222;
      overflow: hidden;
      box-sizing: content-box;
      -webkit-tap-highlight-color: transparent;
    }
    .search-container .search-box button {
      cursor: pointer;
      width: 112px;
      height: 44px;
      line-height: 41px;
      line-height: 42px;
      background-color: #ad2a27;
      border-radius: 0 10px 10px 0;
      font-size: 17px;
      box-shadow: none;
      font-weight: 400;
      border: 0;
      outline: 0;
      letter-spacing: normal;
      color: white;
    }
    body {
      background: no-repeat center /cover;
      background-color: #edf0f5;
    }
  </style>
</head>

<body>
<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: ''
    },
    mounted(){
      document.querySelector('#inp').focus()
    }
  })
</script>

</body>

</html>

03.综合案例小黑记账本

思路分析:

1.基本渲染

  • 立刻发送请求获取数据 created

  • 拿到数据,存到data的响应式数据中

  • 结合数据,进行渲染 v-for

  • 消费统计 —> 计算属性

2.添加功能

  • 收集表单数据 v-model,使用指令修饰符处理数据

  • 给添加按钮注册点击事件,对输入的内容做非空判断,发送请求

  • 请求成功后,对文本框内容进行清空

  • 重新渲染列表

3.删除功能

  • 注册点击事件,获取当前行的id

  • 根据id发送删除请求

  • 需要重新渲染

4.饼图渲染

  • 初始化一个饼图 echarts.init(dom) mounted钩子中渲染

  • 根据数据试试更新饼图 echarts.setOptions({...})

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <!-- CSS only -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" />
  <style>
    .red {
      color: red !important;
    }

    .search {
      width: 300px;
      margin: 20px 0;
    }

    .my-form {
      display: flex;
      margin: 20px 0;
    }

    .my-form input {
      flex: 1;
      margin-right: 20px;
    }

    .table> :not(:first-child) {
      border-top: none;
    }

    .contain {
      display: flex;
      padding: 10px;
    }

    .list-box {
      flex: 1;
      padding: 0 30px;
    }

    .list-box a {
      text-decoration: none;
    }

    .echarts-box {
      width: 600px;
      height: 400px;
      padding: 30px;
      margin: 0 auto;
      border: 1px solid #ccc;
    }

    tfoot {
      font-weight: bold;
    }

    @media screen and (max-width: 1000px) {
      .contain {
        flex-wrap: wrap;
      }

      .list-box {
        width: 100%;
      }

      .echarts-box {
        margin-top: 30px;
      }
    }
  </style>
</head>

<body>
  <div id="app">
    <div class="contain">
      <!-- 左侧列表 -->
      <div class="list-box">

        <!-- 添加资产 -->
        <form class="my-form">
          <input type="text" class="form-control" placeholder="消费名称" v-model.trim()="name" />
          <input type="text" class="form-control" placeholder="消费价格" v-model.number="price" />
          <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>{{ item.price }}</td>
              <td><a href="javascript:;" @click="del(item.id)">删除</a></td>
            </tr>
          </tbody>
          <tfoot>
            <tr>
              <td colspan="4">消费总计: 298.00</td>
            </tr>
          </tfoot>
        </table>
      </div>

      <!-- 右侧图表 -->
      <div class="echarts-box" id="main"></div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    /**
     * 接口文档地址:
     * https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058
     * 
     * 功能需求:
     * 1. 基本渲染
     * 2. 添加功能
     * 3. 删除功能
     * 4. 饼图渲染
     */
    const app = new Vue({
      el: '#app',
      data: {
        list: [],
        name: '',
        price: ''
      },
      async created() {
        // 删除和添加都要调用拿最新数据渲染 → 封装个函数
        // const res = await axios.get('https://applet-base-api-t.itheima.net/bill',{
        //   params:{
        //     creator:'ZKKK'
        //   }
        // })
        // console.log(res)
        // this.list = res.data.data  
        this.render()
      },
      methods: {
        // 定义请求函数
        async render() {
          const res = await axios.get('https://applet-base-api-t.itheima.net/bill', {
            params: {
              creator: 'ZKKK'
            }
          })
          console.log(res)
          this.list = res.data.data
          // 重现渲染饼图,使用最新的数据
          this.myChart.setOption(option = {
            series: [
              {
                data: this.list.map(item => ({
                  value: item.price,
                    name: item.name
                }))
              }
            ]
          })
        },
        // 删除函数
        async del(id) {
          await axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`)
          this.render()
        },
        // 添加函数
        async add() {
          console.log(111)

          if (this.name.trim() == '' || this.price == '') {
            return
          }
          await axios.post('https://applet-base-api-t.itheima.net/bill', {
            creator: 'ZKKK',
            name: this.name,
            price: this.price
          })
          this.render()
          this.name = ''
          this.price = ''
        }
      },
      mounted() {
        this.myChart = echarts.init(document.querySelector('#main'))
        this.myChart.setOption(option = {
          title: {
            text: '消费账单',
            left: 'center'
          },
          tooltip: {
            trigger: 'item'
          },
          legend: {
            orient: 'vertical',
            left: 'left'
          },
          series: [
            {
              name: '消费账单',
              type: 'pie',
              radius: '50%',
              data: [
                { value: 1048, name: 'Search Engine' },
                { value: 735, name: 'Direct' },
                { value: 580, name: 'Email' },
                { value: 484, name: 'Union Ads' },
                { value: 300, name: 'Video Ads' }
              ],
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        })
      }
    })
  </script>
</body>

</html>

04.工程化开发和脚手架

开发Vue的两种方式

  • 核心包传统开发模式:基于html / css / js 文件,直接引入核心包,开发 Vue。

  • 工程化开发模式:基于构建工具(例如:webpack)的环境中开发Vue。

工程化开发模式问题:

  • webpack配置不简单

  • 雷同的基础配置

  • 缺乏统一的标准

脚手架Vue CLI

Vue CLI 是Vue官方提供的一个全局命令工具

可以帮助我们快速创建一个开发Vue项目的标准化基础架子。【集成了webpack配置】

好处:

  1. 开箱即用,零配置

  2. 内置babel等工具

  3. 标准化的webpack配置

使用步骤:

  1. 全局安装(只需安装一次即可) yarn global add @vue/cli 或者 npm i @vue/cli -g

  2. 查看vue/cli版本: vue --version

  3. 创建项目架子:vue create project-name(项目名不能使用中文)

  4. 启动项目:yarn serve 或者 npm run serve(命令不固定,找package.json)

主要使用三个文件:

  1. main.js 入口文件

  2. App.vue App根组件

  3. index.html 模板文件

运行流程

 05.组件化开发

组件化:一个页面可以拆分成一个个组件,每个组件有着自己独立的结构、样式、行为。

​ 好处:便于维护,利于复用 → 提升开发效率。

​ 组件分类:普通组件、根组件。

06.根组件App.vue

组件是由三部分构成

  • 语法高亮插件

三部分构成

  • template:结构 (有且只能一个根元素)

  • script: js逻辑

  • style: 样式 (可支持less,需要装包)

让组件支持less

(1) style标签,lang="less" 开启less功能

(2) 装包: yarn add less less-loader -D 或者npm i less less-loader -D

07.普通组件的注册-局部注册 

1.特点:

只能在注册的组件内使用

2.步骤:

  1. 创建.vue文件(三个组成部分)

  2. 在使用的组件内先导入再注册,最后使用

3.使用方式:

当成html标签使用即可 <组件名></组件名>

4.注意:

组件名规范 —> 大驼峰命名法, 如 HmHeader

// 导入需要注册的组件
import 组件对象 from '.vue文件路径'
import HmHeader from './components/HmHeader'

export default {  // 局部注册
  components: {
   '组件名': 组件对象,
    HmHeader:HmHeaer,
    HmHeader
  }
}

08.普通组件的注册-全局注册 

1.特点:

全局注册的组件,在项目的任何组件中都能使用

2.步骤

  1. 创建.vue组件(三个组成部分)

  2. main.js中进行全局注册

3.使用方式

当成HTML标签直接使用

<组件名></组件名>

4.注意

组件名规范 —> 大驼峰命名法, 如 HmHeader

5.语法

Vue.component('组件名', 组件对象)

// 导入需要全局注册的组件
import HmButton from './components/HmButton'
Vue.component('HmButton', HmButton)


http://www.kler.cn/a/448109.html

相关文章:

  • 深度学习的DataLoader是什么数据类型,为什么不可用来索引
  • flask flask-socketio创建一个网页聊天应用
  • 安装milvus以及向量库增删改操作
  • 电商数据流通的未来:API接口的智能化与自动化趋势
  • linux zip unzip 命令的使用
  • OpenSSL 心脏滴血漏洞(CVE-2014-0160)
  • 数智化医院分布式计算框架融合人工智能方向初步实现与能力转换浅析
  • 数位dp-acwing(数字游戏)
  • 基于单片机的步进电机控制系统的设计研究
  • 数据结构 (队列略版)
  • TCP常见问题
  • 如何在Ubuntu上利用Docker和Cpolar实现Excalidraw公网访问高效绘图——“cpolar内网穿透”
  • [极客大挑战 2019]HardSQL 1
  • 豆包MarsCode:小T的密码变换规则
  • RLDP(快速链路检测)防环
  • Rust vs C: PNG解码器性能之争的启示
  • Apple Vision Pro 开发教程:通过 TestFlight 把开发的程序安装到其他的设备上测试
  • C++算法第十二天
  • 一起学Git【番外篇:如何在Git中新建文件】
  • OpenCV图像分割
  • UITableView实现通讯录效果
  • 【漏洞-Oracle】未设置口令复杂度校验、密码有效期
  • ELK系列-(六)Redis也能作为消息队列?(上)
  • 使用Python实现量子密钥分发:构建安全通信的未来
  • scala基础学习(数据类型)-字符串
  • Oracle筑基篇-调度算法-LRU的引入