2 vue-cli
1 Vue-CLI 项目搭建
# 页面中写--》不好---》工程化---》vue是一个前端项目---》webpack支持---》vue官方提供了一个工具
# vue-cli:vue的脚手架,快速创建一个vue项目,带了很多文件
# 解释:
vue2 中,都是使用vue-cli
vue3中,可以使用vue-cli创建,官方更推荐使用 vite ,更快,更小
# Vue-CLI 是基于nodejs的
-nodejs:是一门后端编程语言
-js:前端运行在浏览器中,浏览器中有js的解释器,但是这个解释器只能运行在浏览器中,不能运行在操作系统之上
-于是就有人,把v8引擎,让它能够运行在操作系统之上+c语言写的:文件,网络,操作系统操作的代码
-nodejs:js语法,运行在操作系统上,后端语言
-跟python一样,是一个解释型语言---》解释器
-LTS:长期支持版本,https://nodejs.org/en/download/
# 搭建node环境
-下载相应平台的版本
-一路下一步,安装即可,自动加入环境变量(在任意位置都可以执行这俩命令)
-装完后会释放两个可执行文件
node: 等同于 python
npm: 等同于 pip
# 安装 vue-cli:脚手架
# pip install django ---》去国外下载很慢,npm也是很慢,加速
# 【可以不用】以后使用淘宝定制的cnpm替代npm,去淘宝镜像站下载,速度块
# 执行:
npm install -g cnpm --registry=https://registry.npm.taobao.org
# 这句话执行完了,以后,就有俩可以安装第三方模块的命令 npm:慢 cnpm:块
# 以后装任何第三方模块,建议使用cnpm,但是使用npm一样的,只是速度差距
cnpm install -g @vue/cli
# 使用vue脚手架,创建vue项目,装完脚手架,就会有个 vue 命令
vue create 项目名 # 注意路径
# 使用编辑器打开创建好的项目(pycharm)
# 另一种创建项目的方式
vue ui
1-1 vue2的创建方式1:





1-2 vue2的创建方式2:
vue ui





1-3 项目目录介绍
vue2_test # 项目名
node_modules # 类似于学的python的虚拟环境,主要放了,当前项目所有的以来,很多小文件,给别人发送项目需要把它删掉,如果删掉,执行命令 npm install 重新下载
public # 文件夹
favicon.ico # 网站小图标
index.html # 单页面应用(spa) <div id="app"></div>
src # 重点:文件夹,以后咱们的代码,都写在这里,js,组件,启动文件。。。
assets # 文件夹,放静态资源,图片,js,css
logo.png # 图片
components # 文件夹,内部放所有的小组件,非页面组件
HelloWorld.vue # 写了一个默认的HelloWorld的组件,是以 .vue结尾都
router # 文件夹,vue-router模块安装了就会有,主要做路由配置
index.js # vue-router的js文件
store # 文件夹,vuex模块安装了就会有,主要做vuex的配置
index.js # vuex的js文件
views # 文件夹,放组件,放页面组件
AboutView.vue # 关于的页面组件
HomeView.vue # 首页的页面组件
App.vue # 根组件 vm对象就是它,它管理了index.html的id为app的div
main.js # 整个入口,非常重要,很多全局配置。。。
.gitignore # git忽略文件相关
babel.config.js# babel的配置,咱们不用管
jsconfig.json # 不需要关注
package.json # 重要:项目依赖的所有第三方模块 等同于python中 requirements.txt
# 执行了 npm install -S axios,这里面就会多这一条
package-lock.json # 锁定版本
README.md # 项目介绍
vue.config.js # vue的配置文件 等同于 django中setting.py
1-4 项目的启动
-
方式1:在命令行中敲 --> npm run serve (注意在项目目录文件夹下)
-
方式2:在webstorm中

