Vue3 京东到家项目实战第一篇(首页及登录功能开发) 进阶式掌握vue3完整知识体系

news2024/11/18 1:30:16

目录

项目首页开发

项目准备✌️

样式开发👍

防抖👊

底部横条✌️

登陆注册功能开发

样式编写 👐

路由守卫实现基础登录校验功能☝️

使用 axios 发送登录 Mock 请求👈

请求函数的封装🙌

通过代码拆分增加逻辑可维护性👏


本项目的源代码在文章末尾哦

项目首页开发💤

我们先看一下在本文中我们这个项目要做的页面,分别是首页,登录和注册页面:

项目首页:

登录页面:

注册页面和登录页面相似,这里就不展示了。在本文中我们会完成京东到家项目首页和登录注册页面的样式开发,其中会用到 element-plus 组件库,登录注册会使用 axios 发送 Mock 请求来实现,贴近真实项目开发。

 

项目准备

我们通过脚手架已经构建好了项目,如果还不会怎么搭建vue3项目的同学,可以看看我的这篇博客,对vue3有个大概的了解:

Vue3全家桶入门 (通过vue-cli脚手架搭建todolist项目环境,深入vue3.0核心知识)https://blog.csdn.net/qq_49900295/article/details/124726599?spm=1001.2014.3001.5501首先,在 main.js 中引入项目需要的依赖:

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import 'normalize.css'
import './style/base.scss'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)
app.use(store)
app.use(router)
app.use(ElementPlus)
app.mount('#app')

这里 normalize.css 和 element-plus 需要我们先安装:

npm install normalize.css --save
npm install element-plus --save

normalize.css 是css的初始化文件,它在默认的HTML元素样式上提供了跨浏览器的高度一致性,总之按装它就完事了,element-plus在我们的项目中可以用到一些弹窗,引入它会非常方便。

除了 normalize.css 外,在 main.js 里我们还引入了 base.scss,在这里我们设置了 html 与 body 的字号,方便在样式中使用rem来实现响应式的字体:

html {
    font-size: 100px;
}
body {
    font-size: .12rem;
}

下面是项目的 style 目录:

在 viriables.scss 文件中我们主要来定义一些颜色变量:

$content-fontcolor: #333;
$content-bgcolor: #F1F1F1;

因为在各个组件中使用这两个颜色特别多,所以我们可以把它单独拿出来,通过变量的形式我们就可以统一更改颜色,这样就非常方便。

下面是 App.vue 中的代码,我们把里面的内容都删掉,我们并不需要 router-link,我们只需要 router-view 渲染子路由就行:

<template>
  <router-view />
</template>

<script>

export default ({
  name: 'App'
})
</script>

样式开发

这是首页的目录结构:

这里HomeView相当于首页的根组件,也就是相当于一个容器里面放着 FooTer,NearBy,StaticView三个子组件,从下图可以看出这三个子组件负责的区域。他们共同构建出了首页的样式。

 

我们看一下 HomeView 中的代码:

<template>
  <div class="wrapper">
    <static-view />
    <near-by />
  </div>
  <foo-ter />
</template>

<script>
import StaticView from './StaticView.vue'
import NearBy from './NearBy.vue'
import FooTer from './FooTer.vue'
export default {
  name: 'HomeView',
  components: {
    StaticView,
    NearBy,
    FooTer
  }
}
</script>

<style lang="scss">
@import '../../style/viriables.scss';
.wrapper {
  overflow-y: auto;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: .5rem;
  padding: 0 .18rem .1rem .18rem;
  .wrapper--content {
    color: $content-fontcolor;
  }
}
.fl {
  float: left;
}
</style>

我们在 HomeView 中引入三个子组件然后在视图模板中使用引入的子组件。记得要在父组件的 components 中声明引入的子组件。wrapper是 StartView与NearBy组件的容器。

在 wrapper 的样式中有一个 overflow-y ,如果不加这个样式的话,首页在拖动滚动条时,Footer 底部就会变成这样:

