Vue相关案例

案例一

案例:实现v-for的模板编译

根据响应式数据渲染模板到页面

技术:

JavaScript ES5/vite/数据响应式/模板编译

问题:如何实现数据响应式?

Proxy代理劫持数据

项目结构:

  1. ├─app.js
  2. ├─index.html
  3. ├─package.json
  4. ├─MyVue3.0
  5. | ├─application.js -管理响应式数据组件初始化/页面挂载创建
  6. | ├─compile.js -模板编译/编译节点/替换节点/实现v-for{}/{{}}文本替换
  7. | ├─handler.js - 处理proxy代理里的getter/setter方法
  8. | ├─index.js
  9. | ├─reactive.js - 实现数据响应式
  10. | utils.js - 工具:判断是否是对象
  11. ├─components
  12. | ├─TestB
  13. | | index.js
  14. | ├─TestA
  15. | | index.js

模拟 vue3.x版本环境下搭建的v-for

  1. //app.js
  2. import { createApp } from './createApp';
  3. import TestA from './components/TestA';
  4. const app = createApp({
  5. components: [
  6. TestA
  7. ]
  8. });
  9. app.mount('#app');
  1. //createApp.js
  2. export function createApp() {
  3. return {
  4. mount: mount
  5. }
  6. }
  7. function mount(el) { }

源码地址:

https://gitee.com/kevinleeeee/v-for-vue3.x-demo

案例二

案例:万年历

功能:

  • 当天/当月/当年的日期信息

聚合接口:

  • 获取当前的详细信息
  • 获取近期的假期
  • 获取当年所有假期
  1. //项目创建
  2. vue create calendar-pro
  3. //增加vue3特性
  4. vue add vue-next

vue3.0 提供了极大的程序设计的可能性,它单独的抛出了许多的 Composition API 组合,每个 API实际上是独立的,可以在任何地方(vue,vuex)去取出相应的 API到程序里调用,每个 Composition API 都是一个工具函数,方便不同的应用场景下使用来完成逻辑业务需要

  1. //vue3.0开发思想,Composition API组合的函数都要解构出来使用
  2. //像vue2.0里的method/data/computed...
  3. import { computed, watch, onMounted } from "vue";
  4. //setup函数:所有逻辑在里面编写,并把视图所有需要的属性和方法一一导出

程序开发优先考虑数据,有了数据才开始写视图,没有数据先模拟数据

  1. //项目目录
  2. ├─babel.config.js
  3. ├─package.json
  4. ├─README.md
  5. ├─vue.config.js - 配置后端数据代理/关闭eslint
  6. ├─src
  7. | ├─App.vue - 根页面结构/路由占位/组件缓存/路由重定向/路由地址侦听改变state
  8. | ├─main.js - 入口文件/创建应用/注册路由/注册store/挂载应用
  9. | ├─views - 视图层
  10. | | ├─Day.vue 当天页面组件/组件通信/挂载时请求后台数据/侦听修改state
  11. | | ├─Month.vue 近期页面组件/组件通信/挂载时请求后台数据/侦听修改state
  12. | | Year.vue 当年页面组件/组件通信/挂载时请求后台数据/侦听修改state
  13. | ├─store
  14. | | ├─index.js - 出口文件/创建Store实例/注册state,mutations
  15. | | ├─mutations.js - 管理state修改的方法(修改标题,输出内容长度,输入内容,错误代码,请求数据,缓存field)
  16. | | states.js - 初始化state对象(标题,输入内容,长度,错误状态码,请求数据)
  17. | ├─services - 数据请求层
  18. | | ├─index.js - 封装请求数据方法/请求到的数据提交存入state
  19. | | request.js - 封装接口请求方法/获取当天/近期/当年详细信息
  20. | ├─router
  21. | | index.js - 路由出口文件/配置路由地址和对应(或动态)加载组件/创建组件实例
  22. | ├─libs
  23. | | ├─https.js - 封装请求数据POST/GET方法
  24. | | utils.js - 工具:加零/拿图标日期/格式化中文日期/拿当前日期/格式化输入日期
  25. | ├─data
  26. | | ├─error.js - 错误状态代码对象数据
  27. | | tab.js - 底栏tab的图标数组数据
  28. | ├─configs
  29. | | keys.js - 配置聚合appKey
  30. | ├─components
  31. | | ├─YearPage - 当前组件
  32. | | | ├─Item.vue - 子项/绑定视图
  33. | | | List.vue - 列表项/遍历子项/传参
  34. | | ├─Tab - tab图标底栏组件
  35. | | | ├─Icon.vue - 子项/图标/路由跳转链接/绑定视图
  36. | | | index.vue - 遍历子项/传参
  37. | | ├─SearchInput - 输入框组件
  38. | | | index.vue - 绑定视图/根据输入内容做事件处理/侦听修改
  39. | | ├─MonthPage - 近期组件
  40. | | | ├─Item.vue - 子项/绑定视图
  41. | | | List.vue - 列表项/遍历子项/传参
  42. | | ├─Header - 标题组件
  43. | | | index.vue 定义视图插槽/根组件设置标题内容
  44. | | ├─ErrorTip - 错误提示组件
  45. | | | index.vue - 获取错误状态码/绑定视图
  46. | | ├─DayPage - 当天组件
  47. | | | ├─Card.vue - 出口/绑定视图/传参
  48. | | | ├─List
  49. | | | | ├─index.vue - 列表项/传参
  50. | | | | Item.vue - 子项/视图绑定
  51. | ├─assets
  52. | | ├─js
  53. | | | ├─common.js
  54. | | | fastclick.js
  55. | | ├─img
  56. | | | ├─bg.jpg
  57. | | | ├─error.png
  58. | | ├─css
  59. | | | ├─border.css
  60. | | | resets.css
  61. ├─public
  62. | ├─favicon.ico
  63. | index.html

