首页 > 其他分享 >vue记录点

vue记录点

时间:2022-12-16 14:48:07浏览次数:60  
标签:vue const 记录 setup value props 组件 ref

1.vue2路由监听

watch: {
 $route: function (to, from) {
     //事件处理
  }
}

 

2.vue3路由监听

watch(
   () => Router.currentRoute.value.path,
   () => {
      // 处理事件
   }
);

 

3.setup

setup 不是生命周期钩子函数!

它只是基于 beforeCreate 运行,但函数内部无法通过 this 获取组件实例

而且 setup 有着生命周期钩子不具备的参数:props 和 context

setup(props, context) {
    // 组件 props
    console.log(props);
    const { attrs, slots, emit } = context;
    // Attribute (非响应式对象)
    console.log(attrs);
    // 组件插槽 (非响应式对象)
    console.log(slots);
    // 触发事件 (方法)
    console.log(emit);
}

这里的 props 就是组件内部定义的 props,是由父组件传入的参数

假如父组件传入了一个属性名为 title 的 props,在 setup 中可以通过 props.title 直接取到

而且这个 props 是响应式的,当传入新的 prop 时,props 会被更新

但正是因为 props 是响应式的,所以不能直接对 props 使用 ES6 解构,因为它会消除 prop 的响应性

Vue 3 提供了一个 toRefs 全局方法来解决这个问题:

import { toRefs } from 'vue';

setup (props) {
    // 通过 toRefs 包装后的 props 可以在 ES6 解构之后依然具有响应性
    const { title } = toRefs(props);
    console.log(title);
}

 

4. 在 setup 中注册生命周期钩子

如果是在 setup 内部注册生命周期钩子,则需要从 Vue 引入带有 on 前缀的生命周期工具函数

import { toRefs, onMounted } from 'vue';

setup (props) {
    // 使用 `toRefs` 创建对prop的 `title` property 的响应式引用
    const { title } = toRefs(props);
    // 注册生命周期钩子
    onMounted(() => {
        console.log('onMounted', title);
    });
}

上面的 onMounted 会接收一个函数作为参数,在组件中对应的生命周期钩子 (mounted) 触发时,会执行这个被传入的函数

除了 onMounted 以外,其他 created 之后的生命周期也有对应的注册函数,如 onUpdated、onBeforeUnmount 等

但 setup 中并没有 beforeCreate 和 created 这两个生命周期的注册函数

因为 setup 本身是基于 beforeCreate 运行,会用到 beforeCreate 和 created 的场景都可以通过 setup 替代

也就是说,在 beforeCreate 和 created 中编写的任何代码都应该直接在 setup 函数中编写

5. setup 的返回值

如果 setup 显式的返回了一个对象,这个对象的所有内容都会暴露给组件的其余部分

setup() {
  return {
    name: 'wise wrong',
    foo: (text: string) => {
      console.log(`Hello ${text}`);
    },
  };
},
mounted() {
  // 直接使用 setup 的返回值
  this.foo(this.name);
}

上面的 setup 返回了一个 foo 函数,还有一个 name 字段,目前这个 name 还不是一个响应式变量

为此我们需要使用 ref 全局方法

import { ref } from 'vue';

setup (props) {
    return {
        name: ref('wise wrong');
    }
}

通过 ref 包装的变量会具有响应性,在组件中可以像正常的组件属性一样使用

但在 setup 内部,ref 包装后的变量需要通过 value 来修改变量的值

import { ref } from 'vue';

setup() {
  const name = ref('wise wrong');
  onMounted(() => {
    // 在 setup 内部通过 value 修改变量值
    name.value = "Let's study Vue 3";
  });
  return {
    name,
  };
},
methods: {
  test() {
    // 在组件中可以直接修改 ref 变量
    this.name = 'good job';
  },
},

除了返回一个对象以外,setup 还可以返回一个渲染函数

import { h, ref, reactive } from 'vue'

export default {
  setup() {
    const readersNumber = ref(0)
    const book = reactive({ title: 'Vue 3 Guide' })
    // 返回一个渲染函数以覆盖 template
    return () => h('div', [readersNumber.value, book.title])
  }
}

如果直接返回了渲染函数,组件中定义的 template 将会失效

在 Setup 中使用 Computed、Watch

setup 的本意是用来替代 mixin,因此除了 data、methods、生命周期钩子之外,还有许多组件选项需要解决

这里先介绍 computed 和 watch

 

1. Computed

在组件中 computed 用来管理包含响应式数据的复杂逻辑