加上 overflow-y 后表示可以在y轴放心滚动。

在修改 FooTer 组件样式时,我们想给底部字体10px大小,但是浏览器里默认我们的最小字号是12px,强制修改10px也只会显示12px,我们应该这么修改:

.docker__title {
  font-size: .2rem;
  transform: scale(.5,.5);
  transform-origin: center top;
}

通过 transform 让元素缩放的方式改变大小,最后要设置它的变换中心点,我们设置水平居中,垂直靠着顶部就正好

防抖

当我们在做到顶部的一个轮播图的时候,因为图片要从服务器中读取,所以加载速度很慢,就会产生一个抖动的现象。比如在图片下面加个文字,看一下网页的加载过程:

因为图片加载的太慢,所以下面的内容会产生这种抖动,我们通过css的方法去解决它:

.banner {
  height: 0;
  overflow: hidden;
  padding-bottom: 25.4%;
  &__img {
    width: 100%;
  }
}

我们先计算一下图片的高宽比,得出是0.254,那这里给个底部内边距百分之25.4指的就是屏幕宽度的百分之25.4,又因为图片的宽度和屏幕宽度一样,所以这就相当于图片的高度。所以我们这么想,就在图片没加载出来之前就会把位置占住。这样就实现了防抖效果。

底部横条

现在我们想给一个底部的条条这个该怎么做呢?这里的难点是我们最外层的盒子有一个padding值,所以我们的横条就不会占满宽度,这个问题应该怎么解决呢?很简单,把这个条条的外边距设置为负的就行

.gap {
  margin: 0 -.18rem;
  height: .1rem;
  background: #F1F1F1;
}

登陆注册功能开发💤

样式编写💥

在 views 目录下的LoginView和RegisterView分别表示登录和注册的页面。 

先编写一下基础代码:

<template>
 hello world
</template>

<script>
export default {
  name: 'LoginView'
}
</script>

<style scoped lang="scss">

</style>

我们先写一下它的视图模板:

<template>
  <div class="wrapper">
      <img src="http://www.dell-lee.com/imgs/vue3/user.png" alt="" class="wrapper__img">
      <div class="wrapper__inp">
          <input type="text" class="wrapper__input__content" />
      </div>
      <div class="wrapper__inp">
          <input type="text" class="wrapper__input__content" />
      </div>
      <div class="wrapper__login-button">登录</div>
      <div class="wrapper__login-link">立即注册</div>
  </div>
</template>

下面我们再写登陆页面的样式:


.wrapper {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 0;
  right: 0;
  &__img {
    display: block;
    margin: 0 auto .4rem auto;
    width: .66rem;
    height: .66rem;
  }
  &__input {
    box-sizing: border-box;
    height: .48rem;
    margin: 0 .4rem .16rem .4rem;
    background: #F9F9F9;
    padding: 0 .16rem;
    border: 1px solid rgba(0, 0, 0, .1);
    border-radius: 6px;
    &__content {
      width: 100%;
      border: 0;
      background: none;
      outline: none;
      line-height: .48rem;
      font-size: .16rem;
      color: rgba(0, 0, 0, .5);
      &::placeholder {
        color: rgba(0, 0, 0, .5);
      }
    }
  }
  &__login-button {
    height: .48rem;
    line-height: .48rem;
    margin: .32rem .4rem .16rem .4rem;
    text-align: center;
    background: #0091FF;
    box-shadow: 0 .04rem .08rem 0 rgba(0,145,255,0.32);
    border-radius: .04rem;
    color: #fff;
  }
  &__login-link {
    text-align: center;
    font-size: .14rem;
    color: rgba(0, 0, 0, .5);
  }
}

现在我们做一些路由跳转,先修改一下 router 里的 index.js 中的内容:

import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/home/HomeView.vue'
import LoginView from '../views/login/LoginView.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/login',
    name: 'login',
    component: LoginView
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