源码地址:

https://gitee.com/kevinleeeee/vue3-wannianli-demo

案例三

案例:星座运势

功能:

  • tab底栏(今天/明天/本周/本月/本年)
  • 标题
  • nav栏(12 星座)
  • 卡片
  • 健康指数
  • 列表

聚合接口:

  1. 接口地址:http://web.juhe.cn/constellation/getAll
  2. 返回格式:json
  3. 请求方式:http get
  4. 请求示例:http://web.juhe.cn/constellation/getAll?consName=%E7%8B%AE%E5%AD%90%E5%BA%A7&type=today&key=申请的KEY
  5. 接口备注:十二星座的今日运势

请求参数说明:

名称 必填 类型 说明
key string 在个人中心->我的数据,接口名称上方查看
consName string 星座名称,如:双鱼座
type string 运势类型:today,tomorrow,week,month,year

JSON返回示例:

  1. /*今日或明日运势格式*/
  2. {
  3. "name": "狮子座",
  4. /*星座名称*/
  5. "datetime": "2014年06月27日",
  6. /*日期*/
  7. "date": 20140627,
  8. "all": "89",
  9. /*综合指数*/
  10. "color": "古铜色",
  11. /*幸运色*/
  12. "health": "95",
  13. /*健康指数*/
  14. "love": "80",
  15. /*爱情指数*/
  16. "money": "84",
  17. /*财运指数*/
  18. "number": 8,
  19. /*幸运数字*/
  20. "QFriend": "处女座",
  21. /*速配星座*/
  22. "summary": "有些思考的小漩涡... ",/*今日概述*/
  23. "work": "80" /*工作指数*/
  24. "error_code": 0 /*返回码*/
  25. }

问题:如何对 nav栏(白羊座/处女座..)切换时实现内容更新切换?

