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

vue3-vben-admin开发记录、知识点

vue3-vben-admin知识点

一、vue3写法

1、生命周期

setup-组件在创建时

onMounted-挂载在dom时运行

onUpdated-响应数据修改时运行

2、reactive

定义: 接收一个普通对象然后返回该普通对象的响应式代理。等同于 2.x 的 Vue.observable()

定义一个全局常量

let otherParam = reactive({
        result: null as any, //设置类型,不设置则为never
        title: '',
        tabledata: [] as any[],
        readid: null as any,
        type: null as any,
        data: null as any,
        workflownumber: '',
      });

TS声明文件,因为TS直接引用第三方JS库的时候,虽然可以用,但是是没有类型检查,所以我们需要做一个声明文件,来声明这些第三方库的类型,这样在使用第三方库的时候,就有类型了

declare module

3、父子组件相互调用

3.1父组件调用子组件

先引入组件页面:

import PersonTable from './PersonTable.vue';

在引入组件,并设置ref

    <a-card title="所得荣誉" :bordered="false">
      <PersonTable ref="tableRef" />
    </a-card>

定义常量,引用方法:

const tableRef = ref<{ getDataSource: () => any; test } | null>(null);

调用:

console.log(tableRef.value.test(otherParam.data));

注意:

如果是通过ref调用子组件的方法并需要取其返回值,可能出现有时间差问题,点击部门列表进行筛选时,获取的返回值总是为上一次点击的,就是因为实际上获取的值是ref上一次存储的值,本次需要获取的值还没来得及更新。所以为了避免这个问题,可以使用VUE提供的 watch 特性来监视ref值的变更。

例子:vue-vben-admin-awards:D:\workspace\vscode\vue-vben-admin-awards\src\views\user\DeptTree.vue

watch(
        () => treeRef.value?.getSelectedKeys()[0],
        (newValue, oldValue) => {
          if (newValue !== oldValue) {
              // 在这里执行其他操作,例如触发事件或者调用其他函数
            handleSelect();
          }
        },
      );

function handleSelect() {
        const key = treeRef.value?.getSelectedKeys()[0];
        console.log(key);
        emit('select', key);
      }
3.2子组件调用父组件

可以在子组件使用emits定义事件,再在父组件中监听该事件,当监听到该事件时,出发相应的函数逻辑:

//子组件DeptTree

emits: ['select'],   //定义select事件
    setup(_, { emit }) {
      const treeRef = ref<{ getSelectedKeys: () => any } | null>(null);

      function handleSelect() {
        const key = treeRef.value?.getSelectedKeys()[0];
        emit('select', key); //触发select事件,并传递参数key
      }
}
//父组件
<DeptTree class="w-1/4 xl:w-1/5" @select="handleSelect" />   //监听select事件,触发时执行handleSelect函数方法


function handleSelect(deptId = '') {  //定义参数deptId,默认值为空,接收子组件传来的key
        console.log(deptId);
        searchInfo.code = deptId;
        reload();
      }

4、路由跳转

//引入
import { useRouter } from 'vue-router';
//获取对象
const router = useRouter();
//路由跳转并携带参数
router.push({
          name: 'high',
          //path:"/detail/high",   //不要这个也行
          params: {
            value: record.pkid,
            title: title,
          },
        });


//目的页面接收参数
let otherParam = reactive({
        showA: false,
        result: null as any, //设置类型,不设置则为never
        title: '',
        tabledata: [] as any[],
        pkid: null as any,
        type: null as any,
        data: null as any,
      });
      const route = useRoute();
      const getParams = () => {
        return route.params;
      };
      // Composition API 生命周期写法
      onMounted(() => {
        console.log('mounted:' + getParams().value);
        otherParam.title = '' + getParams().title;
        otherParam.pkid = getParams().value;
      });

5、表单工具FormSchema

ApiSelect类型的下拉框,formActionType获取整个表单的对象,更新表单的方法updateSchema([{}])