路由守卫实现基础登录校验功能💥

现在我们想实现一个功能,只有当登陆的时候才能访问首页,否则禁止访问首页

我们在 index.js 中通过 beforeEach 实现这个功能,先做一下简单的输出:

router.beforeEach((to, from, next) => {
  console.log(to, from)
  next()
})

这里 to 指的是要跳转到哪个页面的信息,from 指的是从哪个页面跳转的信息。router.beforEach 的意思就是每次在路由跳转前都要执行这个方法。

我们每次在跳转前先判断是否登录,如果用户之前登录过就跳转到对应的页面,否则就跳转到登陆页面。但是如果用户没有登录他跳转到登录页面的时候还会 router.beforEach 进行判断,这样他又会跳到登陆页面,这样会一直循环,所以我们在 if 中还得加一个条件,如果跳转的是登陆页面的话就允许跳转。

router.beforeEach((to, from, next) => {
  const isLogin = false
  if (isLogin || to.name === 'login') {
    next()
  } else {
    next({ name: 'login' })
  }
})

现在我们的页面默认就会跳转到登陆页面,就算在浏览器路径中让它跳到首页,他也不会跳转。

现在我们就去实现当用户点击登陆时候的跳转功能,在 LoginView 里,先给按钮一个点击事件:

<div class="wrapper__login-button" @click="handleLogin">登录</div>

当点击登陆时,会先判断输入的电话号码是否符合格式,符合与不符合都会有相应的弹窗(这里弹窗是element-plus的组件),当符合格式时就让 isLogin 为 ture,表示在登陆状态:

import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
export default {
  name: 'LoginView',
  setup () {
    const router = useRouter()
    let number = ref('')
    let password = ref('')
    let handleLogin = () => {
      let reg = /^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$/
      if (reg.test(number.value)) {
        open2()
        localStorage.isLogin = true
        setTimeout(() => {
          router.push({ name: 'home' })
        }, 2000)
      } else {
        open()
      }
    }
    let open = () => {
      ElMessage({
        message: '您输入的电话号码格式错误',
        type: 'error',
        duration: 2000
      })
    }
    let open2 = () => {
      ElMessage({
        message: '登陆成功欢迎您',
        type: 'success',
        duration: 2000
      })
    }
    return {
      handleLogin,
      number,
      password,
      open,
      open2,
      router
    }
  }
}

然后我们完善一下 router 下 登陆路由的配置:

path: '/login',
name: 'login',
component: LoginView,
beforeEnter (to, from, next) {
  const isLogin = localStorage.isLogin
  if (isLogin) {
    next({ name: 'home' })
  } else {
    next()
  }
}

路由的 beforeEnter 事件就是当跳转路由之前执行的,如果我们当前已经登录成功,跳转到首页了。如果我们想跳转回登录页面的话就会来到 beforeEnter 判断,登陆成功后 isLogin 这个登录状态就是 true,这样就不会再退回到登录页面,还会跳转到首页。

在完成登录页面后,我们照猫画虎继续完成注册页面,把登录页面的内容复制一份,注册页面就比登录页面多了个确认密码,然后去 index.js 中配置路由信息。

只不过我们还得完成登录与注册页面之间的切换,在登录页面点击立即注册后跳转到注册页面:

let handleRegisterClick = () => {
      ElNotification({
        title: '尊敬的用户您好',
        message: h('i', { style: 'color: teal' }, '正在跳转到注册页面'),
        duration: 800
      })
      setTimeout(() => {
        router.push({ name: 'register' })
      }, 900)
    }

在登录页面单击立即注册时,通过 element-plus 弹框提示,然后跳转路由,注册页面也是相同的操作。

使用 axios 发送登录 Mock 请求💥

现在我们的登录注册都是前端模拟出来的,现在我们要学习如何在前端调用接口,和后端做交互。