在点击 nav栏时重新向后端请求数据,配合actived激活函数,解决组件不同步的问题

  1. export default {
  2. ...,
  3. setup() {
  4. const store = useStore(),
  5. state = store.state,
  6. status = ref("");
  7. onMounted(() => {
  8. getData(store);
  9. //定义的响应式状态属性在挂载组件时保存了consName数据(金牛座)
  10. status.value = state.consName;
  11. });
  12. //激活函数
  13. onActivated(() => {
  14. //如果他俩不同,说明上面挂载组件的阶段还没有进行过
  15. //此操作可以解决组件不同步的问题
  16. if (status.value !== state.consName) {
  17. getData(store);
  18. status.value = state.consName;
  19. }
  20. });
  21. },
  22. };
  1. //项目目录:
  2. ├─vue.config.js - 关闭eslint/代理跨域
  3. ├─src
  4. | ├─App.vue - 根组件/页面结构/路由重定向/路由地址监听/修改state
  5. | ├─main.js - 入口文件/注册App/插件/store/路由
  6. | ├─views
  7. | | ├─Month.vue - 本月页面内容组件/组件挂载请求数据/修改state/视图绑定更新
  8. | | ├─Today.vue - 同上
  9. | | ├─Tomorrow.vue - 同上
  10. | | ├─Week.vue - 同上
  11. | | Year.vue - 同上
  12. | ├─store
  13. | | ├─index.js
  14. | | ├─mutations.js
  15. | | state.js
  16. | ├─services
  17. | | ├─index.js
  18. | | request.js
  19. | ├─router
  20. | | index.js
  21. | ├─libs
  22. | | ├─https.js
  23. | | utils.js
  24. | ├─directives - 自定义指令
  25. | | ├─index.js - 出口文件
  26. | | navCurrent.js - 挂载/更新方法时定义相关逻辑
  27. | ├─datas
  28. | | ├─cache.js
  29. | | ├─error.js - 错误状态码数据
  30. | | ├─nav.js - nav栏数据
  31. | | ├─num.js - 指数数据
  32. | | tab.js - tab底栏图标数据
  33. | ├─configs
  34. | | keys.js
  35. | ├─components
  36. | | ├─Tab
  37. | | | ├─Icon.vue - 图标组件
  38. | | | index.vue - 底栏组件
  39. | | ├─NumList
  40. | | | ├─index.vue
  41. | | | Item.vue
  42. | | ├─NavBar
  43. | | | ├─index.vue
  44. | | | Item.vue
  45. | | ├─List
  46. | | | ├─MonthList.vue - 本月内容组件(里面包含复用的组件)
  47. | | | ├─TodayList.vue - 今天内容组件(里面包含复用的组件)
  48. | | | ├─TomorrowList.vue - 明天内容组件(里面包含复用的组件)
  49. | | | ├─WeekList.vue - 本周内容组件(里面包含复用的组件)
  50. | | | YearList.vue - 本年内容组件(里面包含复用的组件)
  51. | | ├─Header
  52. | | | index.vue
  53. | | ├─ErrorTip
  54. | | | index.vue
  55. | | ├─common
  56. | | | ├─Card.vue - 公共卡片组件
  57. | | | ├─ConsItem.vue - 公共子项内容组件
  58. | | | ├─index.js - 全局组件注册的出口文件
  59. | | | Summary.vue - 公共运势总结组件
  60. | ├─assets
  61. | | ├─js
  62. | | | ├─common.js
  63. | | | fastclick.js
  64. | | ├─img
  65. | | | ├─cons.png
  66. | | | ├─error.jpg
  67. | | | ├─双子座.jpeg
  68. | | ├─css
  69. | | | ├─border.css
  70. | | | resets.css
  71. ├─public
  72. | index.html

源码地址:

https://gitee.com/kevinleeeee/vue3-constellation-demo

案例四

案例:驾照题库(未完成)

备注:

目前完成至首页的组件编写,答题和结果还没完成