computed: {
  booksMessage() {
    return this.books.length > 0 ? 'Yes' : 'No'
  }
}

计算属性可以在组件中直接使用,并会随着响应式数据的更新而更新

<template>
  <p>{{ booksMessage }}</p>
</template>

而在 setup 中,需要通过全局函数 computed 来包装

复制代码
import { ref, computed } from 'vue'

setup() {
  const books = ref([]);
  const booksMessage = computed(() => books.value.length > 0 ? 'Yes' : 'No');
  return {
    books,
    booksMessage,
  }
}
复制代码

 

 2. Watch

 watch 用来监听数据的变化

可以通过 watch 定义对应的处理函数,当数据发生变化时候会调用该函数

复制代码
data: () => ({
  question: '',
  answer: 'good luck :)'
}),
watch: {
  question(newQuestion, oldQuestion) {
    // 当 question 变化的时候会执行该函数
    if (newQuestion.indexOf('?') > -1) {
      console.log('answer: ', this.answer);
    }
  }
},
复制代码

在 setup 中,也需要使用全局函数 watch 来包装

复制代码
import { ref, watch } from 'vue'

setup() {
  const question = ref('');
  const answer = ref('good luck :)');

  watch(question, (newValue, oldValue) => {
    if (newValue.indexOf('?') > -1) {
      console.log('answer: ', this.answer.value);
    }
  });

  return {
    question,
    answer,
  }
}
复制代码

 

 

抽取公共逻辑

在了解了基本的 Composition API 之后,可以尝试将公共逻辑抽取出来单独维护

假设有以下两个逻辑点需要被抽取:

1. 在组件加载完成后,通过父组件传入的参数 query 请求数据列表 list,当 query 变化时需要重新请求并更新 list;

2. 根据关键字 keyword 从数据列表 list 中筛选数据,并使用 computed 记录结果。

 

这两段逻辑可以直接在 setup 中实现,但这样会使得 setup 看起来非常累赘

我们可以把这段逻辑拆成两个函数并单独维护

首先在项目目录 src 下创建一个新的文件夹 composables

然后创建 useList.js 文件,完成第一个逻辑:

复制代码
// src/composables/useList.js

import { ref, onMounted, watch } from 'vue';

// 发起接口请求
function fetchList() {
  // ...
}

export default function useList(query) {
  // 创建数据列表 list (data)
  const list = ref([]);
  // 创建查询并更新 list 的方法 (methods)
  const getList = async () => {
    list.value = await fetchList(query);
  };

  // 生命周期 mounted
  onMounted(getList);
  // 监听 query 的变化并更新 list
  watch(query, getList);

  return {
    list,
    getList,
  };
}
复制代码

然后创建 useFilter.js 文件,完成第二个逻辑:

复制代码
// src/composables/useFilter.js

import { ref, computed } from 'vue';

export default function useFilter(list) {
  // 创建搜索关键字 keyword (data)
  const keyword = ref('');
  // 创建筛选结果 filterRes (computed)
  const filterRes = computed(() => {
    return list.filter((value) => {
      return value.includes(keyword.value);
    });
  });

  return {
    keyword,
    filterRes,
  };
}
复制代码

然后在组件中引入,并在 setup 返回组件需要的字段

复制代码
import { defineComponent, toRefs } from 'vue';
import useList from '@/composables/useList';
import useFilter from '@/composables/useFilter';

export default defineComponent({
  props: ['query'],
  setup(props) {
    const { query } = toRefs(props);
    const { list, getList } = useList(query);
    const { keyword, filterRes } = useFilter(list);
    return {
      keyword, // 筛选关键字
      getList, // 查询并更新数据列表
      list: filterRes, // 不需要返回未经筛选的列表
    };
  },
});
复制代码

 

表单部分

校验相关

<el-form ref="ruleForm" :rules="myRules"></el-form>

// 整个表单校验
this.$refs.ruleForm.validate();
// 单个表单字段credentialsFiles校验
this.$refs.ruleForm.validateField("credentialsFiles");
// 移除校验结果
this.$refs.ruleForm.clearValidate();
// 移除校验结果并重置字段值
this.$refs.ruleForm.resetFields();
// 校验规则
myRules: {
  enterpriseId: [{ required: true, message: messageContant, trigger: "change" }],
  contractTimeData: {
    validator: (rule, value, cb) => {
      if (value == "" || value == null || (value.length && value.length == 0))
        cb(new Error($i18n.$ct("请输入内容", "Please input")));
      cb();
    },
    trigger: "blur",
  },
  description: this.isChecked
    ? []
    : [
        { required: true, message: messageContant, trigger: "change" },
        { pattern: /^.{5,200}$/, message: $i18n.$ct("内容长度5-200", "Content length 5-200"), trigger: "change" },
      ],
},

 