在我们的登录组件中,如果用户点击登录了,我们就让登录状态为 true,显然这是不合理的,我们应该先向后端发送请求,如果用户名和密码匹配,才允许登录将状态改为 true。

那我们首先安装一下 axios:

npm install axios ---save

把他引入到登录组件中:

import axios from 'axios'

这里的后端接口是我们通过 fastmock 模拟的后端接口,大家可以通过这个 url 来得到我们这个项目需要用到的数据,下面是我们这个项目的接口文档,可以看到登录是通过发送 post 请求来实现的,后面跟着的有登录的接口地址:

下面是我们这个项目的接口文档的地址:

https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd/

我们给登录按钮加一个点击事件,然后在这个函数里实现我们想要的功能,这里加上 setTimeout 是因为 element-plus 的弹窗有两秒的时间,然后两秒后我们再实现登录跳转就更贴近实际一些。

post 请求中我们还需要把请求的数据返给后端接口, 下面就是登录事件的代码:

 let handleLogin = () => {
      axios.post('https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd/api/user/login', {
        username: username,
        password: password
      }).then(() => {
        open2()
        localStorage.isLogin = true
        setTimeout(() => {
          router.push({ name: 'home' })
        }, 2000)
      }).catch(() => {
        open()
      })
    }

现在当我们点击登录时,就模拟了一个post请求,把输入的内容返回给后端接口,这里的接口只是用来模拟请求过程,并不是我们项目的真实后端接口。

注意要把返回内容的格式设置为 json ,因为 fastmock 是这么要求的。

请求函数的封装💥

vue3 已经支持 async 和 await 这样的语法,我们重新写一下上一节的代码,输出一下返回的结果:

    let handleLogin = async () => {
      const result = await axios.post('https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd/api/user/login', {
        username: username,
        password: password
      // }).then(() => {
      //   open2()
      //   localStorage.isLogin = true
      //   setTimeout(() => {
      //     router.push({ name: 'home' })
      //   }, 2000)
      // }).catch(() => {
      //   open()
      // })
      })
      console.log(result)
    }

启动项目,点击登录,result就在控制台中输出出来了:

这里data中的 errno 表示返回的错误个数,如果是0就表示请求发送成功,那么我们继续完善代码:

    let handleLogin = async () => {
      const result = await axios.post('https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd/api/user/login', {
        username: username,
        password: password
      })
      if (result.data.errno === 0) {
        localStorage.isLogin = true
        open2()
        setTimeout(() => {
          router.push({ name: 'home' })
        }, 2000)
      } else {
        open()
      }
    }

现在我们故意把 url 地址写错:

启动项目,看看有什么效果:

控制台的网络这块就报错了,但是并没有弹窗,这是为什么呢?

因为异常会在 await 那里抛出,不会走下面的代码了,自然不会执行弹窗语句,那我们通过 try catch就能解决这个问题:

let handleLogin = async () => {
      try {
        const result = await axios.post('https://www.fastmck.site/mock/ae8e9031947a302fed5f92425995aa19/jd/api/user/login', {
          username: username,
          password: password
        })
        if (result.data.errno === 0) {
          localStorage.isLogin = true
          open2()
          setTimeout(() => {
            router.push({ name: 'home' })
          }, 2000)
        } else {
          open()
        }
      } catch (e) {
        open3()
      }
    }

这样在输入错误的 url 时,他就会提示我们请求失败了:

现在我们每发一个请求都要写一段很长的请求地址,后面请求别的接口还得再写这样一段代码,那我们就把它封装一下。

我们在 src 目录下新建一个 utils 文件,在 request 里封装 post 请求:

我们对 post 请求做了一个封装:

import axios from 'axios'
export const post = (url, data = {}) => {
  return new Promise((resolve, reject) => {
    axios.post(url, data, {
      baseURL: 'https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd',
      headers: {
        'Content-Type': 'application/json'
      }
    }).then((response) => {
      resolve(response)
    }, err => {
      reject(err)
    })
  })
}