{
    label: '角色',
    field: 'roleName',
    component: 'ApiSelect',
    componentProps: ({ schema, tableAction, formActionType, formModel }) => {
      return {
        onChange: (e: ChangeEvent) => {
          console.log('change' + e);
          if ('' + e == 'Super') {
            formActionType.updateSchema([
              {
                field: 'college',
                ifShow: false,
              },
            ]);
            formActionType.updateSchema([
              {
                field: 'profession',
                ifShow: false,
              },
            ]);
            formActionType.updateSchema([
              {
                field: 'tclass',
                ifShow: false,
              },
            ]);
          } else if ('' + e == 'Department') {
            formActionType.updateSchema([
              {
                field: 'college',
                ifShow: true,
              },
            ]);
            formActionType.updateSchema([
              {
                field: 'profession',
                ifShow: false,
              },
            ]);
            formActionType.updateSchema([
              {
                field: 'tclass',
                ifShow: false,
              },
            ]);
          } else if ('' + e == 'student') {
            formActionType.updateSchema([
              {
                field: 'college',
                ifShow: true,
              },
            ]);
            formActionType.updateSchema([
              {
                field: 'profession',
                ifShow: true,
              },
            ]);
            formActionType.updateSchema([
              {
                field: 'tclass',
                ifShow: true,
              },
            ]);
          }
        },
        api: getdropdownselectList,
        params: { type: 'roleName' },
        labelField: 'roleName',
        valueField: 'roleValue',
      };
    },
    required: true,
  },

6、获取用户对象数据

import { useUserStore } from '/@/store/modules/user';

const userStore = useUserStore();

const username = computed(() => userStore.getUserInfo.username || headerImg);

7、await Promise.all

1.await 可以获得多个promise 的返回结果

2.Promise.all 返回的也是promise,所以可以直接await Promise.all();

获取两个表单的数据:

const [register, { validate }] = useForm({
        layout: 'vertical',
        baseColProps: {
          span: 6,
        },
        schemas: schemas,
        showActionButtonGroup: false,
      });

      const [registerTask, { validate: validateTaskForm }] = useForm({
        layout: 'vertical',
        baseColProps: {
          span: 6,
        },
        schemas: taskSchemas,
        showActionButtonGroup: false,
      });

const [values, taskValues] = await Promise.all([validate(), validateTaskForm()]);
console.log('form data:', values, taskValues);

8、ES6 扩展运算符 三个点(…)

es6中引入扩展运算符(…),它用于把一个数组转化为用逗号分隔的参数序列,它常用在不定参数个数时的函数调用,数组合并等情形。因为typeScript是es6的超集,所以typeScript也支持扩展运算符

用法:
可变参数个数的函数调用
function push(array, ...items) {  
  array.push(...items);  
}  

function add(...vals){
  let sum=0;
  for(let i=0;i<vals.length;i++){
    sum+=vals[i];
  }
  return sum;
}

let arr = [1,2,3,4,5,6];
let sum = add(...arr);
console.log(sum);  //21
更便捷的数组合并
let arr1 = [1,2];
let arr2 = [5,6];
let newArr = [20];
//es5 旧写法
newArr = newArr.concat(arr1).concat(arr2); //[20,1,2,5,6]
console.log(newArr);
//es6 使用扩展运算符
newArr = [20,...arr1,...arr2];  //[20,1,2,5,6]
console.log(newArr);
替代es5的apply方法
// ES5 的写法  
function f(x, y, z) {  
// ...  
}  
var args = [0, 1, 2];  
f.apply(null, args);  
// ES6 的写法  
function f(x, y, z) {  
// ...  
}  
var args = [0, 1, 2];  
f(...args);  
求最大值Math.max()
// ES5 的写法  
Math.max.apply(null, [14, 3, 77])  
// ES6 的写法  
Math.max(...[14, 3, 77])  
//  等同于  
Math.max(14, 3, 77);  
通过push函数,将一个数组添加到另一个数组的尾部
// ES5 的写法  
var arr1 = [0, 1, 2];  
var arr2 = [3, 4, 5];  
Array.prototype.push.apply(arr1, arr2);  
// ES6 的写法  
var arr1 = [0, 1, 2];  
var arr2 = [3, 4, 5];  
arr1.push(...arr2);  
新建Date类型
// ES5  
new (Date.bind.apply(Date, [null, 2015, 1, 1]))  
// ES6  
new Date(...[2015, 1, 1]);  
与解构赋值结合,生成新数组
// ES5  
a = list[0], rest = list.slice(1)  
// ES6  
[a, ...rest] = list 
下面是另外一些例子。  
const [first, ...rest] = [1, 2, 3, 4, 5];  
first // 1  
rest // [2, 3, 4, 5]  
const [first, ...rest] = [];  
first // undefined  
rest // []:  
const [first, ...rest] = ["foo"];  
first // "foo"  
rest // [] 
将字符串转为真正的数组
[...'hello']  
// [ "h", "e", "l", "l", "o" ]  
将实现了 Iterator 接口的对象转为数组
var nodeList = document.querySelectorAll('div');  
var array = [...nodeList];  

