前端项目,个人笔记(五)【图片懒加载 + 路由配置 + 面包屑 + 路由行为修改】

目录

1、图片懒加载

步骤一:自定义全局指令

步骤二:代码中使用

​编辑步骤三:效果查看

步骤四:代码优化

2、封装组件案例-传对象

3、路由配置——tab标签

4、根据tab标签添加面包屑

4.1、实现

4.2、bug:需要手动刷新

4.3、解决方案一

4.4、方案优化:onBeforeRouteUpdate钩子函数

5、修改路由行为


1、图片懒加载

步骤一:自定义全局指令

重构main.js文件:

app.directive('img-lazy',{
    //el:指令绑定元素 img
    //binding:binding.value 指令=后面表达式的值 图片url
    mounted(el,binding){        
        //console.log(el,binding.value)
        const { stop } = useIntersectionObserver(
            el,
            ([{ isIntersecting }]) => {
                console.log(isIntersecting)
                if(isIntersecting){
                    el.src = binding.value;
                    stop();
                }
            }
        )
    }
})

代码解释:

  1.  app.directive('img-lazy', { ... }):在 Vue 应用中定义一个名为 v-img-lazy 的全局指令。
  2. mounted(el, binding) { ... }:这是指令的 mounted 钩子函数,它在被绑定的元素插入到父节点时调用。

    • el:指令所绑定的元素,在这里是一个 img 标签。
    • binding:一个对象,包含了很多属性,其中 binding.value 是指令等号后面的值,这里是图片的 URL。
  3. const { stop } = useIntersectionObserver(el, callback):使用@vueuse/core的

    API - useIntersectionObserver 函数来观察 el 元素是否进入视口。

    1. el:要观察的 DOM 元素。
    2. callback:一个回调函数,当元素与视口有交集时调用。
    3. stop:一个函数,用于停止观察。
  4. ([{ isIntersecting }]) => { ... }:这是 useIntersectionObserver 的回调函数。

    1. isIntersecting:一个布尔值,表示元素是否进入视口。
  5. if(isIntersecting) { ... }:如果 isIntersecting 为 true,说明图片进入了视口。

    • el.src = binding.value;:设置图片元素的 src 属性为指令的值(图片的 URL),从而开始加载图片。
    • stop();:停止观察,因为图片已经加载,不需要再观察其是否进入视口。

步骤二:代码中使用

<img v-img-lazy="item.picture" alt="">

步骤三:效果查看

步骤四:代码优化

把这些代码都写在main.js中,main.js中的内容,太过于杂乱了些,我们整理一下,在根目录下创建directives/index.js:

import { useIntersectionObserver } from '@vueuse/core'

export const lazyPlugin = {
  install (app) {
    // 懒加载指令逻辑
    app.directive('img-lazy', {
      mounted (el, binding) {
        // el: 指令绑定的那个元素 img
        // binding: binding.value  指令等于号后面绑定的表达式的值  图片url
        console.log(el, binding.value)
        const { stop } = useIntersectionObserver(
          el,
          ([{ isIntersecting }]) => {
            console.log(isIntersecting)
            if (isIntersecting) {
              // 进入视口区域
              el.src = binding.value
              stop()
            }
          },
        )
      }
    })
  }
}

main.js中:


2、封装组件案例-传对象

        向组件传值的另一个案例-传普通值,在本系列文章:前端项目,个人笔记(二)【Vue-cli - 引入阿里矢量库图标 + 吸顶交互 + setup语法糖】

       调用的地方:

很明显,我们是有一个GoodItem组件,并且我们直接把good的这个对象传过去了

GoodItem组件代码:

<script setup>
defineProps({
  good: {
    type: Object,
    default: () => { }
  }
})
</script>

<template>
  <RouterLink to="/" class="goods-item">
    <img v-img-lazy="good.picture" alt="" />
    <p class="name ellipsis">{{ good.name }}</p>
    <p class="desc ellipsis">{{ good.desc }}</p>
    <p class="price">&yen;{{ good.price }}</p>
  </RouterLink>