这样在 Login 中我们就不需要引入 axios 了,直接把 post 方法引入进来就行:

import { post } from '../../utils/request'

现在我们的弹窗用的是 element plus 提供的组件,但是用的多了的时候就会有大量冗余的代码,下面我们对他也进行一下封装:

    let alertmessage = (thecontent, thetype, theduration) => {
      ElMessage({
        message: thecontent,
        type: thetype,
        duration: theduration
      })
    }

这样当我们用到弹窗这个功能时,直接指定参数就行了:

在 register 组件里我们点击注册的时候也是发送 post 请求,和登录页面的实现逻辑相同,只是请求的接口不一样,接口地址在上面的接口文档中有,大家可以自行查看,在这一节中我们封装了请求函数,然后在登录页面和注册页面中使用我们封装的这个函数实现了数据的请求。

现在我们的登录注册页面的功能就大致完成了,启动项目看看最终的效果:

 

通过代码拆分增加逻辑可维护性💥

现在我们把各种函数都放在了 setup 中,这样做肯定没有出错,但是这样会让我们的 setup 函数非常长,如果项目做到后面我们要在里面找某一个函数或者变量的时候,都很麻烦,如果把关于登录逻辑的数据和方法都放在 setup 外面的一个函数中,关于注册逻辑的数据和方法放在另一个函数中,这样再把这些函数在 setup 中接收,在 setup 中我们只关心整个页面的实现逻辑就行,这样整个代码的维护性和可读性都大大提高了。

在登录页面我们把向后端发送登录请求的相关逻辑从 setup 中抽离出来:

const useLoginEffect = () => {
  const router = useRouter()
  let username = ref('')
  let password = ref('')
  let handleLogin = async () => {
    if (username.value === '' || password.value === '') {
      alertmessage('输入内容不能为空', 'warning', 1500)
      return
    }
    try {
      const result = await post('/api/user/login', {
        username: username,
        password: password
      })
      if (result.data.errno === 0) {
        localStorage.isLogin = true
        alertmessage('登录成功欢迎您', 'success', 2000)
        setTimeout(() => {
          router.push({ name: 'home' })
        }, 2000)
      } else {
        alertmessage('登录失败', 'error', 2000)
      }
    } catch (e) {
      alertmessage('请求失败', 'error', 2000)
    }
  }
  return { username, password, handleLogin }
}

这里我们重新定义了一个useLoginEffect 函数,然后把需要用到的数据和方法都放进来,最后通过 return 把数据和方法返回出来,以便在 setup 中接收。

我们再把点击注册这个函数的相关逻辑抽离出来:

const useRegisterEffect = () => {
  const router = useRouter()
  let handleRegisterClick = () => {
    ElNotification({
      title: '尊敬的用户您好',
      message: h('i', { style: 'color: teal' }, '正在跳转到注册页面'),
      duration: 800
    })
    setTimeout(() => {
      router.push({ name: 'register' })
    }, 900)
  }
  return { handleRegisterClick }
}

这样我们就把登录页面相关的功能都从 setup 里面抽离了出来,现在再看 setup 里的代码就优雅了许多,浅显易懂:

setup () {
    const { username, password, handleLogin } = useLoginEffect()
    const { handleRegisterClick } = useRegisterEffect()
    return {
      handleLogin,
      username,
      password,
      handleRegisterClick
    }
  }

在 setup 里我们很清晰的知道这个页面的实现逻辑,如果想修改跳转登录这个函数就去对应的函数里修改就可以,方便了很多。

在注册页面的代码拆分和登录页面的相同,这里就不过多阐述。在本文中我们暂时完成了项目首页和登陆注册页面的样式,实现了登陆注册时向后端发送请求获取数据的功能,最后通过代码拆分增加逻辑可维护性。下一篇文章我们会实现商家展示功能的开发,大家记得关注哦!

项目代码地址:

