跳到主要内容

4 篇博文 含有标签「vue」

查看所有标签

vue和django项目的开发/生产环境配置管理

· 阅读需 5 分钟
Jason Lee
The owner of this blog site

前言

虽然教程作者提到了一些分开管理两种环境的做法,但是我这边没有形成完整可复制的做法。借助 chatgpt,将收获整理出来。

vuejs

在项目的根目录下,分别创建两个文件:.env.development and .env.production。最基础的设置是 api 地址:

# .env.development
VITE_API_URL=http://dev-api.example.com

# .env.production
VITE_API_URL=http://api.example.com

任何设置都有以 VITE_开头。为了区别使用配置,在vite.config.js中,有如下:

export default defineConfig({
// 开发环境使用 .env.development 文件
envDir: './',
build: {
// 生产环境使用 .env.production 文件
envFile: '.env.production',
},
});

django

相对于 vue, django 的设置就要复杂一些了。这里把 gpt 关于生产和开发环境的不同列出来,虽然有很多在这个项目没有实现,但是可以为以后更复杂的真实项目做参考。

在 Django 项目中,开发环境和生产环境通常需要进行不同的设置。下面是一些常见的设置差异:

调试模式(Debug Mode):

开发环境:设置 DEBUG = True,以便在出现错误时显示详细的错误信息。 生产环境:设置 DEBUG = False,以避免显示敏感信息和详细的错误信息。 数据库设置:

开发环境:通常使用本地数据库(如 SQLite)进行开发和测试。 生产环境:使用更稳定和可靠的数据库服务器(如 PostgreSQL、MySQL、Oracle)。 静态文件设置:

开发环境:通常将静态文件存储在本地,并通过 Django 的 staticfiles 应用程序来提供静态文件服务。 生产环境:可以使用 CDN(内容分发网络)来提供静态文件,以减轻服务器负载并提高速度。 日志设置:

开发环境:可以设置较详细的日志记录级别,以便更容易调试和跟踪问题。 生产环境:通常使用更严格的日志记录级别,并将日志信息定向到适当的日志文件,以便进行监视和故障排除。 密钥和敏感信息:

开发环境:可以在本地设置中直接存储密钥和敏感信息。 生产环境:建议使用环境变量或其他安全的方式来存储密钥和敏感信息,以保护生产环境的安全性。 域名设置:

开发环境:可以使用本地的开发服务器(如 localhost)进行开发和测试。 生产环境:设置正确的域名,并配置 Web 服务器(如 Nginx 或 Apache)以将请求转发到 Django 应用程序。 缓存设置:

开发环境:可以禁用缓存或使用简单的缓存配置,以方便开发和调试。 生产环境:使用更高效的缓存后端(如 Memcached 或 Redis)来提高性能。 这些只是一些常见的设置差异,实际上还可以根据项目需求和部署环境的要求进行更多的设置和调整。

本项目中,在根目录下创建了三个文件,settings_common.py, settings_dev.py, settings_prod.py。其中 common 是两种环境之间共享的通用配置,然后在 dev 和 prod 中分别引用 common:

from .settings_common import *

然后在 dev 和 prod 各自写一些配置(比如数据库等)。之后修改启动文件manage.py:

import os
import sys

if os.environ.get('DJANGO_ENV') == 'production':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings_prod')
else:
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings_dev')

def main():
# 启动逻辑...

if __name__ == '__main__':
main()

如果要部署,记得把环境变量添加上,即设置 DJANGO_ENV 环境变量为 'production'. 而且如果是 uwsgi 作为 django 的服务器的话,还有修改wsgi.py

总结

前端 vue 的环境区别很简单,后端 django 的稍复杂些。主要分三步走:编写配置文件->修改启动文件->部署设置环境变量。

子组件外面一层的div为什么要加v-if

· 阅读需 2 分钟
Jason Lee
The owner of this blog site

项目中有这样一段代码:

<div class="p-4 bg-white border border-gray-200 rounded-lg mb-4" v-if="post.id">
<PostItem v-bind:post="post" />
</div>

PostItem 作为子组件被包裹在一层 div 中,外层 div 起到控制样式的作用。如果去掉 v-if,前端报错:PostItem 内无法获得 post 数据。一开始,我想不明白:为什么 post 在 script 中赋值,而不能直接使用?

chatgpt 给出的回答是:

如果去掉子组件外面一层的 div 中的 v-if 指令,可能会导致父组件无法正确地向子组件传值。这是因为 v-if 指令会影响组件的渲染时机,如果去掉 v-if 指令,组件会在父组件渲染时一并渲染,此时父组件传递给子组件的数据可能还没有准备好,导致子组件无法正确获取数据。

当加上 v-if 指令后,只有在 v-if 条件为真时,子组件才会被渲染,这样可以保证父组件传递给子组件的数据已经准备好了。因此,如果要在父组件向子组件传值时,建议在子组件外面加一层带有 v-if 指令的 div 来控制子组件的渲染时机,以保证子组件能够正确地获取父组件传递的数据。

跨域问题描述和解决方案

· 阅读需 3 分钟

什么是跨域

跨域是浏览器对js脚本和ajax请求做出的限制。不同源的js脚本获取对方的cookie,ajax无法发送跨域请求。

解决方案

CORS

在服务器设置字段Access-Control-Allow-Origin。当浏览器收到服务器返回的资源上,没有Access-Control-Allow-Origin字段,就会拒绝加载

jsonp

jsonp的原理就是利用<script>标签没有跨域限制,通过<script>标签src属性,发送带有callback参数的GET请求,服务端将接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从而前端拿到callback函数返回的数据。

