Vue项目实战

发布于:2025-03-10 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、项目介绍

  • 优选商城pc端
  • 旅途移动端web项目(H5)
  • 后台管理系统 ts + vue3

常见前端项目的UI库

后台管理系统:element UI 、Ant-Design

小程序:vant

移动端web:vant

门户网站:局部引入UI库

海外:Material UI 规范 react\mui,vue\vuetify

二、项目实战

1.创建项目

方式一:Vue CLI

  • 基于webpack工具
  • 命令: vue create

方式二: create-vue

  • 基于vite工具
  • 命令:npm init vue@latest

项目配置

  • 配置项目的icon
  • 配置项目的标题
  • 配置jsconfig.json

2.项目目录结构划分

src
 |-assets -- 存放静态资源,比如css/images/font等
 |-components -- 存放公共组件
 |-composables -- 组合式函数
 |-mock -- 模拟测试数据
 |-router -- 路由
 |-services -- 接口
 |-stores -- 状态管理,比如pinia、vuex
 |-utils -- 工具包
 |-views -- 页面
 |-App.vue
 |-main.js
 |-gitignore
 |-index.html
 |-jsconfig.json
 |-package-lock.json
 |-package.json
 |-README.md
 |-vite.config.js

3.CSS样式重置

对默认CSS样式进行重置:

  • normalize.css
  • reset.css
npm i normalize.css --save

main.js

import 'normalize.css'

assets/css/reset.css

/* 自定义的css */
a {
    text-decoration: none;
    color: #333;
}

assets/css/index.css

/* 作为css文件的入口统一导入 */
@import './reset.css';
@import './common.css';    

4.路由配置

router/index.js

import {createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      redirect: '/home',
    },
    {
      path: '/home',
      name: 'home',
      component: () => import('@/views/home/index.vue'),
    },
  ],
})

export default router

main.js

import { createApp } from 'vue'
import pinia from './stores'

import App from './App.vue'
import router from './router'

import 'normalize.css'

import '@/assets/css/index.css'

const app = createApp(App)

app.use(router)

app.mount('#app')

5.状态管理配置

stores/index.js

import {createPinia} from "pinia";

const pinia = createPinia()

export default pinia

stores/modules/counter.js

import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  // 也可以这样定义
  // state: () => ({ count: 0 })
  actions: {
    increment() {
      this.count++
    },
  },
})

三、开发中会遇到的问题

1.修改第三方UI组件库的样式

1.用插槽,插入自己的元素那么在自己的作用域中直接修改这个元素

2.全局定义一个变量,覆盖它默认变量的值 *缺点: 全局修改

3.局部定义一个变量,覆盖它默认变量的值 !优点: 局部修改

4.直接查找对应的子组件选择器,进行修改:deep(子组件中元素的选择器)进行修改直接修改CSS

2.vite中动态加载图片

const getAssetUrl = (image) => {
    // 参数一: 相对路径
    // 参数二: 当前路径的url
    const url = `../assets/images/${image}`;
    return new URL(url, import.meta.url).href;
};

3.tabs选项与滚动内容匹配算法

该算法同样适用于歌词匹配

const titlePositionMap = {
    '设施': 300,
    '房东': 500,
    '评论': 700,
    '须知': 1000,
}
// 当前滚动高度
let newValue = 424;
const offsetTopArr = Object.values(titlePositionMap);
let currentIndex = offsetTopArr.length - 1;
// 遍历tabs每个选项的高度,找到当前高度所在的选项索引值
for (let i = 0; i < offsetTopArr.length; i++) {
    if (newValue + 44 < offsetTopArr[i]) {
        currentIndex = i - 1;
        break;
    }
}
tabRef.value.currentIndex = currentIndex < 0 ? 0 : currentIndex;

4.集成百度地图SDK

1.注册百度账号,登录百度地图开发平台

2.打开控制台>应用管理>我的应用,点击创建应用

3.输入应用名称,选择浏览器端,点击确认

4.复制访问应用的ak用于后续的接口调用

index.html

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <title>Vite App</title>
    <script type="text/javascript" src="https://api.map.baidu.com/getscript?v=3.0&&type=webgl&ak=[输入复制的ak]"></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

map.vue

<template>
	<div class="baidu" ref="mapRef"></div>
</template>
<script setup>
const mapRef = ref()
const position = {
    longitude: 112.333,
    latitude: 52.343
}

onMounted(() => {
  const map = new BMapGL.Map(mapRef.value); // 创建地图实例 
  const point = new BMapGL.Point(position.longitude, position.latitude); // 创建点坐标 
  map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
  const marker = new BMapGL.Marker(point);  
  map.addOverlay(marker)
})
</script>

5.组合式函数

在项目中一些公共人物的逻辑可以封装成一个组合式函数进行复用,比如监听页面滚动函数:

useScroll.js

import { throttle } from 'underscore'

export default function useScroll (elRef) {
  let el = window;

  const reachBottom = ref(false);
  const clientHeight = ref(0)
  const scrollTop = ref(0)
  const scrollHeight = ref(0)

  // 节流操作
  const loadMoreHandler = throttle(() => {
    if (el === window) {
      clientHeight.value = document.documentElement.clientHeight;
      scrollTop.value = document.documentElement.scrollTop;
      scrollHeight.value = document.documentElement.scrollHeight;
    } else {
      clientHeight.value = el.clientHeight;
      scrollTop.value = el.scrollTop;
      scrollHeight.value = el.scrollHeight;
    }
    if (scrollHeight.value - scrollTop.value <= clientHeight.value) {
      reachBottom.value = true
    }
  }, 100)

  onMounted(() => {
    if (elRef) {
      el = elRef.value;
    }
    el.addEventListener("scroll", loadMoreHandler)
  })

  onActivated(() => {
    el.addEventListener("scroll", loadMoreHandler)
  })

  onUnmounted(() => {
    el.removeEventListener("scroll", loadMoreHandler)
  })

  onDeactivated(() => {
    el.removeEventListener("scroll", loadMoreHandler)
  })

  return {
    reachBottom,
    clientHeight,
    scrollTop,
    scrollHeight,
  }
}

6.vue中的函数模板引用

在vue中需要直接访问底层 DOM 元素时,不仅仅可以使用ref字符串作为名字,还可以使用函数

<script setup>
    const bindRef = (el) => {
        console.log(el);
        el.addEventListener('click', () => {})
    }
</script>
<template>
<input :ref="bindRef" />
</template>

注意我们这里需要使用动态的 :ref 绑定才能够传入一个函数。当绑定的元素被卸载时,函数也会被调用一次,此时的 el 参数会是 null


网站公告

今日签到

点亮在社区的每一天
去签到