Vue入门到关门之Vue项目工程化

embedded/2024/10/16 2:04:32/

一、创建Vue项目

1、安装node环境

  • 官网下载,无脑下一步,注意别放c盘就行
    • Node.js — Run JavaScript Everywhere (nodejs.org)
  • 需要两个命令
    • npm---->pip
    • node—>python
  • 装完检查一下,hello world检测,退出crtl+c

在这里插入图片描述

2、搭建vue项目环境

  • 装cnpm 这个包,下载东西会快很多,装模块 cnpm替代npm,其他命令还是使用npm
npm install -g cnpm --registry=https://registry.npmmirror.com

在这里插入图片描述

  • 如果卡顿,或者一直失败,可以尝试以下两个解决方案
### 解决方案1:
// 1. 清空缓存
npm cache clean --force
// 2. 关闭SSL验证
npm config set strict-ssl false
// 3. 安装
到这里就可以正常使用npm命令安装需要的工具了。如(npm install -g cnpm   )### 解决方案2:
// 1. 清空缓存
npm cache clean --force
// 2. 切换新源
npm config set registry https://registry.npmmirror.com
// 3. 查看源是否设置成功
npm config get registry
// 4. 安装
到这里就可以正常使用npm命令安装需要的工具了。如(npm install -g cnpm   )
  • 检测是否安装成功

在这里插入图片描述

3、安装vue脚手架

cnpm install -g @vue/cli

在这里插入图片描述

4、创建项目

(1) 装完脚手架,就会有个vue命令,通过vue命令创建vue项目

vue create myfirstvue # 按下面步骤
  • 选y

在这里插入图片描述

  • 选第三个,enter进入

在这里插入图片描述

  • 选下面三个,空格是选择或者取消,方向键控制上下

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 创建成功

在这里插入图片描述

(2)命令行输入vue ui也可以创建项目

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5、使用webstorm打开项目

在这里插入图片描述

6、运行项目

(1)在命令行中输入命令运行

  • 注意命令行的路径得是项目根路径,使用:
npm run serve
  • 默认terminal使用的是powershell,我们可以改成cmd来使用

在这里插入图片描述

在这里插入图片描述

  • 如果有下面这个启动错误

在这里插入图片描述

  • 解决方案

这个错是因为文件夹权限不够,不要将创建的Vue项目放到任意盘的program files文件夹里,不然永远是这个错误,因为那个文件夹不能设置为完全控制,所有肯定会报权限不够的错误。

解决方案就是将项目放入一个自定义文件夹即可

(2)配置webstorm,点绿色箭头执行

  • 新建一个npm命令用来执行执行 serve脚本

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 启动成功的界面

在这里插入图片描述

在这里插入图片描述

二、vue项目目录结构

myfirstvue            # 项目名-node_modules     # 等同于python的venv--》虚拟环境-->里面有很多js,项目的依赖-》可以删除---》项目就不能运行了--》在你本地--》cnpm install--》根据package.json项目的依赖,再重新安装--》又可以运行了-public           # 文件夹,一般不动-favicon.ico  # 小图标-index.html   # spa--》单页面应用--》整个vue项目,就只有这一个html-如果禁用了js--》整个vue都用不了-src             # 文件夹---》核心代码-assets       #文件夹,都放静态文件--》图片,css,js。。。-logo.png # 静态图片-components   # 小组件,给页面组件使用HelloWorld.vue # HelloWorld 组件-views        # 页面组件,页面跳转,实现像 html跳转一样的效果AboutView.vue # 关于页面HomeView.vue  # 首页-store            # vuex--》状态管理器index.js-router           # vue-router---》路由配置文件index.js-App.vue          # 根组件-main.js          # 整个项目入口-.gitignore      # git忽略文件,学了git就会了-babel.config.js # 装了bable配置文件--》把高版本es语法转成es5-jsconfig.json   # 不用管-package.json    # 项目依赖文件--》项目依赖--》npm install--》根据他装-package-lock.json # 锁定文件,之前项目中使用模块版本-README.md       # 项目介绍-vue.config.js   # vue整体配置文件   

三、vue项目运行机制

  • main.js是整个项目入口文件
