本来想用微信小程序来作为前端开发这个菜谱程序,但看了很多的找工作的帖子后发现好像现在都要求会个Vue了,于是我便转为使用Vue来开发我的前端
使用Vue之后最大的感觉是复用性真强,就如我之前逛贴吧看到的一句话一样:自编程语言出现之际,计算机社区就致力于将重复的工作封装起来。面向对象思想,各种库等都是对这一句话很好的解释。在之前我一直使用的都是微信小程序或者原生的Html那一套,接触了Vue之后我才发现这个框架是多么的好用。比如一个按钮,在之前的开发中每个页面都要写一遍,就算是复制也很重复,但在Vue中可以直接写一个按钮组件,之后用到直接调用,并且可以根据需要修改参数或者方法功能,可能只是简单一点,但如果是一个大项目使用这种可复用预编译组件的方式可以节省很多编译时间与资源,提升的效率是巨大的。
夸了这么多,下面我来说一下这几天写Vue碰到的问题与解决方法吧。
-
跨域问题
对于跨域问题我直接引用百度:当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
我遇到的实际情况是前端Vue开发端口为5173,后端是8000,端口不同于是就有了跨域问题。我首先使用的解决方法是在vue的配置中加入反向代理
图为vite.config.js中的反向代理代码
但当我设置之后发现不起作用,当将axios的baseurl换成/api时,要么请求的链接变成localhost:5173而不是8000,要么就变成/api/localhost:8000报404错误。尝试无果之后我便在后端进行配置,配置好之后运行可以,但也不可以运行。它两个端点,一个登陆的login接口仍然报错跨域问题,一个注册的register可以正常运行更神奇的是我把"login"换成"login_"就可以跨域了。这就给我搞蒙了,于是我便去贴吧发帖问了一下,得到的解释是我的login接口在之前没配置好的时候有预检请求,响应被浏览器拦截后缓存了,下次如果再请求就会一直走缓存,解决的方法是刷新浏览器时使用ctrl+F5刷新。
跨域问题方法总结:
跨域的十种解决方案 - 掘金 (juejin.cn)
父子组件之间的通信问题
关于这个问题Vue的文档已经讲的很详细了,这里我简单说一下我遇到的情况与解决方法
(1):子组件响应不同父组件的操作
在本例中子组件为一个登陆注册的组件<LoginRegister>,父组件为<Login>与<Register>,业务为点击子组件中的一句话实现重定向为父组件彼此,即在点击“还没有账号?点击注册”会跳转到注册界面。为了实现这一业务,子组件首先在div上添加$emit,调用内置的 $emit
方法,通过传入事件名称来抛出一个事件,并在data中声明事件名称,同时父组件接收此事件名称为键,根据键值找到对应的方法并执行。子组件<LoginRegisterBox>代码如下:
<script>
export default{
//emits尽量要声明
emits: ['redirect']
}
</script>
<div id="inputcontainer">
<div @click="$emit('redirect')" id="logintext">{{ this.boxtext }}</div>
</div>
父组件<Login>代码如下:
import LoginBox from "../components/LoginRegisterBox.vue";
export default{
components:{
LoginBox
},
methods:{
redirectToeachOther(event){
this.$router.push('/register')
}
}
}
<template>
<LoginBox uptitle="登录" boxtext="还没有账号?点击注册" @redirect="redirectToeachOther" buttonMethod="login"/>
</template>
(2):子组件接收多个父组件的方法名称作用在同一个绑定上
首先说业务详情,这个业务和上一个差不多,不过绑定的名称是动态可变的。具体来说就是我有一个按钮组件,且有三个父组件调用按钮组件需要进行点击事件执行操作,它们对同一个子组件的click进行操作,此时就要求父组件将方法名称利用props传入子组件中,子组件再加以判断,如果传入的值是一个function,那么便执行。代码如下:
子组件<ButtonGen>中
<script>
export default {
props: {
title:String,
buttonMethod:String,
},
methods:{
ChildbuttonMethod(){
const method=this.$parent[this.buttonMethod]
if (typeof method === 'function') {
method()
} else {
console.warn(`Parent method '${this.methodName}' not found or not a function.`)
}
}
}
}
</script>
<template>
<div id="genbutton" @click="ChildbuttonMethod">
</div>
</template>
父组件<LoginRegisterBox>
props:{
buttonMethod:String,
},
<div id="inputcontainer">
<ButtonGen :title="this.uptitle" :buttonMethod="this.buttonMethod"></ButtonGen>
</div>
爷组件<Login>
<script>
import LoginBox from "../components/LoginRegisterBox.vue";
export default{
components:{
LoginBox
},
methods:{
redirectToeachOther(event){
this.$router.push('/register')
}
}
}
</script>
<template>
<LoginBox uptitle="登录" boxtext="还没有账号?点击注册" @redirect="redirectToeachOther" buttonMethod="login"/>
</template>
之所以父子间中的“buttonMethod”是爷组件传进去的,再有父组件传到子组件中,这里其实可以修改为注入,但由于props链条并不深所以就没改。
以上便是本次学习记录全部内容