https://gitee.com/jie_shao1112/jingdong-homeicon-default.png?t=M4ADhttps://gitee.com/jie_shao1112/jingdong-home
 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

html基本标签

目录 1&#xff0c;标题标签h1-h6 2&#xff0c;段落标签p 3&#xff0c;换行标签br 4&#xff0c;水平线标签hr 5&#xff0c;图片标签img及路径详解(绝对/相对路径) 6&#xff0c;超文本链接标签a 7&#xff0c;超本文链接之锚点 8&#xff0c;div标签 9&#xff0c…

JS-获取网页滑动距离,并实时监听

介绍 本文主要介绍通过JS获取网页滑动距离&#xff0c;并实时监听的方法。分析document.body.scrollTop、document.documentElement.scrollTop、window.pageYOffset 三者之间的区别。 一、获取网页滑动距离 JS方法&#xff1a; console.log(网页被卷去的高&#xff1a;, doc…

05-ES6语法:解构赋值

本文我们介绍ES6中解构赋值。ES6的解构赋值语法是一种JS表达式。解构赋值语法是一种JS表达式&#xff0c;通过解构赋值&#xff0c;可以将属性/值从对象/数组中取出&#xff0c;赋值给其他变量。 下面我们具体来看看解构赋值是什么&#xff1f;以及是如何使用的&#xff1f; …

Bootstrap——制作个人简历网页、工具类【边框(添加、删除、颜色、圆角)、清除浮动、颜色(文本、链接、背景)、display属性、浮动、定位、文本对齐】

制作个人简历网页 代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><meta name"viewport"content"widthdevice-width,initial-scale1,minimum-scale1,maximum-scale1,u…

移动端H5网页开发必备知识

简介 工欲善其事必先利其器&#xff0c;今天这篇文章主要讲解移动端H5开发必备的一些基础知识以及移动端适配和布局方案。如果已经看过这篇文章了或者已经掌握了移动端基础的话可以看笔者写的 移动端H5网页开发常见问题汇总 移动端开发必备知识-Hybrid App 像素 像素即一个…

在Vue中获取DOM元素的实际宽高

最近使用 D3.js 开发可视化图表&#xff0c;因为移动端做了 rem 适配&#xff0c;所以需要动态计算获取图表容器的宽高&#xff0c;其中涉及到一些原生DOM API的使用&#xff0c;避免遗忘这里总结一下。 一、获取元素 在 Vue 中可以使用 ref 来获取一个真实的 DOM 元素。 为了…

【Vue】Vue 项目前端响应式布局及框架搭建

文章目录Vue 项目前端响应式布局及框架搭建一、项目基本结构二、项目分辨率响应式创建1、flexible.js2、引用 flexible 插件3、修改 flexible 默认配置4、cssrem 插件 (px -> rem)三、项目页面框架搭建1、设置背景图2、设置标题文字3、页面主体部分&#xff08;1&#xff09…

Request请求转发getRequestDispatcher

文章目录一、getRequestDispatcher理解二、RequestDispatcher.forward()方法与HttpServletResponse.sendRedirect()方法的区别三、实现步骤1.编写index.jsp登录页面2.编写跳转页面success.jsp页面3.编写LoginServlet.java类四、运行示例一、getRequestDispatcher理解 request.g…

Vue项目使用百度地图api

目录 1.百度开发者认证 2.创建应用 3.引用百度地图API文件 4.展示地图 1.百度开发者认证 进入百度地图开放平台 官网&#xff0c;&#xff08;认证需要身份证号码&#xff0c;人脸识别&#xff0c;手机百度APP&#xff0c;邮箱地址&#xff09; 注册登录完成&#xff0c;…

vue中devTools插件安装教程

vue-devTools 为了更方便的在开发过程中对 Vue 程序进行调试&#xff0c;除了传统的浏览器自带的 debug 工具以外&#xff0c;我们还可以通过一些专门为 Vue 提供的扩展插件来进行调试 vue-devTools插件&#xff1a;点击下载 插件安装教程&#xff1a;https://chrome.zzzmh.cn…

