赞
踩
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 )
cnpm install -g @vue/cli
vue create myfirstvue # 按下面步骤
npm run serve
这个错是因为文件夹权限不够,不要将创建的Vue项目放到任意盘的program files文件夹里,不然永远是这个错误,因为那个文件夹不能设置为完全控制,所有肯定会报权限不够的错误。
解决方案就是将项目放入一个自定义文件夹即可
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整体配置文件
// 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 = false new 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') */
<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>
在JavaScript中,let
、const
和var
是用于声明变量的关键字,它们在作用域、可变性和提升等方面有一些重要的区别。 在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围。
ES6 新增了let命令,用来声明局部变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。
var
是ES5及之前版本中用于声明变量的关键字。var
声明的变量存在函数作用域或全局作用域,而不存在块级作用域。var
声明的变量可以被重新赋值,并且可以在同一作用域内多次声明同一个变量。var
声明的变量会被提升(hoisting),即变量的声明会被提升到作用域的顶部,但赋值不会被提升。var x = 10;
if (true) {
var y = 20;
console.log(x); // 可以访问 x
console.log(y); // 可以访问 y
}
console.log(x); // 可以访问 x
console.log(y); // 可以访问 y,因为 var 变量会被提升
let
是ES6中引入的关键字,用于声明块级作用域的变量。let
声明的变量可以被重新赋值,但不能在同一作用域内重新声明。let
声明的变量不会被提升,只有在声明后才能访问。let x = 10;
if (true) {
let y = 20;
console.log(x); // 可以访问 x
console.log(y); // 可以访问 y
}
console.log(x); // 可以访问 x
console.log(y); // 会报错,y 在块级作用域外不可访问
const
也是ES6中引入的关键字,用于声明常量,常量的值一旦赋值就不能再改变。const
声明的变量也具有块级作用域。const PI = 3.14;
// PI = 3.14159; // 这里会报错,常量不可重新赋值
const person = {
name: 'Alice',
age: 30
};
person.age = 31; // 这是允许的,因为对象的属性可以修改
const
,如果变量的值需要变化,则使用let
,避免使用var
。let
和const
提供了更好的变量声明方式,有助于代码的可读性和可维护性,同时避免了var
可能导致的一些问题。let
声明变量时,如果变量的值会发生变化,但不需要重新声明变量,可以使用let
。const
声明常量时,如果变量的值不会改变,可以使用const
,这有助于提高代码的可读性和可维护性。“暂时性死区”(Temporal Dead Zone,简称 TDZ)是指在 ES6 中使用 let 或 const 声明变量时,变量存在但无法访问的区域。这种行为是为了在 JavaScript 中引入块级作用域而设计的。
在 JavaScript 中,使用 var 声明的变量在其声明语句之前就可以被访问,这种行为称为"变量提升"。而在使用 let 或 const 声明变量时,变量虽然存在于作用域中,但是在声明语句之前访问这些变量会导致引发 ReferenceError 异常。
暂时性死区的产生原因是,let 和 const 声明的变量在进入作用域时就已经被创建,并且被绑定到了该作用域中,但是在变量的声明语句之前,访问这些变量会进入暂时性死区,因为此时变量尚未初始化
(1)简化代码,使代码更简洁
(2)箭头函数内部,没有自己的this,它会使用上一级的this,解决了函数内部的this指向问题
(3)this指向问题:
console.log(this) # window 对象
函数调用
如果函数作为普通函数调用,this 指向全局对象(在严格模式下为 undefined)
如果函数作为对象的方法调用,this 指向调用该方法的对象。
构造函数
箭头函数
this
的值是在函数被调用时确定的,根据调用方式不同可能指向不同的对象。但是在箭头函数中,this
的值是在定义函数时确定的,它会捕获所在上下文的this
值,而不是在运行时改变。这种行为可以避免在回调函数中出现意外的this
指向问题,使得代码更加简洁和可读。DOM 事件处理函数:
ES6 类方法:
模板字符串是 JavaScript 中的一种特殊字符串,用反引号 ` (也称为反引号、重音符号或反引号字符)括起来。模板字符串可以包含多行文本和嵌入表达式,使用${}
语法插入表达式。这使得在字符串中嵌入变量、表达式或函数调用变得更加方便。举个例子:
const name = 'Alice';
const greeting = `Hello, ${name}!`;
console.log(greeting); // 输出: Hello, Alice!
在上面的例子中,${name}
是一个嵌入的表达式,它会被变量name
的值替换掉。模板字符串的这种特性使得动态生成字符串变得更加简单和直观。
解构赋值是一种在 JavaScript 中方便地从数组或对象中提取数据并赋值给变量的语法。它可以让你快速地将数组或对象中的值解构到单独的变量中。
在对象解构赋值中,花括号{}
里面放置的是要提取的属性名,而变量名则是接收对应属性值的变量名。
let user = {name: 'lqz', age: 19, hobby: '烫头'}
// 平常写法
let name=user.name
let age=user.age
// 解构赋值写法
let {name,age,hobby,a=10} = user
console.log(name,age,hobby,a)
在数组解构赋值中,方括号[]
里面放置的是要提取的元素位置,而变量名则是接收对应位置元素的变量名。同时**,...rest
的语法表示将剩余的元素赋值给rest
变量,这在需要获取数组中剩余元素时非常有用。**
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]
function getuserInfo() {
return {name: 'xiao', age: 19, hobby: ['烫头', '喝酒']}
}
let {name='1', hobby} = getuserInfo()
console.log(name, hobby) // 如果内部修改,优先返回值中的值
ES6 允许在函数参数中设置默认值,当调用函数时未提供参数时,将使用默认值
# 案例
function demo01(name,age=19) {
console.log(name,age)
}
demo01('xiao')
展开运算符 ...
可以将可迭代对象(如数组、字符串、对象)展开为多个参数或元素。也可以用于函数参数。
# 案例1:对象 let a={age:19,hobby:'打球'} let user={name:'xiao',age:20,...a} console.log(user) ''' Object age: 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] '''
在以后,做项目开发的时候,肯定要导入某些模块使用:
<script src=""></script>
import App from './App.vue'
语法引入默认导出允许一个模块只导出一个默认值。在一个模块中,你可以使用 export default
来导出默认值,然后在另一个模块中使用 import
语句来引入这个默认值。
示例:
// 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 } }
在导入默认导出时,你可以选择给导入的变量起一个名字,这个名字不必和导出时的名称相同。
<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>
默认导出适用于导出一个单一的值、对象、函数等,使得导入时更加简洁。
在 JavaScript 中,除了默认导出之外,还有一种常用的导出方式是命名导出(Named Export)。命名导出允许一个模块导出多个变量、函数或对象,这些导出的内容可以在导入时通过名称引用。
使用命名导出时,你可以在一个模块中通过 export
关键字导出多个变量、函数或对象,然后在另一个模块中通过名称引入这些导出。
示例:
// 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')
}
}
在导入命名导出时,需要使用花括号 {}
来指定要导入的内容,同时这些名称必须与导出时使用的名称相匹配。
// 第一种方式:花括号导入
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>
命名导出适用于导出多个变量、函数或对象,使得模块的功能更加灵活和可扩展。
__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>
<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>
单页面应用的字面意思就是只需要一个html页面就能实现页面跳转的效果,其本质就是组件的跳转。
那组件如何跳转?这就需要借助于第三方:vue-router 了
npm install vue-router
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
vue create my-project
# 在创建项目时选择安装 Vue Router
但是如果你在创建vue项目的时候没有勾选router项,在这里可以按照第一种或者第二种方案进行安装。一般情况下,推荐使用 npm 安装的方式,因为这种方式可以更好地与构建工具(如 Webpack)集成,并且可以使用 ES6 语法。
只需要在App.vue 写个标签,之后就不要再写任何其他东西了
<template>
<div id="app">
<router-view>
</router-view>
</div>
</template>
根据你的需求来创建不同的页面组件,为了下面的登录跳转案例,我在这里会创建IndexView LoginView两个页面组件,当登录成功时跳转到首页获取电影列表。
接下来需要我们在在 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
以后浏览器再次访问不同路径,就会根据不同的路由来切换相对应的页面组件
cnpm install axios -S
# 导入
import axios from 'axios'
# 使用
axios.get().then()
pip3 install django-cors-headers
INSTALLED_APPS = (
...
'corsheaders',
...
)
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
...
]
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' )
this.$router.push('router/index.js/在index.js中配置过的路径')
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
# user表扩写字段需要加default或者null=True
gender = 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)
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class LoginSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
response = super().validate(attrs)
user = self.user
data = {'code': 100, 'msg': '登录成功','username': user.username,'gender': user.get_gender_display()}
data.update(response)
return data
import json
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView
class FilmView(APIView):
def get(self, request):
with open('./film.json', 'rt', encoding='utf-8') as f:
res = json.load(f)
return Response(res)
from django.contrib import admin
from django.urls import path
from rest_framework_simplejwt.views import token_obtain_pair
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', token_obtain_pair),
path('film/',views.FilmView.as_view())
]
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', }
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
<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> 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>
<script> 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 }} </span> </p> <p>{{ film.nation }}|{{ film.runtime }}</p> </div> </div> </div> </template> <style scoped> h1 { background-color: aquamarine; } </style>
在 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>
标签中的样式只会应用于当前组件内部的元素,而不会影响其他组件。这意味着即使你在其他组件中使用了相同的类名或标签名,也不会受到当前组件样式的影响。
因为真正运行的文件是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)
只要按照上面的处理跨域的步骤来写,以后不需要再响应头中加了允许跨域的键值对了,不论是post,还是delete,所有请求都没有跨域了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。