最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue项目实战(二)——Vue3+Vite+TypeScript实现ToDoList|刷题打卡

    正文概述 掘金(豆包君)   2021-04-07   497

    @Vue3+Vite+TypeScript 实现 ToDoList

    不刷题,只打卡;上掘金,拿offer!

    前言

     小白课系列完成,下面开始我们的实战课程吧!

    • 注:本项目基于 Vue3 + Vite + TypeScript 框架实现搭建

    正文

     如果看完了《Vue 小白课》,那么对 Vue3 项目的整体情况有了一定了解,并且搭建好了 Vue3 的环境。本篇我们就来练习一下 Vue3,实现 ToDoList 项目。

     倘若对 VueCLI 项目不是特别了解,请先参考:

    • Vue 小白课(五)——Vue3 + Vite 及 VueCLI4 项目搭建

    以下是我们的搭建好的项目目录结构:

    Vue项目实战(二)——Vue3+Vite+TypeScript实现ToDoList|刷题打卡

    主要文件介绍

     在这个 ToDoList 当中,涉及到知识点包括以下内容:

    入口文件 -- main.js

     我们首先看下 main.js文件, 在 2.X 版本中创建一个 vue 实例是通过 new Vue()来实现的,到了 3.X 中则是通过使用 createApp 这个 API。

    // 先导入createApp模块
    import { createApp } from 'vue'
    import App from './App.vue'
    
    // 使用createApp方法将我们的入口文件放进去,最后挂载
    createApp(App).mount('#app')
    

    根组件 -- App.vue

    App.vue是我们项目的根组件满所有的组件都是挂载到他里面运行的。

    <template>
      <img  src="./assets/logo.png" />
      <HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
    </template>
    
    <script lang="ts">
    // 引入 defineComponent() 以正确推断 setup() 组件的参数类型
    import { defineComponent } from 'vue'
    import HelloWorld from './components/HelloWorld.vue'
    
    export default defineComponent({
      name: 'App',
      components: {
        HelloWorld,
      },
    })
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    

     我们看到其中有defineComponent 函数,它只是对 setup 函数进行封装,返回 options 的对象;

    export function defineComponent(options: unknown) {
      return isFunction(options) ? { setup: options } : options
    }
    

     defineComponent 最重要的是:在 TypeScript 下,给予组件正确的参数类型推断 。

    业务组件 -- HelloWorld.vue

    HelloWorld.vue就是我们要写业务的组件了。删除一些初始化显示的东西,我们的组件就是这样子:

    <template>
      <h1>{{ msg }}</h1>
    </template>
    
    <script lang="ts">
    import { ref, defineComponent } from 'vue'
    export default defineComponent({
      name: 'HelloWorld',
      props: {
        msg: {
          type: String,
          required: true,
        },
      },
      // setup 函数是 Composition API(组合 API)的入口
      // 几乎所有东西都在setup()方法中,包括挂载的生命周期挂钩。
      setup: () => {
        const count = ref(0)
        return { count }
      },
    })
    </script>
    
    <style scoped></style>
    

     如果你对 Vue 2 得项目比较熟悉,看到这个组件的时候最显眼的应该是setup函数了。这个就是 Vue 3 的特性之一 ——组合式 API

     我们先对比一下 Options API(Vue 2)Composition API(Vue 3 )

    Options API 约定:

    • 我们需要在 props 里面设置接收参数

    • 我们需要在 data 里面设置变量

    • 我们需要在 computed 里面设置计算属性

    • 我们需要在 watch 里面设置监听属性

    • 我们需要在 methods 里面设置事件方法

     你会发现 Options APi 都约定了我们该在哪个位置做什么事,这反倒在一定程度上也强制我们进行了代码分割。

     这种碎片化使得理解和维护复杂组件变得困难。选项的分离掩盖了潜在的逻辑问题。此外,在处理单个逻辑关注点时,我们必须不断地“跳转”相关代码的选项块。

     现在用 Composition API,不再这么约定了,于是乎,代码组织非常灵活,我们的控制代码写在 setup 里面即可。

    setup 函数的特点:

    1. setup 函数是处于 生命周期函数 beforeCreate 和 Created 两个钩子函数之间的函数 也就说在 setup 函数中是无法 使用 data 和 methods 中的数据和方法的

    2. setup 函数是 Composition API(组合 API)的入口

    3. 在 setup 函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用

    setup 函数的注意点:

    1. 由于在执行 setup 函数的时候,还没有执行 Created 生命周期方法,所以在 setup 函数中,无法使用 data 和 methods 的变量和方法

    2. 由于我们不能在 setup 函数中使用 data 和 methods,所以 Vue 为了避免我们错误的使用,直接将 setup 函数中的 this 修改成了 undefined

    3. setup 函数只能是同步的不能是异步的

    开始实现 ToDoList

     介绍完 vue 3 项目的主要文件,我们就可以开始实现 ToDoList 项目了。

    1、创建 ToDoList 组件

     我们可以将/src/components中的HelloWorld.vue文件改名为ToDoList.vue,并且 将name也改为ToDoList,将其<template>标签中不必要的内容删除,如下:

    <template>
      <h1>{{ msg }}</h1>
    </template>
    

    2、引入注册 ToDoList 组件

     在/src中的App.vue文件中,将原先注册HelloWorld的全改为ToDoList,并且 将传值msg内容改为ToDoList,如下:

    <template>
      <ToDoList msg="ToDoList" />
    </template>
    
    <script lang="ts">
    // 引入 defineComponent() 以正确推断 setup() 组件的参数类型
    import { defineComponent } from 'vue'
    import ToDoList from './components/ToDoList.vue'
    
    export default defineComponent({
      name: 'App',
      components: {
        ToDoList,
      },
    })
    </script>
    

     OK,以上两步做完,我们的项目运行起来是这样子的:

    Vue项目实战(二)——Vue3+Vite+TypeScript实现ToDoList|刷题打卡

     来认识一下props

     组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板中直接引用父组件的数据。要让子组件使用父组件的数据,需要通过子组件的 props 选项。它分为两种方式:动态和静态

    • 静态 props
    <blog-post ></blog-post>
    
    • 动态 props

     在模板中,要动态地绑定父组件的数据到子组件模板的 props,和绑定 Html 标签特性一样,使用 v-bind 绑定;

    <!-- 动态赋予一个变量的值 -->
    <blog-post v-bind:></blog-post>
    

    3、创建并渲染列表

     接下来,我们在setup函数中创建一个数组 items,记得要把数组 return 出来,然后在<template>里写我们的 html 结构,使用 v-for 指令来实现列表的渲染,如下:

    <template>
      <h1>{{ msg }}</h1>
      <ul class="ToDoList">
        <li v-for="(item, index) in items" :key="item.id">
          <!-- 待办事项 -->
          <span v-text="item.title"></span>
          <!-- 完成按钮 -->
          <button>完成</button>
        </li>
      </ul>
    </template>
    
    <script lang="ts">
    import { ref, defineComponent } from 'vue'
    export default defineComponent({
      name: 'ToDoList',
      props: {
        msg: {
          type: String,
          required: true,
        },
      },
      // setup 函数是 Composition API(组合 API)的入口
      // 几乎所有东西都在setup()方法中,包括挂载的生命周期挂钩。
      setup: () => {
        const items = ref([
          {
            id: 1,
            title: '吃饭',
          },
          {
            id: 2,
            title: '睡觉',
          },
          {
            id: 3,
            title: '打豆豆',
          },
        ])
        // 注意:这里一定要return,不然在模板中是获取不到它的值的。
        return { items }
      },
    })
    </script>
    
    <style scoped></style>
    

     在 setup 中,我们又返回了 items 数组,其中每个元素包括 id,title,我们将 items 使用 v-for 绑定到列表中,渲染后的结果如下:

    Vue项目实战(二)——Vue3+Vite+TypeScript实现ToDoList|刷题打卡

    注:

    1. vue 中列表循环需加:key="唯一标识", 唯一标识可以是 item 里面 id、index 等,因为 vue 组件高度复用,增加 Key 可以标识组件的唯一性。为了更好地区别各个组件, key 的作用主要是为了高效的更新虚拟 DOM。详情请参考 -- VUE 中演示 v-for 为什么要加 key

    2. setup函数中,可以使用ref函数来创建一个响应式数据,并将其 ruturn 出去;当数据发生改变时,Vue 会自动更新 UI,

    4、绑定删除事件

     接下来我们使用v-on来为按钮绑定事件,目的是点击删除按钮的时候,将列表中相应的选项删除。

    <button v-on:click="deleteItem(index)">完成</button>
    

     这里我们增加了click方法,方法名为deleteItem,参数为数组下标index(数字类型)。

     紧接着上面定义的 deleteItem 方法,我们接着在setup中定义deleteItem事件并返回

    // 点击完成按钮,删除对应事项
    let deleteItem = (index: number) => {
      items.value.splice(index, 1)
    }
    

    注:

     在setup函数中没有 this,所有的 ref 对象,要在 js 中获取它的值,都要加上一个value属性

    5、使用 input 输入框添加新事项

     截至目前我们使用的都是现成的列表,接下来我们使用输入框来动态为列表添加条目:

    <div>
      待办:<input type="text" v-model="newItem" />
      <button @click="addNewItem">添加</button>
    </div>
    

     使用指令v-model在表单控件或者组件上创建双向绑定,即绑定 newItem,使用@来绑定事件监听器,点击添加按钮会响应事件addNewItem

    addNewItem同样在setup中编写如下:

    // 点击添加按钮,添加新的待办事项
    let addNewItem = () => {
      // 输入框非空判断
      if (!newItem.value) {
        return
      }
      // 使用push为数组添加新元素
      let obj = {
        id: id, // id 唯一且自增
        title: newItem.value, // todo 标题
      }
      items.value.push(obj)
      // id 自增
      id++
      // 清空输入框
      newItem.value = ''
    }
    

     在 setup中,我们声明一个变量id默认为 0,items默认为空数组,newItem为空字符串。输入框输入内容后,点击添加按钮 items 中 push 一条内容,其中包括 id 与 title,然后 id 自增,并且最后将输入框清空。

    总结

     通过以上几个关键的知识点,我们最终就实现了 ToDoList 的基本功能,效果如下:

    Vue项目实战(二)——Vue3+Vite+TypeScript实现ToDoList|刷题打卡

     如果喜欢,可以再加一些样式。

     路漫漫其修远兮,与诸君共勉。

    参考文献:

    • Vue 官网
    • vue3.0 中 setup 使用 | CSDN - 前端小 99
    • Vue3 - defineComponent 解决了什么? | CSDN - MINO 吖
    • 使用 Vue3+TS 开发一个 TODOList 的应用 | CSDN - Maddix

    附 ToDoList.vue 代码

    <template>
      <h1>{{ msg }}</h1>
      <div>
        待办:<input type="text" v-model="newItem" />
        <button @click="addNewItem">添加</button>
      </div>
      <ul class="ToDoList">
        <li v-for="(item, index) in items" :key="item.id">
          <!-- 待办事项 -->
          <span v-text="item.title"></span>
          <!-- 完成按钮 -->
          <button v-on:click="deleteItem(index)">完成</button>
        </li>
      </ul>
    </template>
    
    <script lang="ts">
    import { ref, defineComponent } from 'vue'
    export default defineComponent({
      name: 'ToDoList',
      props: {
        msg: {
          type: String,
          required: true,
        },
      },
      // setup 函数是 Composition API(组合 API)的入口
      // 几乎所有东西都在setup()方法中,包括挂载的生命周期挂钩。
      setup: () => {
        const items = ref([
          {
            id: 1,
            title: '吃饭',
          },
          {
            id: 2,
            title: '睡觉',
          },
          {
            id: 3,
            title: '打豆豆',
          },
        ])
        // 绑定输入框内容
        let newItem = ref('')
        // id 唯一且自增
        let id = 0
        // 点击完成按钮,删除对应事项
        let deleteItem = (index: number) => {
          items.value.splice(index, 1)
        }
        // 点击添加按钮,添加新的待办事项
        let addNewItem = () => {
          // 输入框非空判断
          if (!newItem.value) {
            return
          }
          // 使用push为数组添加新元素
          let obj = {
            id: id, //
            title: newItem.value, // todo 标题
          }
          items.value.push(obj)
          // id 自增
          id++
          // 清空输入框
          newItem.value = ''
        }
        // 注意:这里一定要return,不然在模板中是获取不到它的值的。
        return { items, id, newItem, deleteItem, addNewItem }
      },
    })
    </script>
    
    <style scoped></style>
    

    后记:Hello 小伙伴们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富文章的动力!GitHub 地址


    下载网 » Vue项目实战(二)——Vue3+Vite+TypeScript实现ToDoList|刷题打卡

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元