js深拷贝方法

一、ES6中扩展运算符 ES6中的扩展运算符&#xff08;如果只是一层数组或者对象就是深拷贝&#xff0c;多层就是浅拷贝&#xff09; var obj {name : "海绵宝宝",age: 18,sayHello (){console.log("比奇堡早上好");}}var newObj {...obj}console.log(&q…

Vue中的跨域解决方案

前言 跨域是因为浏览器存在对不同源页面数据接收的限制。这种限制就是浏览器的同源策略。 同源策略是浏览器的安全机制&#xff0c;跨域的原理就是通过各种方式避开浏览器的安全机制 使用 在项目开发时&#xff0c;对跨域的概念仅限于了解&#xff0c;所以没有注重过程&#xf…

Vue全新一代状态管理库 Pinia【一篇通】

文章目录前言1. Pinia 是什么&#xff1f;1.1 为什么取名叫 Pinia?1.2. 为什么要使用 Pinia ?2. 安装 Pinia2.1.创建 Store2.1.1. Option 类型 Store2.1.2 Setup 函数类型 Store2.1.3 模板中使用3. State 的使用事项&#xff08;Option Store &#xff09;3.1 读取 State3.2 …

命令行 cnpm install 报错: Install fail Error: Unsupported URL Type: npm:vue-loader@^15.9.7

是不是在 进行 cnpm install 报了同款错误呢&#xff01; G:\Git\owl-read-admin>cnpm install Install fail! Error: Unsupported URL Type: npm:vue-loader^15.9.7 Error: Unsupported URL Type: npm:vue-loader^15.9.7at parseUrl (C:\Users\Lenovo\AppData\Roaming\np…

@DateTimeFormat注解

DateTimeFormat注解 前言 前言在使用DateTimeFormat进行格式化注解时&#xff0c;总是不能匹配前端传入的。格式总是报错 我这里使用的是pattern进行解析的的但是前端是给我传入的ISO类型的导致不能匹配所以总是报错。后来我们进行查看源码得到了答案。 源码解析 看下源码解析…

vue实现在线预览office文件

最近在做电子档案&#xff0c;后端提供了文件的华为云的oss链接。已经实现了点击下载文件的功能。但是呢&#xff0c;他们又希望常规的文件&#xff0c;可以直接点击预览&#xff0c;不需要下载。 按道理说&#xff0c;做文件的在线预览&#xff0c;买个第三方服务什么的&…

前端工程师都在用的 VSCode 常用插件

文章目录前言一、VSCode常用的插件1.Chinese (Simplified) (必备)2.Auto Rename Tag3.One Dark Pro 颜色主题4.格式化代码&#xff08;vscode系统自带&#xff09;5.open in browser 浏览器预览页面6. Live Server 实时预览&#xff08;推荐&#xff09;7. vscode-icons 设置文…

Vue用户管理(增删改查)功能详情

1、最终实现效果&#xff1a; Users.vue: <template><div><!--面包屑导航区域--><el-breadcrumb separator-class"el-icon-arrow-right"><el-breadcrumb-item :to"{ path: /home }">首页</el-breadcrumb-item><el…

Ant Design Vue文件上传详解

ant design 基于vue的文件上传 (XSLX文件篇) Upload 上传 template <a-uploadname"multipartFile":multiple"false":action"action"methods"post"change"uploadFile":file-list"fileList":disabled"di…

Emmet语法总结

1 Emmet简介 Emmet是一个Web开发工具&#xff0c;用于加快HTML和CSS代码的编写速度。使用Emmet能够通过简短的表达式生成HTML或CSS代码片段。另外&#xff0c;截至2022年&#xff0c;主流的编辑器工具如Visual Studio Code、WebStorm都已经集成了Emmet工具&#xff0c;无需手动…