Quasar开发总结

Posted by Wh0ami-hy on March 24, 2024

1. 创建项目

Vue版本选择Vue3

Vue组件风格选择:composition API(组合式API)

CSS preprocessor(CSS预处理器)选择:SCSS

其他选择:ESLint(选Prettier规则,这样可以搭配vscode中的插件进行自动格式化)、Pinia、Axios、Vue-i18n、Vite、Vue-router

2. 父子组件通信

  • 封装子组件,先定义子组件需要接收的属性、数据
  • 在父组件中,调用子组件,通过子组件的props传入子组件所需属性、数据
  • 对于弹窗类的子组件,需要在子组件中使用:model-value="switch"双向绑定来控制弹窗的显示状态。父组件在调用时,将switch置为true传入子组件v-model:switch="switch",则子组件打开。子组件关闭时,需要在子组件中使用$emit,将父组件中定义的switch置为false,则子组件关闭
  • 在父组件中调用子组件,可将父组件中的函数与子组件中的函数绑定
  • 在子组件中改动的父组件的数据,最后一定要通过$emit传回给父组件
  • 子组件中不提供数据,只是通用模板的封装,数据是存在于父组件中的,数据源于父组件,最后要归于父组件

    3. 删除数组中的数据

在Vue或类似的现代前端框架中,使用过滤操作来“删除”数据项,而不是直接的删除操作,有几个原因:

  • 不变性(Immutability): 通过过滤创建一个新数组,而不是直接修改原始数组,可以保持数据的不变性。这是函数式编程中的一个常见概念,有助于避免副作用,使状态管理更加可预测。
  • 响应式更新: 在Vue中,数组的响应式更新是通过替换数组或更新数组的长度来触发的。直接使用过滤方法返回一个新数组,可以确保Vue能够检测到数据的变化,并自动更新DOM。如果直接在原数组上进行删除操作(如使用splice),虽然Vue也能检测到变化,但使用过滤方法在概念上更简单,代码更清晰。
  • 简洁性: 使用过滤方法可以用一行代码实现删除功能,代码更加简洁明了。过滤方法直接表达了“我们想要的是除了某项之外的所有项”的意图,这比手动遍历数组并删除特定项要直观得多。
  • 功能性: 过滤方法是一种声明式编程的体现,它描述了我们想要的结果(一个不包含被删除项的新数组),而不是如何通过各种操作达到这个结果。这种方式使得代码更容易理解和维护。

总之,使用过滤操作来“删除”数据项,是一种更符合现代前端框架设计哲学的做法,它提高了代码的清晰度、可维护性和响应式能力。

4. 页面交互样式统一

网格:一整个大的页面作为一个div,在该div中再划分div布置页面内容,页脚footer的div应与最外层div同级

组件的样式,使用自带的样式,不自己写css实现

消息提示notify统一从 top弹出

全局统一颜色:警告、成功、失败、信息等

全局使用统一风格:如蓝白灰色

全局组件采用圆润风格,有轻微阴影

全局的组件应该统一采用卡片的方式进行布置

页面的设计、布局、交互,尽量做到在PC、移动端都能顺手且美观

5. 响应式布局

<div class="row"> </div>

布局怎么区分是用column(列)还是row(行)

左右划分是在行内进行的,表示占几列(col)

上下划分是在列内进行的,表示占几行(col)

什么是响应式布局

页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整

响应式网站常见特点:

  • 同时适配PC + 平板 + 手机等

  • 标签导航在接近手持终端设备时改变为经典的抽屉式导航

  • 网站的布局会根据视口来调整模块的大小和位置

6. vue-echarts切换定制主题

从echarts官网保存定制主题的.json文件,该文件内容格式如下

{
    "version": 1,
    "themeName": "westeros",
    "theme": {

    }
}

只需要保留theme后面的值即可

{
...
...
...
    }

引入json文件

import westeros from "westeros.json";

注册主题

import { registerTheme } from "echarts/core";
registerTheme("theme", westeros);

使用主题

provide(THEME_KEY, "theme");

完整代码

import westeros from "westeros.json";
import { registerTheme } from "echarts/core";
registerTheme("theme", westeros);
provide(THEME_KEY, "theme");

7. vue-i18n国际化

在创建项目的时候勾选vue-i18n,否则需要手动做配置

翻译内容需要手动准备

en

export default {

  // Add your translations here

  failed: "Action failed",

  success: "Action was successful",

  welcome: "Welcome",

  goodbye: "Goodbye",

  hello: "Hello",

  language: "Language",

};

zh

export default {

  // Add your translations here

  failed: "失败",

  success: "成功",

  welcome: "欢迎",

  goodbye: "再见",

  hello: "你好",

  language: "语言",

};

按官网步骤一步步来即可

8. Vue Router实现路由鉴权

前端实现页面级的权限控制

路由动态渲染、身份验证

8.1. meta属性

给路由添加额外的附加信息,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的meta属性来实现,并且它可以在路由地址和导航守卫上都被访问到

const asyncRouterMap = [{

        path: '/permission',
        component: Layout,
        name: '权限测试',
        meta: {
        //访问页面需要的角色
            role: ['admin', 'super_editor']
        },
        children: [{
                path: 'index',
                component: Permission,
                name: '权限测试页',
                meta: {
                //访问页面需要的角色
                    role: ['admin', 'super_editor']
                }
            }
        ]
    }
]

如何访问这个 meta 字段呢

一个路由匹配到的所有路由记录会暴露为 route 对象的route.matched 数组。我们需要遍历这个数组来检查路由记录中的 meta 字段,但是 Vue Router 还为你提供了一个 route.meta 方法,它是一个非递归合并所有 meta 字段(从父字段到子字段)的方法

8.2. 动态路由

动态路由主要通过两个函数实现。router.addRoute() 和 router.removeRoute()

9. 实现轮播文字效果

<template>
    <div class="box">
        <transition name="roll">
            <div class="inner" :key="index">
                
            </div>
        </transition>
    </div>
</template>

<script setup>
import { reactive, ref } from 'vue'

const list = reactive(['轮播文字11111111', '轮播文字222222222222', '轮播文字33333333333333333333'])
const index = ref(0)
setInterval(() => (index.value === list.length - 1 ? (index.value = 0) : index.value++), 2000)
</script>
<style scoped>

.box {

  position: relative;

  height: 50px;

  background-image: linear-gradient(

    90deg,

    rgba(13, 0, 36, 1) 0%,

    rgba(46, 59, 202, 0.8) 100%

  );

  font-size: 16px;

  color: #fff;

  padding: 0 10px;

  .inner {

    position: absolute;

    height: 100%;

    display: flex;

    align-items: center;

  }

}

.roll-enter-active,

.roll-leave-active {

  transition: all 0.4s ease-in-out;

}

  

.roll-enter-from {

  transform: translateY(100%);

}

.roll-leave-to {

  transform: translateY(-100%);

}

</style>

本站总访问量