功能:

  • 页面:首页选择/答题/结果
  • 后端数据本地缓存
  1. //项目结构:
  2. ├─vue.config.js
  3. ├─src
  4. | ├─App.vue - 根组件/视图结构/监听路由
  5. | ├─main.js - 入口文件
  6. | ├─views
  7. | | ├─index.vue 首页页面区域
  8. | | ├─Result.vue
  9. | | Test.vue
  10. | ├─store
  11. | | ├─index.js
  12. | | ├─mutations.js
  13. | | state.js
  14. | ├─services
  15. | | ├─index.js - 请求数据函数
  16. | | request.js - 请求数据函数里的请求方法
  17. | ├─router
  18. | | index.js
  19. | ├─libs
  20. | | https.js - 封装axios请求
  21. | ├─datas
  22. | | ├─error.js
  23. | | ├─subject1&a1.js - 缓存后端数据
  24. | | ├─subject1&a2.js
  25. | | ├─subject1&b1.js
  26. | | ├─subject1&b2.js
  27. | | ├─subject1&c1.js
  28. | | ├─subject1&c2.js
  29. | | ├─subject4&a1.js
  30. | | ├─subject4&a2.js
  31. | | ├─subject4&b1.js
  32. | | ├─subject4&b2.js
  33. | | ├─subject4&c1.js
  34. | | subject4&c2.js
  35. | ├─configs
  36. | | ├─keys.js
  37. | | ├─model.js - 驾照类型数据
  38. | | subject.js - 科目类型数据
  39. | ├─components
  40. | | ├─SubjectSelector - 科目选择组件
  41. | | | ├─index.vue - 遍历子项/传数据
  42. | | | Item.vue - 绑定模板/点击事件/修改state
  43. | | ├─ModelSelector 驾照选择组件
  44. | | | ├─index.vue - 遍历子项/传数据
  45. | | | Item.vue - 绑定模板/点击事件/修改state
  46. | | ├─Header
  47. | | | index.vue
  1. 接口地址:http://v.juhe.cn/jztk/query
  2. 返回格式:json
  3. 请求方式:get post
  4. 请求示例:http://v.juhe.cn/jztk/query?subject=1&model=c1&key=您申请的appKey&testType=rand
  5. 接口备注:根据输入参数返回相关题目

请求参数说明:

名称 必填 类型 说明
key string 您申请的 appKey
subject int 选择考试科目类型,1:科目 1;4:科目 4
model string 驾照类型,可选择参数为:c1,c2,a1,a2,b1,b2;当 subject=4 时可省略
testType string 测试类型,rand:随机测试(随机 100 个题目),order:顺序测试(所选科目全部题目)

返回参数说明:

注意: 当四个选项都为空的时候表示判断题,item1:正确 item2:错误,请开发者自行判断!

名称 类型 说明
error_code int 返回状态码
reason string 返回原因
result string 题目内容

JSON返回示例:

  1. {
  2. "error_code": 0,
  3. "reason": "ok",
  4. "result": [{
  5. "id": 12,
  6. "question": "这个标志是何含义?", //问题
  7. "answer": "4", //答案
  8. "item1": "前方40米减速", //选项,当内容为空时表示判断题正确选项
  9. "item2": "最低时速40公里", //选项,当内容为空时表示判断题错误选项
  10. "item3": "限制40吨轴重",
  11. "item4": "限制最高时速40公里",
  12. "explains": "限制最高时速40公里:表示该标志至前方限制速度标志的路段内,机动车行驶速度不得超过标志所示数值。此标志设在需要限制车辆速度的路段的起点。以图为例:限制行驶时速不得超过40公里。", //答案解释
  13. "url": "http://images.juheapi.com/jztk/c1c2subject1/12.jpg" //图片url
  14. }]
  15. }

源码地址:

https://gitee.com/kevinleeeee/vue3-license-demo

案例五

案例:UI 插件-轮播图

技术: vue3.x

功能:

  • 插槽的方式定义视图结构
  • 用户自定义插件配置
  • 自动轮播
  • 小圆点指示器联动图片
  • 两侧按钮向前向后翻图片
  1. //用户自定义的配置项
  2. <carousel
  3. :autoplay="true"
  4. :duration="3000"
  5. :initial="4"
  6. :hasDot="true"
  7. :hasDirector="true"
  8. :dotBgColor="'#000'"
  9. :autoplayDir="'prev'"
  10. >
  1. //项目结构:
  2. ├─package.json
  3. ├─README.md
  4. ├─src
  5. | ├─App.vue - 根组件/用户配置/定义子组件插槽内容/遍历子组件
  6. | ├─main.js - 入口文件/注册插件
  7. | ├─libs
  8. | | ├─myUi
  9. | | | ├─index.js - 插件出口文件/全局注册组件
  10. | | | ├─Carousel
  11. | | | | ├─Director.vue - 两侧按钮组件
  12. | | | | ├─Dot.vue - 小圆点组件/根据索引长度定义圆点个数
  13. | | | | ├─index.vue - 出口文件/父组件/业务逻辑/视图绑定事件/定义子组件插槽内容
  14. | | | | Item.vue - 每一张图片组件/组件实例绑定响应式索引和自身索引
  15. | ├─data
  16. | | carousel.js - 定义图片名称数据
  17. | ├─assets
  18. | | ├─img
  19. | | | ├─1.jpg
  20. | | | ├─2.jpg
  21. | | | ├─3.jpg
  22. | | | ├─4.jpg
  23. | | | 5.jpg
  24. ├─public
  25. | index.html

