Skip to content

Latest commit

 

History

History
152 lines (110 loc) · 7.14 KB

学习.md

File metadata and controls

152 lines (110 loc) · 7.14 KB

vue3项目学习

懒加载-自定义全局指令

一开始只加载前面部分,随着下滑,进入视口区域才加载后面的内容。

定义全局自定义指令

自定义一个到达视口区域后自动加载的指令img-lazy,然后在<img/>中使用v-img-lazy属性实现图片的懒加载 官方文档

main.js

// 定义全局自定义指令
app.directive("img-lazy",{
    mounted(el,binding){
        // el: 指令绑定的那个元素 img
        // binding: binging.value 绑定到表达式的值=>这里是图片url
        console.log(el,binding.value);
    }
})

判断是否进入视口区域

使用vueUse中提供功能。useIntersectionObserver函数能够判断。

// 定义全局自定义指令
app.directive("img-lazy", {
    mounted(el, binding) {
        // el: 指令绑定的那个元素 img
        // binding: binging.value 绑定到表达式的值=>这里是图片url
        // console.log(el,binding.value);

        // stop用于停止继续监听
        const {stop} = useIntersectionObserver(
            el,
            ([{ isIntersecting }]) => {
               // isIntersecting :bool, 是否进入视口区域
               if(isIntersecting){
                // 将Url赋值给src后就会自动的去请求该url, 注意需要将原来的src删除
                el.src = binding.value
               }
            },
        )
    }
})

优化懒加载

使用插件的方式应用懒加载

上面是在main.js入口函数中实现的懒加载,我们应该将实现其移动到单独的地方,然后只在这里注册。 可以使用插件的形式实现。插件的实现和扩展方法有些类似,在插件的定义中可以使用install()获取到使用该插件的app对象,还可以传递参数。

将插件写在directives文件夹中,其基本语法是:

const lazyImgPlugin = {
  install(app, options) {
    // 配置此应用
  }
}

我们将之前写在main.js中的内容剪切到这里面,然后导入判断是否进入视口的函数即可。写完之后将该插件导出,然后在main.js中导入该插件,使用app.use()注册该插件。

处理重复鉴定视口的问题

useIntersectionObserver默认是一直监听是否进入视口的,即加载图片之后还是会在反复进入视口时反复执行对应的回调。 可以从useIntersectionObserver中解构出stop函数,该函数用于结束监听,在第一次加载图片之后就是要该函数结束掉监听。

const {stop} = useIntersectionObserver(
    el,
    ([{ isIntersecting }]) => {
        // isIntersecting :bool, 是否进入视口区域
        if (isIntersecting) {
            // 将Url赋值给src后就会自动的去请求该url, 注意需要将原来的src删除
            el.src = binding.value
            stop()
        }
    },
)

路由

路由传参

路由传参可以使用restfull的params,也可以是查询字符串的query。传递之后使用vue-router中的useRoute来获取当前路由的参数。

const route = useRoute()
const id = route.params.id

路由激活显示 active-class

需要显示当前那个路由是被激活的,方便用户知道当前是在哪个页面。Router-Link组件支持该功能,其active-class对应css样式,表示该路由处于被激活状态时的样式。

路由缓存

路由导航存在缓存,只在路由参数变化时其并不会重新导航加载组件,而是进行组件复用,这就意味着生命周期函数也不会被调用。 解决方法:

  1. 让组件实例不服用,每次强制销毁,在RouterView组件绑定独一无二的key,<RouterView :key="$route.fullPath"/> 。缺点是当前路由下的所有资源都会刷新,做不到只刷新部分.
  2. 使用监听(精细化控制),有专门监听路由变化的beforeRouteUpdate导航钩子; 或者是watchEffect(route,()=>{}),监听响应式数据的变化并调用回调函数。项目里面使用的是beforeRouteUpdate

使用逻辑函数拆分业务

业务逻辑变多了以后如果放在一个文件里面就很乱,所以将每一个业务逻辑单独封装,使用是单独调用即可,增强了可读性。直接搬代码即可,学习到的点是:使用的hooks(各种AOP钩子)其实类似于注册该钩子,注册之后就会在其生命周期发生时出发,相当于注册到vue的整个对象中去了。

el-form的数据校验

el-form分为三个部分。el-formel-itemel-input

  1. 响应式表单对象和rules对象分别绑定到el-form:model:rules上。
  2. el-itemprop上绑定校验规则中的校验名。
  3. 将数据使用v-model进行双向绑定到el-input

自定义用户校验

自定义校验规则将requiredmin之类的规则改为validator并传入一个函数,必须有这三个参数,且不论是否通过校验都需要执行callback

validator: (rule, value, callback) => {
    if (value == false) {
        callback(new Error('请同意协议'))
    } else {
        callback()
    }
}

script中实现路由跳转

使用vue-router中的useRouter方法回去到router实例,有pushreplace两种路由跳转方式,push是将当前的路由信息记录到浏览器的历史记录栈中,此时用户可以使用浏览器的后退功能回到跳转前的位置;replace是将当前的路由信息直接替换为要跳转的路由地址,不会像浏览器历史记录栈中添加新的路由信息,这种方法一般用于不希望用户跳转回来的情况,如登录成功后的跳转。这两种方法都是不会刷新页面请求的。

使用pinia管理用户数据

将所有涉及到需要存储数据的操作都封装到pinia的action中,使用的组件只需要调用其action后,再使用数据state即可。
将登录接口的调用放在pinia中,用其action获取数据后放入state,将state和action导出后和全局使用。
将用户的Token持久化到localStorage

axios的异步请求和拦截器响应流程

axios的请求都是异步请求,会返回一个Promise对象,所以我们一般使用asyncawait进行异步编程。在拦截器使用时会将响应拦截下来做预处理,如果这个响应是成功了,则是fulfilled状态,会继续回到原来的执行流程继续执行.then()中的内容;而如果响应是失败,则是reject状态,会进入到.catch()中的内容。而我们如果使用await来等待请求,则会在fulfilled时继续原来的流程执行,而在reject是将错误信息向上一步一步抛出直到有catch来捕获后进行处理,不会继续原流程执行。在vue3中有个onErrorCaptured钩子可以全局捕获组件的错误。如果不显式进行捕获处理,系统也不会崩溃,应该是vue3中有相应处理,比如将信息请求错误信息打印到控制台。 大多数现代的浏览器会在未捕获的 Promise 拒绝(uncaught promise rejection)时自动将错误信息打印到控制台。这个与vue3框架处理的信息不一样。