// main.js---> 指定了index.html---> id为app的div---> 根App.vue 这个组件做了关联//es6 模块导入规范,等同于python导包
//commonJs的导入规范:var Vue=require('vue')
import Vue from 'vue'
import App from './App.vue'  //根组件
import router from './router'
import store from './store'Vue.config.productionTip = falsenew Vue({router,store,render: h => h(App)  // 代指 el
}).$mount('#app')/*
new Vue({el:'#app' //原来是用el:'#app',现在是new出Vue对象,挂载到#app上---》.$mount('#app')render: h => h(App) //原来是在页面上div中写样式,现在组件化开发 把根组件(import App from './App.vue'),通过render渲染上,渲染组件的方式
}).$mount('#app')
*/
  • vue文件大致模版(template、script、style)
<template><!-- 模板区域 -->
</template>
<script>// 逻辑代码区域// 该语法和script绑定出现//export default-->es6的默认导出(导出一个对象),模拟commonJS的导出方式制定的export default {}
</script>
<style scoped>/* 样式区域 *//* scoped表示这里的样式只适用于组件内部, scoped与style绑定出现 */
</style>
  • 组件写法
# template 写之前我们方在template标签的模版字符串
<template><div id="app"><h1>我是根组件</h1><button @click="haneldShow">点我弹alert</button></div>
</template># script标签--》原来js代码都写在这里、
<script>
export default {name: 'HelloWorld', // 组件名字data() {return {}},methods: {haneldShow() {alert('111')}}
}
</script>#style
<style>button{background-color: aqua;
}
</style>
  • 定义组件
//1 新建xx.vue
components-->HelloWorld.vue
//2 引入使用
<script>// es6的引入import from import HelloWorld from '@/components/HelloWorld.vue'import Vue from 'vue'Vue.component('HelloWorld',HelloWorld)  // 全局组件export default {components: {  // 局部组件HelloWorld:HelloWorld},    
}
</script>

四、es6语法总结

1、let、const、var

在JavaScript中,letconstvar是用于声明变量的关键字,它们在作用域、可变性和提升等方面有一些重要的区别。 在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围。

ES6 新增了let命令,用来声明局部变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。

(1)var

  • var是ES5及之前版本中用于声明变量的关键字。
  • 使用var声明的变量存在函数作用域或全局作用域,而不存在块级作用域。
  • var声明的变量可以被重新赋值,并且可以在同一作用域内多次声明同一个变量。
  • var声明的变量会被提升(hoisting),即变量的声明会被提升到作用域的顶部,但赋值不会被提升。
  • 例如:
    javascript">var x = 10;
    if (true) {var y = 20;console.log(x); // 可以访问 xconsole.log(y); // 可以访问 y
    }
    console.log(x); // 可以访问 x
    console.log(y); // 可以访问 y,因为 var 变量会被提升
    

(2)let

  • let是ES6中引入的关键字,用于声明块级作用域的变量。
  • 使用let声明的变量可以被重新赋值,但不能在同一作用域内重新声明。
  • let声明的变量不会被提升,只有在声明后才能访问。
  • 例如:
    javascript">let x = 10;
    if (true) {let y = 20;console.log(x); // 可以访问 xconsole.log(y); // 可以访问 y
    }
    console.log(x); // 可以访问 x
    console.log(y); // 会报错,y 在块级作用域外不可访问
    

(3)const

  • const也是ES6中引入的关键字,用于声明常量,常量的值一旦赋值就不能再改变。
  • 常量必须在声明时进行初始化,且常量的值不可被重新赋值,但如果常量是对象或数组,对象或数组的属性或元素可以被修改。
  • const声明的变量也具有块级作用域。
  • 例如:
    javascript">const PI = 3.14;
    // PI = 3.14159; // 这里会报错,常量不可重新赋值const person = {name: 'Alice',age: 30
    };
    person.age = 31; // 这是允许的,因为对象的属性可以修改
    

(4)总结

  • 在现代JavaScript中,推荐优先使用const,如果变量的值需要变化,则使用let,避免使用var
  • letconst提供了更好的变量声明方式,有助于代码的可读性和可维护性,同时避免了var可能导致的一些问题。
  • 使用let声明变量时,如果变量的值会发生变化,但不需要重新声明变量,可以使用let
  • 使用const声明常量时,如果变量的值不会改变,可以使用const,这有助于提高代码的可读性和可维护性。