问题描述:调试阶段,前端项目请求后端接口返回数据,前端项目和后端的端口不一致,产生了跨域问题。部署阶段,前端打包完毕,项目发起请求,同样有跨域问题,两种场景的解决方法不同。

下面解决问题的场景是,打包的前端文件并不在服务器的文件路径中。

调试阶段

后端可以不用设置,只要前端设置代理服务器即可。在vue根目录下的vue.config.js添加下述代码:

module.exports = ({
devServer: {
proxy: 'http://localhost:3000' //3000为后端接口的端口号
},
publicPath: './' //解决打包后的静态文件路径问题
})

跨域只存在浏览器中,服务器之间不存在跨域,所以可以通过服务器代理

部署阶段

vue根目录下建立两个配置文件:.env.development.env.production

//.env.development
VUE_APP_BASE_API='http://localhost:3000'
VUE_APP_ENV='dev'
//.env.production
VUE_APP_BASE_API='http://localhost:3000'
VUE_APP_ENV='pro'

在请求代码处,设置判定条件,若当前调试环境,则url=/home, 若为打包环境,则url为全文

let api = null;
if (process.env.VUE_APP_ENV === 'dev') {
api = '/home'
} else {
api = process.env.VUE_APP_BASE_API + '/home'
}

最后,express要设置cors允许跨域

router.all('*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Methods', '*');
res.header('Content-Type', 'application/json;charset=utf-8');
next();
});

初学vue2踩坑记

· 阅读需 6 分钟

跟着 b 站黑马程序员的视频入门 vue,跟敲代码过程中,踩到一些坑,在这里记录一下:

  • 定义方法时,是methods而不是method
  • {{}}叫做插值表达式

  • 写计数器案例时用到了 flex,发现下面这种换行不是 flex 认可的换行,align-content无效:

<span>{{num}}</br>{{num}}</span>
  • v-bind bind,绑定的意思,就是给元素绑定属性。首先,用简写形式:[name]="content"。然后绑定类名属性class时,最简单的写法是,:class="{[name]:isActive}",也就是切换类。 v-for 有一个性能优化问题。实时绑定的数据,在数据量大的情况下,计算复杂大,所以,vue 在使用了 v-for 的标签里添加了一个 key 属性,并将其用 v-bind 绑定,属性值应该是一个不重复的值,在数据更新时,判断是否时新的 key, 然后渲染。不宜用索引值,因为在数组中间插入时,很多数据的 key 会更新。

  • v-model 双向绑定表单元素的值。那么常见的表单元素及其值有哪些呢?

你可以用 v-model 指令在表单 <input><textarea><select> 元素上创建双向数据绑定。

官网文档上的举得例子挺多,感觉这里是比较容易犯错的。

  • <input type=''>

顺便复习一下 input 表单元素。看到以下类型能想起他们作用和浏览器中的样式即可。 text/password/radio/checkbox/button


下面是做视频中的项目时遇到问题的记录

  • 如何将输入框的内容双向绑定?

原以为input需要声明一个值作为输入内容,实际上 v-model 自己就可以将输入值和data中的变量绑定。所以应该先创建data中的变量,然后绑定。

  • 悬浮在 item 时,显示删除符合的 css

原本想的是先用行内样式将删除模块设为display:none。后来发现不起效。原因是行内样式的优先级最高,<style>标签里的 css 会被覆盖。所以把上述代码放到了<style>里,成功。

  • 如何设置主体高度随条目数量增大而增大,并在超过某一限度时设置滚动

直接上代码:

.items {
max-height: 420px;
overflow: auto;
}

附上overflow中 scroll 和 auto 属性的区别:

二者都会在内容超出范围时显示滚动条,但在元素没有超出时,auto 会隐藏滚动条,scroll 依旧显示滚动条,但是禁用该滚动条。


一起记录下 vuecli 的入门学习过程。

  • babel:将 es 较新版本的规则编译成较低的,来让浏览器运行

  • npm run serve后,生成的两个地址中,有一个网络地址,可以通过其他在同一局域网下的设备访问

  • package.json中,script下包含了项目的启动方式。除了start外,都要写成npm run ...的形式。

  • 开发环境和生产环境:开发环境包含了很多库,还要.vue后缀文件,不能被浏览器解析。所以,执行 webpack(vuecli 自带)打包,npm run build命令后,变成 html\css\js 的生成环境。

  • .gitignore说明了哪些文件在 git 上传中被忽略

  • .vue文件中的<template>标签下。只能用一个 html 根标签。一个组件就包含了 html\js\css.

  • main.js和 vue 组件里的 js 代码什么关系? index.html直接执行的 js 文件只有main.js,而main.js导入了其他组件编写的 js 代码的接口。

  • 组件注册分为全局(很少用)和局部。局部组件三步走:引入+注册+使用。注册完毕后,就可以将整个组件以 html 标签的形式插入到 app.vue 中。

  • style标签里面添加scoped可以令样式只作用于当前组件,是通过为组件标签添加 hash 值属性实现的。

  • slot是什么?用于组件之间的嵌套。在组件 a 标签内部,插入组件 b 标签,并在组件 b 标签中添加 slot 属性及 id。然后在组件 a 内添加<slot>标签,name 属性是 id。即可实现精确的占位。

package.json 里面的 devDependencies 和 dependencies 分别是什么?

配置项命令描述
devDependencies--save-dev 简写 -D开发环境,管理的依赖包仅在开发阶段有效
dependencies--save 简写 -S生产环境,管理的依赖包在项目上线后依然有效