vue3项目(三)---Home

该文详细介绍了如何使用Vue.js构建Home页面,包括整体结构的搭建,通过组件化实现分类、轮播图等功能,利用Pinia管理状态,以及实现图片的懒加载优化。同时,文章强调了组件复用和封装的重要性,如HomePanel和GoodsItem组件,以提高代码效率。
摘要由CSDN通过智能技术生成

1. Home-整体结构搭建和分类实现

结构的搭建

步骤:

1) 按照结构新增五个组件,准备最简单的模版,分别在Home模块的入口组件中引入

 在组件里准备简单的模块,如下

//src/views/Home/components/HomeCategory.vue

<script setup>
</script>

<template>
  <div> HomeCategory </div>
</template>

2)Home模块入口组件中引入并渲染

//src/views/Home/index.vue
<script setup>
import HomeCategory from './components/HomeCategory.vue'
import HomeBanner from './components/HomeBanner.vue'
import HomeNew from './components/HomeNew.vue'
import HomeHot from './components/HomeHot.vue'
import HomeProduct from './components/HomeProduct.vue'
</script>

<template>
  <div class="container">
    <HomeCategory />
    <HomeBanner />
  </div>
  <HomeNew />
  <HomeHot />
  <HomeProduct />
</template>

分类的实现

步骤:

1)准备静态页面

2)使用pinia中的数据渲染(因为数据和吸顶导航的数据一样,所以直接拿取就可以)

//src/views/Home/components/HomeCategory.vue

<script setup>
import {useCategoryStore} from '@/stores/category'

const categoryStore=useCategoryStore()
</script>

<template>
  <div class="home-category">
    <ul class="menu">
      <li v-for="item in categoryStore.categoryList" :key="item.id">
        <RouterLink to="/">{{ item.name }}</RouterLink>
        <RouterLink v-for="i in item.children.slice(0,2)" :key="i" to="/">{{i.name}}</RouterLink>
        <!-- 弹层layer位置 -->
        <div class="layer">
          <h4>分类推荐 <small>根据您的购买或浏览记录推荐</small></h4>
          <ul>
            <li v-for="i in item.goods" :key="i.id">
              <RouterLink to="/">
                <img :src="i.picture" />
                <div class="info">
                  <p class="name ellipsis-2">
                    {{ i.name }}
                  </p>
                  <p class="desc ellipsis">{{i.desc}}</p>
                  <p class="price"><i>¥</i>{{i.price}}</p>
                </div>
              </RouterLink>
            </li>
          </ul>
        </div>
      </li>
    </ul>
  </div>
</template>

2. Home-banner轮播图功能实现

步骤:

1)搭建静态页面

2)使用elementPlus搭建相关组件

 

3)获取数据

//src/apis/home.js

import httpInstance from "@/utils/http";

// 获取banner
export function getBannerAPI(){
    return httpInstance({
        url:'/home/banner'
    })
}

 4)渲染数据

//src/views/Home/components/HomeBanner.vue

<script setup>
import {getBannerAPI} from '@/apis/home'
import {onMounted, ref} from 'vue'

const bannerList=ref([])

const getBanner=async()=>{
    const res=await getBannerAPI()
    console.log(res);
    bannerList.value=res.result
}
onMounted(()=>getBanner())
</script>

 3. Home-面板组件封装

 

由于,新鲜好物和人气推荐模块,在 结构上非常相似 ,只是内容不同。
通过组件封装可以 实现复用结构 的效果。
核心思路:把可复用的结构只写一次,把 可能发生变化的部分抽象成组件参数(props / 插槽)。
步骤:
1)创建三个组件,HomeHot,HomeNew,HomePanel,并给HomeHot,HomeNew准备静态模版
2)HomePanel里书写抽象可变的部分
- 主标题和副标题是 纯文本 ,可以抽象成 prop 传入
- 主体内容是 复杂的模版 ,抽象成 插槽 传入

 

4. Home-新鲜好物和人气推荐实现

步骤:
1)准备静态页面
2)先实现标题区域
//src/views/Home/components/HomeNew.vue

<script setup>
// 导入封装的组件
import HomePanel from "./HomePanel.vue";
</script>

<template>
//使用封装组件修改静态组件
<HomePanel title="新鲜好物" sub-title="新鲜出炉 品质靠谱">
    <ul class="goods-list">
      <li v-for="item in newList" :key="item.id">
        <RouterLink to="/">
          <img :src="item.picture" alt="" />
          <p class="name">{{ item.name }}</p>
          <p class="price">&yen;{{ item.price }}</p>
        </RouterLink>
      </li>
    </ul>
</HomePanel>
  <div></div>
  <!-- 下面是插槽主体内容模版
  <ul class="goods-list">
    <li v-for="item in newList" :key="item.id">
      <RouterLink to="/">
        <img :src="item.picture" alt="" />
        <p class="name">{{ item.name }}</p>
        <p class="price">&yen;{{ item.price }}</p>
      </RouterLink>
    </li>
  </ul>
  -->
</template>

3)实现主体内容区域

调用接口获取数据,渲染数据

//src/apis/home.js