</template>


<style scoped lang="scss">
.goods-item {
  display: block;
  width: 220px;
  padding: 20px 30px;
  text-align: center;
  transition: all .5s;

  &:hover {
    transform: translate3d(0, -3px, 0);
    box-shadow: 0 3px 8px rgb(0 0 0 / 20%);
  }

  img {
    width: 160px;
    height: 160px;
  }

  p {
    padding-top: 10px;
  }

  .name {
    font-size: 16px;
  }

  .desc {
    color: #999;
    height: 29px;
  }

  .price {
    color: $priceColor;
    font-size: 20px;
  }
}
</style>

可以重点看一下,是如何接收父组件传来的对象的·~


3、路由配置——tab标签

路由配置:

效果:


4、根据tab标签添加面包屑

4.1、实现

效果:

这个值的获取,是根据url中的id查询到tab的name的,因此第一步,我们需要封装一个查询请求:

api/category.js:

import http from "@/utils/http";

/**
 * @description: 根据id获得一级分类对象信息
 * @param {*} id 分类id
 * @return {*}
 */
export function getTopCategoryAPI(id){
    return http.get('/category',{params:{id}});
}

使用:  Category/index.vue:

<script setup>
import {getTopCategoryAPI} from '@/api/category'
import {useRoute} from "vue-router";
import {onMounted, onUpdated, ref} from "vue";

const categoryData = ref({})
const route = useRoute()
const getCategory = async () => {
  // 如何在setup中获取路由参数 useRoute() -> route 等价于this.$route
  //console.log(route.params.id);
  const res = await getTopCategoryAPI(route.params.id)
  categoryData.value = res.result
}
onMounted(()=>getCategory())
</script>

<template>
  <div class="top-category">
    <div class="container m-top-20">
      <!-- 面包屑 -->
      <div class="bread-container">
        <el-breadcrumb separator=">">
          <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
          <el-breadcrumb-item>{{ categoryData.name }}</el-breadcrumb-item>
        </el-breadcrumb>
      </div>
    </div>
  </div>
</template>


<style scoped lang="scss">
.top-category {
  h3 {
    font-size: 28px;
    color: #666;
    font-weight: normal;
    text-align: center;
    line-height: 100px;
  }

  .sub-list {
    margin-top: 20px;
    background-color: #fff;

    ul {
      display: flex;
      padding: 0 32px;
      flex-wrap: wrap;

      li {
        width: 168px;
        height: 160px;


        a {
          text-align: center;
          display: block;
          font-size: 16px;

          img {
            width: 100px;
            height: 100px;
          }

          p {
            line-height: 40px;
          }

          &:hover {
            color: $xtxColor;
          }
        }
      }
    }
  }

  .ref-goods {
    background-color: #fff;
    margin-top: 20px;
    position: relative;

    .head {
      .xtx-more {
        position: absolute;
        top: 20px;
        right: 20px;
      }

      .tag {
        text-align: center;
        color: #999;
        font-size: 20px;
        position: relative;
        top: -20px;
      }
    }

    .body {
      display: flex;
      justify-content: space-around;
      padding: 0 40px 30px;
    }
  }

  .bread-container {
    padding: 25px 0;
  }
}
</style>

重点代码:

4.2、bug:需要手动刷新

bug原因:当你在同一个组件内点击时,他会复用之前的组件 ,所以就不会刷新了,需要手动刷新~

4.3、解决方案一

 在路由入口处处理:

<RouterView :key="$route.fullPath"/>

方案:将路由入口中的所有组件全部都会重新加载~ 而我们只需要对应的组件刷新即可,因此就有了方案优化:

4.4、方案优化:onBeforeRouteUpdate钩子函数

onBeforeRouteUpdate((to)=>{
  getCategory(to.params.id)
})

 