(5)补充

“暂时性死区”(Temporal Dead Zone,简称 TDZ)是指在 ES6 中使用 let 或 const 声明变量时,变量存在但无法访问的区域。这种行为是为了在 JavaScript 中引入块级作用域而设计的。

在 JavaScript 中,使用 var 声明的变量在其声明语句之前就可以被访问,这种行为称为"变量提升"。而在使用 let 或 const 声明变量时,变量虽然存在于作用域中,但是在声明语句之前访问这些变量会导致引发 ReferenceError 异常。

暂时性死区的产生原因是,let 和 const 声明的变量在进入作用域时就已经被创建,并且被绑定到了该作用域中,但是在变量的声明语句之前,访问这些变量会进入暂时性死区,因为此时变量尚未初始化

2、 箭头函数

(1)简化代码,使代码更简洁

(2)箭头函数内部,没有自己的this,它会使用上一级的this,解决了函数内部的this指向问题

(3)this指向问题:

  • 在全局上下文中,this 指向全局对象,在浏览器环境中通常是 window 对象,在 Node.js 中是 global 对象
console.log(this) # window 对象
  • 函数调用

    • 如果函数作为普通函数调用,this 指向全局对象(在严格模式下为 undefined)

    • 如果函数作为对象的方法调用,this 指向调用该方法的对象。

  • 构造函数

    • 在构造函数中,this 指向的是新创建的实例对象。
  • 箭头函数

    • 箭头函数的 this 指向定义时所在的作用域的 this 值,而不是调用时的 this 值。换句话说,箭头函数的 this 是词法作用域,而不是动态作用域。在传统的函数中,this的值是在函数被调用时确定的,根据调用方式不同可能指向不同的对象。但是在箭头函数中,this的值是在定义函数时确定的,它会捕获所在上下文的this值,而不是在运行时改变。这种行为可以避免在回调函数中出现意外的this指向问题,使得代码更加简洁和可读。
  • DOM 事件处理函数:

    • 在 DOM 事件处理函数中,this 指向触发事件的 DOM 元素
  • ES6 类方法:

    • 在 ES6 类方法中,this 指向调用该方法的对象实例

3、模版字符串