1-5 依赖包下载
# 依赖package.json文件
npm install
2 es6导入导出语法
# 写vue项目,大量的看到:他们是es6的导入和导出语法
import App from './App.vue'
export default{}
# 总结:
1 以后可以在任意位置写xx.js,可以定义变量,定义函数
2 导出某些变量,函数
export default {
name,print
}
2.1 默认导出和命名导出
#默认导出 不用名名字
export default {}
# 命名导出
export const a =10
3 在想用的地方导入
import 别名 form '路径' # . 和 ..
4 使用
别名.name
别名.print()
# 补充:如果一个包下有一个名为index.js 的文件,可以只导入到包这一层
import lqz from './lqz' # 简写成,index.js 可以省略,以后看到的index.js 等同于python的包中的__init__.py
lqz.showName()
3 前后端交互
3-1 axios与后端交互
# 1 安装
npm install -S axios
# 2 在想用的地方导入使用即可
import axios from 'axios'
# 3 使用发送请求即可
axios.get('http://127.0.0.1:8000/user/').then(res=>{
console.log(res)
this.name=res.data.name
this.age=res.data.age
})
# 解决跨域很多种:浏览器的同源策略
-1 后端使用cors技术
-2 使用nginx转发
-3 前端做代理:之上测试阶段使用,上线后没有
3-2 处理跨域
# 1 django中使用django-cors-headers,解决跨域
# 2 安装 pip3 install django-cors-headers
# 3 在app的注册中加入
INSTALLED_APPS = (
...
'corsheaders',
...
)
# 4 在中间件中加入
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
...
]
# 5 配置文件中加入
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'*'
)
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',
)
3-3 post请求携带数据
handleSubmit() {
axios.post('http://127.0.0.1:8000/user/', {
username: this.username,
password: this.password
}).then(res => {
console.log(res.data)
if (res.data.code == 100) {
// 登录成功跳转到百度
location.href = 'http://www.baidu.com'
} else {
alert(res.data.msg)
}
})
}
3-4 携带请求头
# 请求头中带token
handleSubmit1() {
axios.post('http://127.0.0.1:8000/user/',
{
username: this.username,
password: this.password
},
{
headers: {token: 'asdfasdfasd'}
}
).then(res => {
console.log(res.data)
if (res.data.code == 100) {
// 登录成功跳转到百度
location.href = 'http://www.baidu.com'
} else {
alert(res.data.msg)
}
})
}
# 这里的token需要跨域--> 将token接入到 CORS_ALLOW_HEADERS 列表中
4 props配置项指定默认值
# props是组件间通信,父传子,自定义属性时,子组件间中接收父组件中传入的数据使用的配置项
# 三种使用方式
//1 基本使用
// props: ['msg'],
// 2 属性认证,限制类型
// props:{
// msg:String // 接受的msg必须是string类型
// },
// 3 限定类型,限定必传,限定默认值
props: {
msg: {
type: String, //类型
required: false, //必要性
default: '老王' //默认值
},
xx:Boolean,
},
5 混入
# minxin 混入:可以把多个组件共用的配置提取成一个混入对象
# 提取混入对象
1 第一步:抽取共用的代码,定义混入 mixin的index.js下写了
export const hunhe = {
methods: {
handleShowName() {
alert(this.name)
}
},
}
2 第二步:注册混入,全局注册(只要注册了,所有组件都可以用)
// 全局注册混入,以后所有组件中都能用
import {hunhe} from '@/mixin'
Vue.mixin(hunhe)
3 第三步:注册混入,局部注册,在组件中注册了,这个组件可以用(在组件中)
import {hunhe} from "@/mixin";
mixins: [hunhe]
6 插件
# 插件功能:用于增强Vue,后期咱们学的vuex,vue-router,elementui都是基于插件的形式使用的
# 实现一个插件
1 定义一个插件,插件内部加入混入
import Vue from 'vue'
import axios from 'axios'
export default {
install(a) {
console.log(a) // a就是Vue对象
// 写代码,加入混入
Vue.mixin({
methods: {
handleShowName() {
alert(this.name)
}
}
})
// 在vue中放入变量
Vue.prototype.xxx='lxx is handsome'
// 在vue中放入函数
Vue.prototype.hello=()=>{
alert('hello')
}
// 通过插件,把axios对象放入vue实例上
Vue.prototype.$http=axios
// 还是自定义指令,或者组件
Vue.component('lxx', {
template: `
<div>
<h2>我是全局组件</h2>
</div>
`
})
}
}
2 应用插件 在main.js中
import plugins from './plugins'
Vue.use(plugins) // 自动调用插件内的install,完成对Vue的强化
3 使用
this.xxx
this.hello
this.$http
7 scoped样式
# 加载<style scoped> 表示写的样式,只在当前组件生效,不会影响到其他组件,造成污染
8 命名插槽的其他写法
# 1 默认插槽
# 2 具名插槽
# 3 使用v-slot:bottom指定命名插槽 建议使用这个(template不会渲染在dom上,而是直接渲染它下的子标签)
<template v-slot:bottom>
<form action="" >
<p>用户名:<input type="text"></p>
<p>密码:<input type="password"></p>
<button>登录</button>
</form>
<p>我是p标签</p>
</template>
9 项目中使用bootstrap,elementui
# 样子不好看,css用的少,ui组件库
# 使用bootstrap,vue不建议使用,可以用,建议用elementui,饿了么团队出的ui组件库
# 除了这个外,还有很多
-iView:https://www.iviewui.com/view-ui-plus/guide/introduce
-app端的ui组件库:http://vant3.uihtm.com/#/zh-CN/home
-很多其他
# elementui
9-1 elementui的使用步骤
# 1 安装 npm install element-ui -S
# 2 在main.js中引入
// 使用elemenui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI); // 使用插件,多出很多ui组件,全局的
# 3 在组件中使用,直接去官网复制代码,贴进去即可
注意复制全:templage,script,style内容
9-2 boostrap
# 1 安装
npm install jquery
npm install bootstrap@3
# 2 在main.js中引入
import 'bootstrap'
import 'bootstrap/dist/css/bootstrap.min.css'
# 3 使用jquery,在vue的配置文件中vue.config.js
const {defineConfig} = require('@vue/cli-service')
const webpack = require("webpack");
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
"window.$": "jquery",
Popper: ["popper.js", "default"]
})
]
}
};
# 4 以后在组件中直接使用bootsrtap的样式即可
10 localStorage和sessionStorage
# 前端存数据的地方
-cookie中:借助第三方插件,自己用js写
-sessionStorage:只要页面关闭,它就没了
-localStorage:永久存在,手动删除,或浏览器存满了、
# 通过这三个东西就可以实现组件间通信
# 使用:sessionStorage
sessionStorage.setItem('name', 'lqz')
sessionStorage.getItem('name')
sessionStorage.clear() // 清空
sessionStorage.removeItem('name')
# 使用:localStorage
localStorage.setItem('name', 'lqz')
localStorage.getItem('name')
localStorage.clear() // 清空
localStorage.removeItem('name')
11 vuex
# 插件:vuex,状态管理器,存取数据用的,可以跨组件通信(屏蔽了组件的父子关系)
# 使用
1 新建store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// 存数据的地方
state: {
sum: 0
},
// 厨师,真正的干货
mutations: {
JIA(state, value) {
state.sum += value
}
},
// 服务员,中转站
actions: {
jia(context, value) {
// context 上下文
// value 组件中调用时,传入的值
// 判断是否有权限改请求一下后端接口,获取了,有权限,
context.commit('JIA', value)
}
},
})
2 在main.js中使用
import store from './store'
new Vue({
router,
store, # 把store放在这里
render: h => h(App)
}).$mount('#app')
3 在任意组件中,想获取state中的数据
this.$store.state.变量 即可
4 在任意组件中修改数据
this.$store.dispatch("actions中定义的函数",参数)
它就会触发 actions中定义的函数 的执行,内部执行了 context.commit('JIA', value)
它又会触发 mutations中定义的函数执行,内部对sum进行了修改
5 在任意组件中修改数据也可以
this.$store.commit('JIA',2)