表格部分

根据某一属性合并行或列

// 在table加span-method属性
<el-table :data="tableData" :span-method="objectSpanMethod" >
    <el-table-column :type="要合并列标志" :label="测试" >
    <el-table-column :label="测试2" >
</el-table>

// data
spanArr: [],
pos: 0,

// methods
/**
 * 计算合并数组 在获取表格数据后调用
 * data 表格数据
 * prop 根据这个属性合并
 */
getSpanArr(data, prop) {
  // data就是我们从后台拿到的数据
  for (let i = 0; i < data.length; i += 1) {
    if (i === 0) {
      this.spanArr.push(1);
      this.pos = 0;
    } else {
      // 判断当前元素与上一个元素是否相同
      if (data[i][prop] === data[i - 1][prop]) {
        this.spanArr[this.pos] += 1;
        this.spanArr.push(0);
      } else {
        this.spanArr.push(1);
        this.pos = i;
      }
    }
  }
},
// 行合并
objectSpanMethod({ column, rowIndex }) {
  if (column.type === "merge") {
    const myRow = this.spanArr[rowIndex];
    const myCol = myRow > 0 ? 1 : 0;
    return {
      // [0,0] 表示这一行不显示, [2,1]表示行的合并数
      rowspan: myRow,
      colspan: myCol,
    };
  }
},

 

标签:vue,const,记录,setup,value,props,组件,ref
From: https://www.cnblogs.com/kewenxin/p/15161077.html

相关文章

  • 记录2022年微服务技术架构选型
    后端技术栈套用互联网上的一句话,在java领域里面躲不过去的alibaba,所以本次微服务架构选型还是基于SpringCloudAlibaba做为基础。在SpringCloud众多的实现方案中,Sprin......
  • 一次磁盘占用率 100% 的排查记录
    你好,我是悟空。最近遇到一个服务器的问题:磁盘满了,占用率100%~这个问题太常见了,于是先来排查一波是哪些文件占用了大量磁盘。一、排查磁盘占用率100%1.1查看磁盘使用的大致......
  • npm问题记录
    npmERR!codeETIMEOUT设置代理关闭:npmconfigsetproxyfalse清除缓存:npmcacheclean若报错则:npmcacheclean--force降级npm版本:[email protected]设置淘宝镜......
  • 零基础学 Vue + Element UI 第01步 —— 搭建开发环境、创建项目、修改默认模板、启动
    通过对《零基础学前端系列教程|和前端谈恋爱的第001–006天》的学习,我们已经基本掌握了HTML的核心标签,CSS的常见样式,对Javascript也略有接触。零基础学前端系列教程|......
  • vue3自定义无限滚动
    最初使用的vue3-infinite-scroll-better插件进行滚动加载,打包部署后插件滚动功能失效了也不报错很难查找问题出现在哪部分,只好自己写一个相对简单的功能监控窗体的滚动......
  • 几款拿来就能用的vue工具库,不来看看吗?
    一、博主介绍......
  • Windows下安装mysql-python(MySQLdb)问题记录
    今天太倒霉了,这篇文章马上就要写完了,结果火狐崩溃了,而且csdn居然没有自动保存,只有上午的有记录;想到这个安装的问题也折腾哥快一天了,还是再次打字把问题记录下吧,我就喜欢偏......
  • CMD使用记录
    #切换cmd编码为utf-8(临时切换,永久切换需要改注册表)chcp65001 #重命名renD:\s.inis.txt#计算机名setCT=%computername%#打印到文件echo%computername%>D:\TAO.txt......
  • Spring Boot + vue-element 开发个人博客项目实战教程(二十一、个人介绍、公告管理、标
    ⭐作者简介:码上言⭐代表教程:​​SpringBoot+vue-element开发个人博客项目实战教程​​⭐专栏内容:零基础学Java、个人博客系统文章目录​​一、个人介绍​​​​二、......
  • Vue笔记7--路由管理Vue-router
    Vue-router路由核心:改变URL,但是页面不进行整体刷新。路由理解为指向的意思,其中有很重要的一个关键就是路由表。路由表,是一个映射表,一个路由就是一组映射关系,key:valueke......