// 获取新鲜好物
export const findNewAPI=()=>{
    return httpInstance({
        url:'/home/new'
    })
}
//src/views/Home/components/HomeNew.vue
<script setup>
// 导入封装的组件
import HomePanel from "./HomePanel.vue";
import { findNewAPI } from "@/apis/home";
import { onMounted, ref } from "vue";

// 获取数据
const newList = ref([]);

const getNewList = async () => {
  const res = await findNewAPI();
  newList.value = res.result;
};

onMounted(() => getNewList());
</script>

 人气推荐的实现和新鲜好物一样。

5.Home-图片懒加载指令实现

场景:电商网站的首页通常会很长,用户不一定能访问到 页面靠下面的图片 ,这类图片通过懒加载优化手段可以做到 只有进入视口区域才发送图片请求。
核心原理:图片进入视口才发送资源请求。
步骤:
1) 可以通过插件的方法把 懒加载指令 封装为插件。
懒加载指令可以使用vueUse完成。
当图片进入视口区域,发送图片资源请求
//src/directive/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);
                // 利用vueUse判断图片是否进入视口区域
                // isIntersecting是一个布尔值
               useIntersectionObserver(el, ([{ isIntersecting }]) => {
                    console.log(isIntersecting);
                    if (isIntersecting) {
                        // 进入了视口区域,发送图片资源请求
                        el.src = binding.value   
                    }
                })
            }
        })
    }
}

2)在main.js中进行插件的注册

//src/main.js

// 引入懒加载插件
import {lazyPlugin} from '@/directives'

// 注册懒加载插件
app.use(lazyPlugin)

3)解决重复监听问题

useIntersectionObserver会一直监听是否进入视口区域,每进入和离开一次,都会监听。
所以在监听的图片第一次完成加载之后就停止监听。

 

7.Home-Product产品列表实现

 步骤:

1)准备静态页面

 所以在Product页面上也要使用HomePanel组件。

所以记得引入。

2)封装接口

//src/apis/home.js

// 获取所有商品模块
export const getGoodsAPI=()=>{
    return httpInstance({
        url: '/home/goods'
      })
}

3)获取数据,渲染数据

//src/views/Home/components/HomeProduct.vue
<script setup>
// 引入组件
import HomePanel from './HomePanel.vue'

import {getGoodsAPI} from '@/apis/home'
import { ref,onMounted } from 'vue'

const goodsProduct = ref([])
const getGoods = async () => {
  const { result } = await getGoodsAPI()
  goodsProduct.value = result
}
onMounted( ()=> getGoods() )
</script>

4)图片懒加载

8.Home-GoodsItem组件封装

 

注意产品列表的主体区域里,有很多这个组成,我们可以封装为一个组件,方便复用。

步骤:

1)创建GoodsItem组件

//src/views/Home/components/GoodsItem.vue
<script setup>
defineProps({
    goods:{
        type:Object,
        default:()=>{}
    }
})
</script>

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

2)在HomeProduct组件中使用

//src/views/Home/components/HomeProduct.vue
<script setup>
import GoodsItem from './GoodsItem.vue'
</script>

总结:

1.纯展示类组件通用封装思路总结:

home页中的HomePanel和GoodsItem这两个组件就是纯展示类的组件。

 1)搭建纯静态的部分,不管可变的部分
 2)抽象可变的部分为组件参数
 非复杂的模版抽象成props,复杂的结构模版抽象为插槽
2.home页面使用了图片懒加载。
把懒加载封装为了一个插件,可以全局使用。
3.使用elementPlus制作轮播图。
Vue3中使用vue-awesome-swiper的步骤如下: 1. 首先,在项目的根目录下通过npm或yarn安装vue-awesome-swiper和swiper库: ``` npm install swiper vue-awesome-swiper --save ``` 2. 在main.js中引入插件,并注册到Vue应用中: ```javascript import { createApp } from 'vue'; import App from './App.vue'; import VueAwesomeSwiper from 'vue-awesome-swiper'; import 'swiper/css/swiper.css'; const app = createApp(App); app.use(VueAwesomeSwiper); app.mount('#app'); ``` 3. 在需要使用轮播图的组件中,使用Swiper组件进行轮播图的展示。例如,在Home.vue组件中: ```html <template> <div> <swiper :options="swiperOptions"> <swiper-slide v-for="item in swiperItems" :key="item.id"> <img :src="item.imageUrl" alt="slide-image" /> </swiper-slide> <div class="swiper-pagination" slot="pagination"></div> <div class="swiper-button-next" slot="button-next"></div> <div class="swiper-button-prev" slot="button-prev"></div> </swiper> </div> </template> <script> export default { data() { return { swiperOptions: { // Swiper的配置选项 // 可根据需要进行配置,例如autoplay、loop等 }, swiperItems: \[ // 轮播图的数据 // 可根据需要进行配置,例如图片地址、标题等 \] }; } }; </script> <style> /* 样式可以根据需要进行自定义 */ </style> ``` 这样就可以在Vue3中使用vue-awesome-swiper进行轮播图的展示了。请注意,确保安装的是支持Vue3的swiper版本,并按照上述步骤正确引入和使用插件。引用\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [vue3 使用 swiper轮播库](https://blog.csdn.net/qq_36131788/article/details/121083045)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [vue3 swiper/vue-awesome-swiper使用](https://blog.csdn.net/weixin_52164116/article/details/123373656)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值