11 vue-router使用
# spa:单页面应用,很多页面组件,来回切换,借助于vue-router
# 使用
1 router下新建index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@/views/Home'
Vue.use(VueRouter)
// 这个地方注册路由,最重要的地方
const routes = [
{
path: '/home',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: About
},
{
path: '/login',
name: 'login',
component: Login
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
2 在main.js中注册
import router from './router'
new Vue({
router,
render: h => h(App)
}).$mount('#app')
3 写好一个个页面组件
Home.vue
About.vue
Login.vue
4 以后访问路径
http://192.168.1.5:8080/home 显示Home组件
http://192.168.1.5:8080/about 显示About组件
http://192.168.1.5:8080/login 显示Login组件
5 以后在任意组件中
this.$router,拿到的就是导出的router对象
13 Vue3介绍
# vue3 比 vue2好,性能提高了,支持ts语法,源码升级,多个一些新的api
# 重点:
组合式API(vue3) 和 配置项API(vue2)
# 学的所有vue2的东西,可以直接写在vue3上,完全支持
14 Vue3 项目创建
# 创建vue3的项目
-方式一:使用vue-cli创建
-跟创建vue2一模一样
-方式二:使用vite创建(不需要装任何东西)
## 创建工程
npm init vite-app vue3_test2
## 进入工程目录
cd vue3_test2
## 安装依赖
npm install
## 运行
npm run dev
15 常用api之setup
# vue3中不建议使用data来管理数据。使用setup
# setup 中可以写变量,写函数,只要reurn了,在模版中就可以使用
<template>
<!-- 组件不需要放在一个div标签内了 -->
<br>
<h2>{{name}}--->{{age}}</h2>
<button @click="handleAdd">点我年龄+1</button>
</template>
<script>
export default {
name: 'App',
components: {},
// 以后vue3不建议使用data,methods...(但还是可以用的)
// 建议使用setup,组合式api
setup(){
// 定义变量
let name = 'lkp'
let age = 19
// 定义函数
function handleAdd(){
age += 1 // 数据变了,数据没变(不是响应式,没有做绑定)
console.log(age)
}
// 要在模板中使用,return出去
return {
name,
age,
handleAdd,
}
}
}
</script>
16 常用api之ref和reactive
# 上面没有响应式:数据变,页面变,页面变数据变
# 基本数据类型使用ref包裹一下,使之变成响应式
在模版中直接使用
在setup中 使用对象.value获取真正的值
# 对象,数组类型,使用reactive包裹
模版中直接使用
<template>
<!-- 组件不需要放在一个div标签内了 -->
<br>
<h2>{{name}}--->{{age}}</h2>
<button @click="handleAdd">点我年龄+1</button>
<hr>
<h2>名字是:{{person.name}},年龄是:{{person.age}}</h2>
<button @click="handleChange">点我修改名字</button>
</template>
<script>
import {ref, reactive} from 'vue';
export default {
name: 'App',
components: {},
// 以后vue3不建议使用data,methods...(但还是可以用的)
// 建议使用setup,组合式api
setup(){
// 定义变量
let name = ref('lkp')
let age = ref(19)
let person = reactive({name:'刘亦菲', age: 33})
// 定义函数
function handleAdd(){
age.value += 1 // 加上ref后,数据变为对象了
console.log(age)
}
function handleChange(){
person.name = person.name + '?'
console.log(age)
}
// 要在模板中使用,return出去
return {
name,
age,
handleAdd,
person,
handleChange
}
}
}
</script>
17 计算和监听属性
# computed 配置项完成计算属性
# watch 配置项完成监听属性
以上的照常用
# 推荐使用组合式api
<template>
<!-- 组件不需要放在一个div标签内了 -->
<h2>{{fullName}}</h2>
<button @click="handleChange">点我修改姓</button>
<hr>
<h2>{{sum}}</h2>
<button @click="sum++">点我sum+1</button>
</template>
<script>
import {ref, reactive, computed, watch} from 'vue';
export default {
name: 'App',
setup(){
const sum = ref(10)
const person = reactive({firstName:'刘', lastName: '大帅'})
let fullName = computed(()=>{
return person.firstName + '-' + person.lastName
})
watch(sum, (newValue, oldValue)=>{
console.log('老数据', oldValue)
console.log('新数据', newValue)
})
let handleChange=()=>{
person.firstName="龙"
}
return {
person,
fullName,
handleChange,
sum
}
}
}
</script>
18 生命周期
# 生命周期变了
vue2 8个生命周期钩子函数
vue3 8个生命周期钩子函数,支持组合式api
beforeCreate===>setup()
created=======>setup()
beforeMount ===>onBeforeMount
mounted=======>onMounted
beforeUpdate===>onBeforeUpdate
updated =======>onUpdated
------下面的变了------
beforeUnmount ==>onBeforeUnmount
unmounted =====>onUnmounted
19 toRef
setup() {
const data = reactive({
name: '刘',
age: '清政',
isShow:false
})
// es6语法中的对象解压
return {
...toRefs(data) // 解压开,return了
// name:data.name,
// age:data.age,
// isShow:data.isShow,
}
}
<template>
<h2>{{name}}==>{{age}}==>{{isShow}}</h2>
</template>
<script>
import {reactive, toRefs} from 'vue';
export default {
name: 'App',
setup(){
const data = reactive({name: 'lkp', age:19, isShow:true})
return {
// es6语法,对象的解压
...toRefs(data)
}
}
}
</script>

浙公网安备 33010602011771号