模板字符串是 JavaScript 中的一种特殊字符串,用反引号 ` (也称为反引号、重音符号或反引号字符)括起来。模板字符串可以包含多行文本和嵌入表达式,使用${}语法插入表达式。这使得在字符串中嵌入变量、表达式或函数调用变得更加方便。举个例子:

javascript">const name = 'Alice';
const greeting = `Hello, ${name}!`;console.log(greeting); // 输出: Hello, Alice!

在上面的例子中,${name}是一个嵌入的表达式,它会被变量name的值替换掉。模板字符串的这种特性使得动态生成字符串变得更加简单和直观。

4、解构赋值

解构赋值是一种在 JavaScript 中方便地从数组或对象中提取数据并赋值给变量的语法。它可以让你快速地将数组或对象中的值解构到单独的变量中。

  • 解构赋值允许从数组或对象中提取数据,并将其赋值给变量。
  • 解构赋值可以方便地交换变量的值,同时还支持默认值。

(1)对象解构赋值

在对象解构赋值中,花括号{}里面放置的是要提取的属性名,而变量名则是接收对应属性值的变量名。

javascript">let user = {name: 'lqz', age: 19, hobby: '烫头'}
// 平常写法
let name=user.name
let age=user.age
// 解构赋值写法
let {name,age,hobby,a=10} = userconsole.log(name,age,hobby,a)

(2)数组解构赋值

在数组解构赋值中,方括号[]里面放置的是要提取的元素位置,而变量名则是接收对应位置元素的变量名。同时**,...rest的语法表示将剩余的元素赋值给rest变量,这在需要获取数组中剩余元素时非常有用。**

javascript">const numbers = [1, 2, 3, 4, 5];
const [first, second, ...rest] = numbers;console.log(first); // 输出: 1
console.log(second); // 输出: 2
console.log(rest); // 输出: [3, 4, 5]

(3)解构函数返回值

function getuserInfo() {return {name: 'xiao', age: 19, hobby: ['烫头', '喝酒']}
}let {name='1', hobby} = getuserInfo()
console.log(name, hobby)  // 如果内部修改,优先返回值中的值

5、默认参数

ES6 允许在函数参数中设置默认值,当调用函数时未提供参数时,将使用默认值

# 案例
function demo01(name,age=19) {console.log(name,age)
}
demo01('xiao')

6、展开运算

展开运算符 ... 可以将可迭代对象(如数组、字符串、对象)展开为多个参数或元素。也可以用于函数参数。

# 案例1:对象
let a={age:19,hobby:'打球'}
let user={name:'xiao',age:20,...a}
console.log(user)
'''
Objectage: 19    # 以后面值为主hobby: "打球"name: "xiao"
'''# 案例2:数组
let l=[1,2,3]
let l1=[44,55,66,...l]
console.log(l1)
# [44, 55, 66, 1, 2, 3]# 案例3
function demo01(a,...b){console.log(a)console.log(b)
}
demo01(1,2,34,4)
'''
1
[2, 34, 4]
'''
let l=[44,5,66,7]
demo01(...l)
'''
44
[5, 66, 7]
'''

7、模块化

在以后,做项目开发的时候,肯定要导入某些模块使用:

  • 之前的前端是使用<script src=""></script>
  • 以后在项目中:import App from './App.vue' 语法引入

(1)默认导出和导入

默认导出 (Default Export)

默认导出允许一个模块只导出一个默认值。在一个模块中,你可以使用 export default 来导出默认值,然后在另一个模块中使用 import 语句来引入这个默认值。

示例:

javascript">// xiao/utils.js
var name = 'xiao'function add(a, b) {console.log(name)return a + b
}export default name  // 只导出变量
export default add   // 只导出函数
export default {name,add}  // 导出对象export default {name:"彭于晏",add: (a,b)=>{return a+b}
}
导入默认导出

在导入默认导出时,你可以选择给导入的变量起一个名字,这个名字不必和导出时的名称相同。

javascript"><script type="module">// 相对导入,相对于当前文件import xiao from './xiao/utils'  // 绝对导入--》开始导入的路径  src路径,但是需要写个 @import xiao from '@/xiao/utils'console.log(utils.name)let res=utils.add(3,4)console.log(res)
</script>
注意事项
  • 一个模块只能有一个默认导出。
  • 在导入默认导出时,你可以选择使用任何合法的变量名。

默认导出适用于导出一个单一的值、对象、函数等,使得导入时更加简洁。

(2)命名导出和导入

在 JavaScript 中,除了默认导出之外,还有一种常用的导出方式是命名导出(Named Export)。命名导出允许一个模块导出多个变量、函数或对象,这些导出的内容可以在导入时通过名称引用。

命名导出 (Named Export)

使用命名导出时,你可以在一个模块中通过 export 关键字导出多个变量、函数或对象,然后在另一个模块中通过名称引入这些导出。

示例:

javascript">// xiao/utils.js
// 可以导出多个
export const age = 99
export const add = (a, b) => a + b
export const showName = name => {console.log(name)
}export const obj={name:'xiao',show(){alert('show')}
}
导入命名导出

在导入命名导出时,需要使用花括号 {} 来指定要导入的内容,同时这些名称必须与导出时使用的名称相匹配。

javascript">// 第一种方式:花括号导入
import {age, add, showName} from '@/xiao/common'
import {showName, obj} from '@/xiao/common'
// 以后可以使用showName里面函数
// 以后可以使用obj的对象,又可以点obj.xx// 第二种方式:*全部导入然后取别名
<script type="module">import * as xx from './xiao/utils.js'console.log(xx.add(8,9))console.log(xx.age)
</script>
注意事项
  • 一个模块可以有多个命名导出。
  • 在导入命名导出时,必须使用与导出时相同的名称。

命名导出适用于导出多个变量、函数或对象,使得模块的功能更加灵活和可扩展。

(3)如果在文件夹下有个index.js,只要导到文件夹一层即可

  • index.js就相当于python中的__init__,导入的时候可以不用带index.js
// 导出的是index.js
export default {name:'xiao',showAge:function (){console.log('age',this.name)},showName:()=>{console.log(this.name)},showHobby(){console.log('hobby',this.name)}
}// 导入可以不用带index
<script type="module">// 命名导出的导入import xiao from '@/xiao/index'或者可以直接写成import xiao from '@/xiao'console.log('----',lqz.name)lqz.showAge()lqz.showHobby()
</script>

(4)vue项目中,组件的使用

  • 创建组件Child
<template><div><div class="top"><button>后退</button><span @click="handleShow">{{ title }}</span><button>前进</button></div></div>
</template><script>
export default {name: 'Child',data() {return {title: '首页'}},methods: {handleShow() {alert('1111')}}
}
</script><style scoped>
.top {display: flex;justify-content: space-between;
}
</style>
  • 在其他组件中使用
<template><div id="app"><h1>我是根组件</h1><button>点我弹alert</button><hr><Child></Child></div>
</template>
<script>
// @ 代指---》src文件夹
import Child from "@/components/Child.vue";
export default {name: 'HelloWorld',  // 组件名字components:{Child    // 注册局部组件}
}
</script><style>
button{background-color: aqua;
}
</style>

五、vue-router简单使用

单页面应用的字面意思就是只需要一个html页面就能实现页面跳转的效果,其本质就是组件的跳转。

那组件如何跳转?这就需要借助于第三方:vue-router 了

1、安装vue-router

(1)通过 npm 安装

  • 这是最常用的安装方式。安装完成后,你可以在代码中引入并使用 Vue Router。
npm install vue-router

(2)通过 CDN 引入

  • 你也可以通过 CDN 的方式引入 Vue Router,在 HTML 文件中添加以下代码:
  • 这种方式适合快速体验或在简单的项目中使用。
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

(3)通过 Vue CLI 安装

  • 如果你使用 Vue CLI 创建项目,在创建项目时可以选择安装 Vue Router。Vue CLI 会自动配置好 Vue Router 的基本设置。
vue create my-project
# 在创建项目时选择安装 Vue Router

但是如果你在创建vue项目的时候没有勾选router项,在这里可以按照第一种或者第二种方案进行安装。一般情况下,推荐使用 npm 安装的方式,因为这种方式可以更好地与构建工具(如 Webpack)集成,并且可以使用 ES6 语法。

2、App.vue写个标签

只需要在App.vue 写个标签,之后就不要再写任何其他东西了

<template>
<div id="app"><router-view></router-view></div>
</template>

3、在views里面创建页面组件

根据你的需求来创建不同的页面组件,为了下面的登录跳转案例,我在这里会创建IndexView LoginView两个页面组件,当登录成功时跳转到首页获取电影列表。

4、注册组件

接下来需要我们在在 router/index.js里面注册刚刚创建的页面组件

# 1 导入import LoginView from "@/views/LoginView";import IndexView from "@/views/IndexView";const routes = [# 2 注册路由{path: '/',name: 'home',component: IndexView},{path: '/login',name: 'login',component: LoginView},
]# 4 

5、完成

以后浏览器再次访问不同路径,就会根据不同的路由来切换相对应的页面组件

六、登录跳转案例

1、前期准备

(1)模块安装

  • 项目中使用axios 需要安装
cnpm install axios -S
  • 在要用的位置[注意导入的位置],
# 导入
import axios from 'axios'
# 使用
axios.get().then()

(2)跨域问题的解决

  • 使用pip安装
pip3 install django-cors-headers
  • 添加到setting的app中
 INSTALLED_APPS = (...'corsheaders',...)
  • 添加中间件
MIDDLEWARE = [  ...'corsheaders.middleware.CorsMiddleware',...
]
  • setting下面添加下面的配置
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = ('DELETE','GET','OPTIONS','PATCH','POST','PUT','VIEW',
)
CORS_ALLOW_HEADERS = ('XMLHttpRequest','X_FILENAME','accept-encoding','authorization','content-type','dnt','origin','user-agent','x-csrftoken','x-requested-with','Pragma','token'
)

(3)前端页面组件跳转

  • 在登陆成功时跳转到首页时候使用
this.$router.push('router/index.js/在index.js中配置过的路径')

2、后端

(1)models.py

from django.db import models
from django.contrib.auth.models import AbstractUserclass UserInfo(AbstractUser):# user表扩写字段需要加default或者null=Truegender = models.IntegerField(choices=((1, 'Male'), (2, 'Female'), (3, 'Other')), default=1)age = models.IntegerField(default=18)phone = models.CharField(max_length=11, null=True, blank=True)

(2)serializer.py

from rest_framework_simplejwt.serializers import TokenObtainPairSerializerclass LoginSerializer(TokenObtainPairSerializer):def validate(self, attrs):response = super().validate(attrs)user = self.userdata = {'code': 100, 'msg': '登录成功','username': user.username,'gender': user.get_gender_display()}data.update(response)return data

(3)views.py

import json
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIViewclass FilmView(APIView):def get(self, request):with open('./film.json', 'rt', encoding='utf-8') as f:res = json.load(f)return Response(res)

(4)urls.py

from django.contrib import admin
from django.urls import path
from rest_framework_simplejwt.views import token_obtain_pair
from app01 import viewsurlpatterns = [path('admin/', admin.site.urls),path('login/', token_obtain_pair),path('film/',views.FilmView.as_view())
]

(5)settings.py

AUTH_USER_MODEL = 'app01.userinfo'SIMPLE_JWT = {"TOKEN_OBTAIN_SERIALIZER": "app01.serializer.LoginSerializer",
}CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = ('DELETE','GET','OPTIONS','PATCH','POST','PUT','VIEW',
)
CORS_ALLOW_HEADERS = ('XMLHttpRequest','X_FILENAME','accept-encoding','authorization','content-type','dnt','origin','user-agent','x-csrftoken','x-requested-with','Pragma','token'
)REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'app01.exceptions.common_exception_handler',
}

3、前端

(1)router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入
import LoginView from "@/views/LoginView.vue";
import IndexView from "@/views/IndexView.vue";Vue.use(VueRouter)const routes = [// 注册路由{path: '/',name: 'index',component: IndexView},{path: '/login',name: 'login',component: LoginView},
]const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes
})export default router

(2)LoginView.vue

<template><div><h1>登录</h1><p>用户名:<input type="text" v-model="username"></p><p>密码:<input type="password" v-model="password"></p><p><button @click="handleSubmit">登录</button></p></div>
</template>
<script>javascript">
import http from "axios"export default {name: "LoginView",data() {return {username: '',password: ''}},methods: {handleSubmit() {// 发送ajax请求http.post('http://127.0.0.1:8000/login/', {username: this.username,password: this.password}).then(response => {if (response.data.code == 100) {// 跳转  vue-router支持的(重点)this.$router.push('/')} else {alert(response.data.msg)}})}}
}
</script>
<style scoped>
</style>

(3)IndexView.vue

<script>javascript">
import axios from 'axios'export default {name: "IndexView",data() {return {filmList: []}},created() {axios.get('http://127.0.0.1:8000/film/').then(res => {this.filmList = res.data.results}).catch(err => {alert('请联系系统管理员')})}
}
</script>
<template><div><h1>首页</h1><div v-for="film in filmList"><img :src="film.poster" alt="" height="200px" width="150px"><div><h3>{{ film.name }}</h3><p>主演:<span v-for="item in film.actors">{{ item.name }} &nbsp;&nbsp;</span></p><p>{{ film.nation }}|{{ film.runtime }}</p></div></div></div>
</template>
<style scoped>
h1 {background-color: aquamarine;
}
</style>

七、scoped的使用

在 Vue.js 中,<style> 标签中的 scoped 属性用于将样式限定在当前组件的作用域内,避免样式污染和冲突。这样做可以确保样式只适用于当前组件,而不会影响其他组件。以后项目中的css样式,都会写在vue组件的<style>标签中。

以下是一个简单的示例,演示了如何在 Vue 组件中使用 scoped 属性:

<template><div class="container"><h1>This is a scoped style example</h1><p>This is a paragraph with scoped style.</p></div>
</template><style scoped>
.container {background-color: lightblue;padding: 20px;
}h1 {color: blue;
}p {color: green;
}
</style>

在上面的示例中,<style scoped> 标签中的样式只会应用于当前组件内部的元素,而不会影响其他组件。这意味着即使你在其他组件中使用了相同的类名或标签名,也不会受到当前组件样式的影响。

八、问题

1、打开文件运行的流程

  • 在django的views.py 打开文件,打开文件的代码中写的文件路径,这个文件为什么要放在项目根路径?

因为真正运行的文件是manage.py,如果要打开文件,就得从项目运行的路径下开始找,而manage.py对应的正是项目根目录下。

class FilmView(APIView):def get(self, request):with open('./film.json', 'rt', encoding='utf-8') as f:res = json.load(f)return Response(res)

2、跨域问题

只要按照上面的处理跨域的步骤来写,以后不需要再响应头中加了允许跨域的键值对了,不论是post,还是delete,所有请求都没有跨域了


http://www.ppmy.cn/embedded/26041.html

相关文章

聚醚醚酮(Polyether Ether Ketone)PEEK在粘接使用时可以使用UV胶水吗?要注意哪些事项?

一般情况下&#xff0c;聚醚醚酮&#xff08;Polyether Ether Ketone&#xff0c;PEEK&#xff09;是一种难以黏附的高性能工程塑料&#xff0c;而UV胶水通常不是与PEEK进行粘接的首选方法。PEEK表面的化学性质和高温性能使得它对常规胶水的附着性较低。然而&#xff0c;有一些…

Postgresql 从小白到高手 十一 :数据迁移ETL方案

文章目录 Postgresql 数据迁移ETL方案1、Pg 同类型数据库2 、Pg 和 不同数据库 Postgresql 数据迁移ETL方案 1、Pg 同类型数据库 备份 : pg_dump -U username -d dbname -f backup.sql插入数据&#xff1a; psql -U username -d dbname -f backup.sqlpg_restore -U username…

HTML中input输入框(详解输入框的用法)

目录 一、input介绍 1.概念 2.好处 3.用法 4.应用 二、input语法 1.文本输入框 (type"text") 2.密码输入框 (type"password") 3.数字输入框 (type"number") 4.电子邮件输入框 (type"email") 5.复选框 (type"checkbox&…

面试准备之手写9种排序算法(默认从小到大排序)之插入排序、冒泡排序、选择排序、希尔排序

插入排序 第一重循环下标从1到n-1&#xff0c;一是表示插入轮数&#xff0c;而是为下一重循环nums[j]和nums[j - 1]比较并交换&#xff08;nums[j]>nums[j-1]时&#xff09;做准备&#xff0c;再有就是下一重循环是逆向进行&#xff0c;由于之前的下标在之前的循环中已经经…

如何使用 ArcGIS Pro 查找小区最近的地铁站

学习 GIS 除了可以用在工作上之外&#xff0c;还可以将其运用到生活之中&#xff0c;比如查找距离小区最近的地铁站&#xff0c;这里为大家介绍一下查找的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的POI数据&#xff0c;除了POI数据…

Stability AI 推出稳定音频 2.0:为创作者提供先进的 AI 生成音频

概述 Stability AI 的发布再次突破了创新的界限。这一尖端模型以其前身的成功为基础&#xff0c;引入了一系列突破性的功能&#xff0c;有望彻底改变艺术家和音乐家创建和操作音频内容的方式。 Stable Audio 2.0 代表了人工智能生成音频发展的一个重要里程碑&#xff0c;为质量…

linux安装MySQL 8.0笔记

在Linux系统中安装MySQL 8.0的详细操作步骤如下&#xff1a; 1. 添加MySQL Yum Repository 首先&#xff0c;您需要添加MySQL的Yum仓库。这可以通过下载并安装一个RPM包来实现&#xff0c;该RPM包会将MySQL仓库添加到您的仓库列表中。 wget https://repo.mysql.com//mysql80-c…

长难句打卡4.30

Priestly explains how the deep blue color of the assistant’s sweater descended over they ears from fashion shows to departments stores and to the bargain bin in which the poor girl doubtless found her garment. 普里斯特利则向助手解释了她身上这件针织衫所采…