问题:如何改变自定义配置项initial来操作视图显示指定下标的初始图片?

  1. 子组件标签属性定义v-if="selfIndex === currentIndex"
  2. 通过 Composition API 里的getCurrentInstance方法拿到组件实例
  3. 通过组件实例里的vnode.key属性拿到遍历子组件时的自身index
  4. 通过组件实例的parent.ctx.currentIndex属性拿到组件执行期上下文里定义的currentIndex
  5. 并将selfIndexcurrentIndex属性做响应式处理并返回视图使用
  6. 此时,用户修改标签属性initial的值改变视图显示下标的图片

问题:如何拿到父组件v-for遍历的item长度?

通过访问组件实例里slots.default()[0].children.length属性可以拿到

问题:如何实现自动轮播功能?

  1. Carousel组件里新增逻辑
  2. 定义定时器方法和延迟时间duration
  3. 组件挂载完毕时拿到父组件v-for遍历的item长度
  4. 执行定时器方法,并在组件卸载之前需要清除计时器
  5. 定时器方法里执行setIndex(dir)函数
  6. 通过 currentIndex 下标来显示指定图片
  7. 具体实现:

    1. 方向为nextcurrentIndex === itemLen说明到达最后一张图片时,将currentIndex重置为 0
    2. 方向为prevcurrentIndex === -1 说明到达第一张图片时,将currentIndex重置为itemLen - 1最后一项

问题:如何给轮播图添加动画效果?

  1. 先给子组件视图嵌套<transition>标签
  2. 定义类
  1. .v-enter-active,
  2. .v-leave-active {
  3. transition: all 0.3s linear;
  4. }
  5. .v-enter-active {
  6. transform: translateX(100%);
  7. }
  8. .v-enter-to {
  9. transform: translateX(0);
  10. }
  11. .v-leave-active {
  12. transform: translateX(0);
  13. }
  14. .v-leave-to {
  15. transform: translateX(-100%);
  16. }

问题:如何实现用户配置:hasDot="true"来显示或隐藏小圆点指示器?

通过子组件模板绑定v-if="hasDot"父组件传递过来的hasDot属性决定是否显示

问题:如何实现操作小圆点指示器?

  1. 定义子组件 Dot.vue
  2. 遍历父组件item长度v-for="item in itemLen"
  3. 父组件Carousel传的值有:itemLen,currentIndex,hasDot,dotBgColor
  4. 子组件视图<a>标签动态绑定属性:style="{ backgroundColor: item - 1 === currentIndex ? dotBgColor : '#fff',}"
  5. 以上绑定会实现:

    1. 小圆点同步图片的索引显示当前选中的圆点状态
    2. 同时实现用户配置的选中小圆点的颜色操作(默认为橙色)
  6. 向父组件emit事件传递index
  7. 父组件定义点击事件并根据子组件传的index修改currentIndex实现点击小圆点同步当前轮播的图片

问题:如何实现鼠标移入停止轮播?

  1. Carousel组件视图绑定两个事件:mouseenter/mouseleave
  2. 鼠标移入时清除定时器实现停止轮播
  3. 鼠标移出时重新执行定时器内部封装的autoPlay函数实现继续轮播

问题:如何实现左右两侧按钮?

  1. 定义子组件 Director.vue
  2. <div>标签定义属性v-if="dir === 'next'"实现用户配置操作是否显示两侧按钮
  3. <a>标签定义点击事件@click="dirClick(dir)"
  4. 另一个<div>标签定义属性v-else-if="dir === 'prev'"
  5. <a>标签定义点击事件@click="dirClick(dir)"
  6. 定义dirClick函数并把dir参数emit事件传递给父组件
  7. 父组件同时挂载向前和向后组件并各加上属性dir="next"dir="prev"
  8. 父组件根据dirClick事件处理函数复用setIndex函数即可实现向前/向后翻逻辑
  9. 实现点击 prev/next 按钮显示前一张或后一张图片

源码地址:

https://gitee.com/kevinleeeee/vue3-uiplugin-caroucel-demoLL