//接第七点,解包values、taskValues两个对象
individualsubmit({ ...values, ...taskValues, mylist, ttype, wfnum }).then(function (response) {
            console.log(response);
            if (response == 'success') {
              createMessage.success('提交成功!');
              issubmit.value = !issubmit.value;
            }
          });

json对象做三元表达式判断

{
type: "refer",
key: "machineNumber",
label: "整机编号",
refinfo: "equipmentPool",
refName: "整机",
 isReturnCode: true,
clientParam: {
    EQ_isEnable: "1",
   // EQ_agent: JSON.parse(localStorage.getItem('_A_P_customer')).id || ''
...(JSON.parse(localStorage.getItem('_A_P_customer')).id ? { EQ_agent: JSON.parse(localStorage.getItem('_A_P_customer')).id } : {})
},

二、各组件接口方法

1、侧边抽屉

<template>
	<Drawer4 @register="register4" />
</template>

import Drawer4 from './Drawer4.vue';
  
export default defineComponent({
    components: {
      Drawer4,
    },
    setup() {
      const [register4, { openDrawer: openDrawer4 }] = useDrawer();
      function send() {
        openDrawer4(true, {
          data: 'content',
          info: 'Info',
        });
      }
      return {
        send,
        register4,
      };
    },
  });

2、进度条

<div class="progress" style="width: 200px">
                        <Progress :percent="item.percent" status="active" />
                      </div>

3、分步步骤条

<Steps :current="item.current - 1" progress-dot size="small">
                    <Step :title="i.status" v-for="i in item.workflowlist" :key="i.id">
                      <template #description>
                        <div v-show="i.handler">{{ i.handler }}-{{ i.handleaction }}</div>
                        <p>{{ i.handletime }}</p>
                      </template>
                    </Step>

         <!-- <Step title="创建项目">
            <template #description>
                <div>Vben</div>
                <p>2016-12-12 12:32</p>
            </template>
        </Step>
        <Step title="部门初审">
            <template #description>
                <p>Chad</p>
            </template>
        </Step>
        <Step title="财务复核" /> 
        <Step title="完成" /> -->
</Steps>

http://www.kler.cn/news/319442.html

相关文章:

  • 【多线程】面试高频考点!JUC常见类的详细总结,建议收藏!
  • 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-24
  • 小孩真的需要手机上学吗?怎样远程了解他在学校用iPhone干什么?
  • 代码随想录 | Day24 | 二叉树:二叉树的公共祖先(有个自己的想法)二叉搜索树的公共祖先
  • Fyne ( go跨平台GUI )中文文档-小部件 (五)
  • VisualPromptGFSS
  • 【C++ Primer Plus习题】17.7
  • GEO数据库提取疾病样本和正常样本|GEO数据库区分疾病和正常样本|直接用|生物信息|生信
  • 使用宝塔部署项目在win上
  • MySQL数据库脚本转化成sqlite数据库脚本的修改点
  • 动态规划day38|322. 零钱兑换(背包满了吗?最小值怎么表示?)、279. 完全平方数、139. 单词拆分、多重背包要点、背包问题大总结
  • 網路本地連接沒有有效的IP配置:原因與解決方法
  • 匈牙利算法详解与实现
  • 【Tomcat】常见面试题整理 共34题
  • 跨站请求伪造(CSRF)漏洞详解
  • 【MySQL】知识总结——索引的类型分类和性质
  • 2023国赛C题 蔬菜类商品的自动定价与补货决策(上)
  • Spring Boot 中实现动态列导入讲解和案例示范
  • element plus上传文件 点击确认后文件上传到接口
  • Java项目实战II基于Java+Spring Boot+MySQL的车辆管理系统(开发文档+源码+数据库)
  • 【Java】将一个List拆分使用线程池多线程运行
  • linux进程间通信——消息队列、信号量、ipc设计原理
  • 梧桐数据库(WuTongDB):向量化查询优化器的一些实现细节
  • 傅里叶变换及其应用笔记
  • 使用dom-to-image截图html区域为一张图
  • Redis --- redis事务和分布式事务锁
  • 全栈杂谈第三期 我们用的网络协议是什么
  • 前端css样式覆盖
  • 我的AI工具箱Tauri版-MicrosoftTTS文本转语音
  • 24.9.23学习笔记