5、修改路由行为

        我们会发现当我们在首页时,右侧滚动条可能是在中间,当我们切到美食时,滚动条还是在中间,没有跳到最上面。处理:

scrollBehavior(){
  return{
    top:0
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/274775.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s详细教程

Kubernetes详细教程 1. Kubernetes介绍 1.1 应用部署方式演变 在部署应用程序的方式上&#xff0c;主要经历了三个时代&#xff1a; 传统部署&#xff1a;互联网早期&#xff0c;会直接将应用程序部署在物理机上 优点&#xff1a;简单&#xff0c;不需要其它技术的参与 缺点…

QT 驾校系统界面布局编写

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);this->resize(ui->label_img->width(),ui->label_img->height());//图片自适应窗口大小ui->label_img->setScaledContents(true);//图片置…

ES集群和分片以及脑裂

文章目录 概要一、概念二、节点角色三、master节点脑裂四、参考 概要 在工作中不可避免会用到ES&#xff0c;而用到ES就不得使用其集群模式了。 单节点的话不得不面临两个重大缺陷&#xff1a;单点故障&#xff08;高可用&#xff09;和海量数据存储搜索。 ES通过集群模式解决…

竞争优势:大型语言模型 (LLM) 如何重新定义业务策略

人工智能在内容创作中的突破 在当今快节奏的商业环境中&#xff0c;像 GPT-4 这样的大型语言模型 (LLM) 不再只是一种技术新颖性&#xff1b; 它们已成为重新定义跨行业业务战略的基石。 从增强客户服务到推动创新&#xff0c;法学硕士提供了企业不容忽视的竞争优势。 1. 加强…

LVGL:拓展部件——键盘 lv_keyboard

一、概述 此控件特点&#xff1a; 特殊Button矩阵&#xff1a;lv_keyboard 本质上是一个经过定制的按钮矩阵控件。每个按钮都可以独立触发事件或响应。预定义的键映射&#xff1a;lv_keyboard 自带了一套预设的按键布局和对应的字符映射表&#xff0c;开发者可以根据需要选择…

Spring MVC入门(4)

请求 获取Cookie/Session 获取Cookie 传统方式: RequestMapping("/m11")public String method11(HttpServletRequest request, HttpServletResponse response) {//获取所有Cookie信息Cookie[] cookies request.getCookies();//打印Cookie信息StringBuilder build…

WPF —— 控件模版和数据模版

1:控件模版简介: 自定义控件模版&#xff1a;自己添加的样式、标签&#xff0c;控件模版也是属于资源的一种&#xff0c; 每一个控件模版都有一唯一的 key&#xff0c;在控件上通过template属性进行绑定 什么场景下使用自定义控件模版&#xff0c;当项目里面多个地方…

K8s的Pod出现Init:ImagePullBackOff问题的解决,(以calico网络插件为例)

问题描述&#xff1a; 对于这类问题的解决思路应该都差不多&#xff0c;本文以calico插件安装为例&#xff0c;发现有个Pod的镜像没有pull成功 第一步&#xff1a;查看这个pod的描述信息 kubectl describe pod calico-node-t9rql -n kube-system从上图发现是docker拉取"…

基于Lealfet.js展示Turf.js生成的平滑曲线实践

目录 前言 一、问题的由来 1、创建网页框架 2、创建map对象 3、构建点位&#xff0c;生成路线 二、Turf.js平滑曲线改造 1、官网方法介绍 2、0.4弯曲度曲线 3、0.85弯曲度曲线 4、0.1度弯曲曲线 5、综合对比 总结 前言 在很多的关于路线的gis应用中&#xff0c;我们…

详细教---用Django封装写好的模型

本次我们要用自己写好的热销词条爬虫代码来演示如何用Django把我们写好的模型封装。 第一步&#xff1a;代码准备 热搜词条搜集代码&#xff1a; import requests from lxml import etreeurl "https://tophub.today/n/KqndgxeLl9" headers{User-Agent: Mozilla/5.…

如何本地部署1Panel面板

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

NLP---Bert分词

目录&#xff1a; Q&#xff1a;bert分词步骤1&#xff1a;构建N * N 的相关性矩阵&#xff0c;计算相邻两个字的相关性&#xff0c;低的话&#xff08;<阈值&#xff09;就切割。2&#xff1a;将A词进行mask计算出A的embedding&#xff0c;然后将AB两个词一起mask&#xff…

除了大众点评,中国未来还会产生多少家这样的人工智能公司? - 学习Yelp公司的软件工程-评价和推荐系统

原文作者&#xff1a;Jason Sleight&#xff0c;ML&#xff08;Machine Learning&#xff09;平台集团技术负责人 翻译&#xff1a;数字化营销工兵 了解数据是Yelp成功的重要组成部分。为了将我们的消费者与当地优秀的企业联系起来&#xff0c;我们每天为各种任务提供数百万条建…

【0274】从shared init file或local init file加载relation cache(2 - 1)

上一篇&#xff1a; 【0273】深入分析 relcache&#xff08;relation descriptor cache&#xff09;初始化第一阶段&#xff08;1&#xff09; 【0264】深入分析relcache&#xff08;relation descriptor cache&#xff09;缓存初始化第2阶段&#xff08;2&#xff09; 1. 前…

JSONP 实现跨域请求案例

后端使用 express 搭建&#xff0c;案例代码如下&#xff1a; const express require(express)const app express() const PORT 3000app.get(/data, (req, res) > {const jsonData {name: Alan,age: 666,city: GD}const callback req.query.callback // 获取前端中的回…

Python分析无人驾驶汽车在桂林市文旅行业推广的问卷

【项目背景】 通过市场调研、文本分析、访谈和问卷调查等方法&#xff0c;探讨&#xff1a; 网民对无人驾驶汽车出行服务的态度。无人驾驶安全员的行业背景。不同人群在旅游时的交通选择偏好。游客及当地居民对桂林市文旅路线的交通满意度。乘客对无人驾驶汽车的满意度。桂林…

00_coolprop_in_matlab在Matlab中使用CoolProp

在Matlab中使用CoolProp 简介 CoolProp是一个开源的热力学性质库&#xff0c;可以计算多种流体的热力学性质。CoolProp支持多种编程语言&#xff0c;包括Python、C、Matlab等。本文将介绍如何在Matlab中使用CoolProp。 CoolProp官网 本文所使用的Matlab版本为R2021a。 在Ma…

飞天使-k8s知识点26-kubernetes温故知新1-pod

文章目录 创建一个podpod的启动命令和参数更改pod 镜像拉取策略 pod 的三种探针pod 探针的实现方式prestop 和 prestart 创建一个pod apiVersion: v1 # 必选&#xff0c;API 的版本号 kind: Pod # 必选&#xff0c;类型 Pod metadata: # 必选&#xff0c;元数据name: nginx # …

在idea中配置tomcat服务器,部署一个项目(下载教程加链接)

第一步&#xff1a;把Tomcat下载好 ww​​​​​​​Apache Tomcat - Welcome! 链接如上&#xff1a;进去后在左边找到Tomcat8点击进去后 找到图下内容 第二步&#xff1a; 打开这个文件点击bin进去 会出现一个黑色框框&#xff0c;也就是服务器 完成后就可以在浏览器输入…

【爬虫】实战-爬取Boss直聘信息数据

专栏文章索引&#xff1a;爬虫 所用工具&#xff1a; 自动化工具&#xff1a;DrissionPage 目录 一、找到目标数据(2个确定)​ 1.确定目标网页 2.确定目标网址 二、编写代码​ 三、查看数据​ 五、总结 一、找到目标数据(2个确定) 1.确定目标网页 打开目标网站 网站&am…
最新文章