昨日回顾

# 1 props
-不需要在data中定义了,他就在当前组件对象身上了 this
-props:[]
-props:{name:String}
-props:{name:{require:,default:...}} # 2 组件间通信
-1 父子:父传子 ,自定义属性
-2 子传父,自定义事件
-3 ref属性
-4 localStorage,sessionStorage,cookies
-5 vuex # 3 插件 --> 使用第三方插件(vue-router,vuex,elementui)
-导入
-Vue.use(elementui)----> install(){} -自定义插件:
-xx.js 中 export default{
install(vue){
1 自定义指令
2 往vue中放全局 Vue.prototype.$axios=axios
3 执行minxin
4 全局组件
}
} # vuex:状态管理器,vue存数据的地方,跨组件间通信
-vue2使用版本是vuex3
-vue3使用版本是vuex4
-npm install vuex@3
-三个状态:
state:真正存数据的
mutations:修改state的地址 state.变量名,修改即可
actions:判断,跟后端交互,调用mutations的地方 context.commit -在组件中使用
-模板中: {{$store.state.变量名}}
-js中:
-直接用:this.$store.state.变量名
-调用mutations:this.$store.commit('mutations')
-正常套路:触发actions,this.$store.dispatch() # vue-router -vue-router:3版本对应vue2,4版本对应vue3 -单页面应用:index.html,以后都是页面组件间的切换,借助于vue-router -使用步骤:
-1 基本使用,router/index.js---->routes,加对象 {},加入路径后,访问这个路径就显示指定的组件
-2 跳转到不同的页面
-js控制:this.$router.push('路径') ,可以写个对象
-标签控制:<router-link to属性=路径>,也可以写个对象
-3 跳转到别的页面传参数
-?name=lqz&age=19 取:this.$route.query.name
-/books/1/ index.js 中配置路由,取:this.$route.params.id -路由嵌套:routes内部对象中写: children ---》/goods/list -路由跳转:
-html中跳转:router-link to属性 可以之间写字符串路径,数据绑定对象{}
-js跳转:this.$router.push('goods') -跳转携带数据:
-get地址中参数:this.$route.query.参数名
-路由中分割出来的参数:this.$route.params.【router/index.js的routes使用:绑定的】 -路由守卫:
-进入该路径之前,进行一些逻辑判断,允许进还是不允许
-权限的控制
-router.beforeEach()
-router.afterEach()
-全局路由守卫
-前置守卫
-后置守卫 -前置守卫
router.beforeEach((to, from, next) => {
// 1 取出cookie中token
// 2 判断如果不是login页面,from对象,就是路由对象,判断一下,如果是,next()
// 3 如果不是,判断token的值是否为空,如果为空,弹窗,跳转到login
// router.push({name: 'login', params: {id: 99}})
// router.push('/login/88')
next({name:'login',params:{id:33}})
}) - localStorage,sessionStorage,cookie
-cookie:借助于第三方 vue-cookies

今日内容

1 vue3介绍

# 1 vue项目的版本,新项目使用vue3,有部分老项目使用vue2

# vue3 的变化
1.性能的提升
打包大小减少41%
初次渲染快55%, 更新渲染快133%
内存减少54%
2.源码的升级
使用Proxy代替defineProperty实现响应式
重写虚拟DOM的实现和Tree-Shaking
- Tree-Shaking:摇晃树 --> 掉树叶
意思就是将代码中不用的部分给删掉了
3.拥抱TypeScript
Vue3可以更好的支持TypeScript
4.新的特性
Composition API(组合API) 最新的特性
setup配置
ref与reactive
watch与watchEffect
provide与inject
新的内置组件
Fragment
Teleport
Suspense
其他改变
新的生命周期钩子 换了名字
data 选项应始终被声明为一个函数
移除keyCode支持作为 v-on 的修饰符 5 组合式API和配置项API
vue2 :配置项API
new Vue({
el:'#app',
data:{}
}) vue3: 组合式API
setup(){
let name='lqz'
let add=()=>{
}
return {name, add}
}

组合式api:

2 创建vue3项目的两种方式

# vue-cli:创建vue2和vue3
-跟之前一样
# vite:创建vue3,创建最新
npm init vue@latest
# Pinai
# vite创建另一种方式:创建vue3.0.4版本
npm init vite-app <project-name>
## 进入工程目录
cd <project-name>
## 安装依赖
npm install
## 运行
npm run dev # 启动的两种方式 # 以后再页面中的this,已经不是vue2中的vc对象了,是一个代理对象

vue-cli创建Vue3项目

# 创建跟之前vue2 一样,只是选择vue版本的时候,选择vue3

# 创建完成,使用pycharm打开,并运行

# eslint是什么?
类似python的PEP8编码规范。而且不符合规范时,项目无法编译。 # history模式

补充说明,history模式:

history风格的router在这里:

npm run serve本质执行的是package.json中的如下:

可以改名字:

main.js

create(app)创建一个Vue对象。

Vue3建议不使用配置项api,推荐使用组合式api。

Vite创建Vue3项目

# 新建的前端构建工具,最大的优势就是速度快
https://cn.vuejs.org/guide/scaling-up/tooling.html#project-scaffolding # 使用步骤:
- 安装 :npm init vue@latest
- 按需选择,vueRouter
- cd到项目中执行cnpm install 把依赖装好
- 运行:npm run dev - vueRouter:跟之前一样
- Pinia:用来替换Vuex的,新一代的状态管理器
- 链式调用 # 在Vite创建的项目里使用Vuex:
1.在Vite项目新建目录和文件 store/index.js
2.将Vue3项目中的 store/index.js文件的代码复制到Vite创建的store/index.js中。
3.在Vite项目的main.js注册插件
import vuex from './stores/index'
const app = createApp(App)
app.use(vuex) -index.js:
import { createStore } from 'vuex' export default createStore({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
}) # 为什么这么快
-创建项目快----》不安装第三方依赖
-执行项目,热更新----》按需编译

Vite的优点:特点速度快

创建项目:

添加vue rounter:

使用pinia(vuex5)做状态管理:

继续按照图片配置:

不懂的就选择NO。

Vue3目录结构

main.js:

Vite项目没有下第三方依赖:还需要下依赖

项目运行命令也发送了变化:

npm run dev

Vite的优点

访问哪个页面,就编译哪个页面,也就是只有用的时候才会进行编译。而不是每次都编译整个项目的所有页面。

3 setup函数

# vue 新增的setup配置项函数,
-在里面可以定义变量
-定义函数
-必须return 变量和函数,在模板中才能使用

Vue3创建实例和Vue2的区别

# vue2的创建vue实例和vue3创建vue实例的区别

	-new Vew()---->是Vue的实例,里面有$store,$refs...
-createApp(App)--->是个对象,对象里有东西,没有$store,$refs...,以后有用,都是导入使用 # 以后vue3 的<template>,里面不需要写一个div标签了 # 以后都写在setup函数中,定义变量,定义函数,一定要return,在template中才能使用 # 失去了响应式

Vue3:

Vue2:

查看Vue3 app对象:

查看Vue2 Vue实例:

总结:Vue2会创建Vue的实例,里面有$store...Vue3创建的就是一个对象,不再是Vue的实例了。总的来说,Vue3就是为了不使用this。以后使用都是导入使用。

还有区别,Vue3的template不需要只写在一个div里面了。

使用组合式api,核心就是setup函数。以后都在setup函数中写组合式api。

示例:

在setup申明变量:

需要return返回出去一个对象:

点击按钮年龄加一:

怎么使用setup中的数据,直接用即可,无需使用this。修改setup中定义的数据,页面并不会变化,因为没有做数据和页面的双向绑定,失去了响应式。

<template>
<h2>{{ name }}</h2>
<h3>{{ age }}</h3>
<button @click="handleClick">点我看美女</button>
<br>
<button @click="handleAdd">点我,age+1</button>
</template> <script> export default {
name: 'App',
setup() { // setup中没有this了
// 以后所有的变量定义函数编写,都写在这个函数中
// 定义变量 如果这么写,变量渲染没问题,但是没有响应式,页面变了,变量不会变
let age = 19
let name = 'lqz'
// 定义函数
function handleClick() {
alert('美女~~~')
}
let handleAdd = () => {
console.log('我要开始加了')
age=age+1
console.log(age)
}
// 函数必须有返回值
return {
age, name, handleClick, handleAdd
} }
}
</script>

4 ref和reactive

# 导入使用:import {ref, reactive} from 'vue'

# 有响应式
-以后定义变量,如果想有响应式就用 ref 包裹起来,再修改变量,需要用 变量名.value 修改 # 配置项api和组合式api可以混写,不建议
-在前在data中定义的变量
-在setup中定义的变量 -总结:
在setup中定义的变量和函数,在之前配置项api中可以直接使用this.变量,函数调用即可
但是在原来配置项中定义的变量,函数,在setup中无法使用 # 不同类型做响应式
ref通常用来包裹,数字,字符串类型,以后使用 xx.value
reactive用来包裹数组和对象类型 以后使用 直接用即可 # 总结
ref定义的数据:
操作数据需要.value,读取数据时模板中直接读取不需要.value。
reactive定义的数据:
操作数据与读取数据:均不需要.value # Vue2和Vue3的响应式区别
响应式会降低速度,直接渲染较快。通过ref来自定义哪些变量需要响应式,哪些变量无响应式。而Vue2是监听所有变量,比较消耗资源。

ref

想要实现数据和页面的双向绑定,需要使用ref.

先导入ref:

这里age变成了ref对象:

真正的值在value中。

如何实现响应式:

实现名字后面加?:

配置项api和组合式api可以一起写,但是不建议:

在setup中定义的变量和函数,在之前配置项api可以直接使用this获取这些变量和函数。但是这个this不是原来的this了 。

reactive

申明对象时:

使用ref包一下。

需要使用value来修改值:

ref对象通过点value可以获取到proxy代理对象。

使用reactive:

可以直接修改:

如果使用插值语法渲染,直接将变量名放在template就行了。

<template>
<h2>{{ name }}</h2>
<h3>{{ age }}</h3>
<br>
<button @click="handleAdd">点我,age+1</button>
<br>
<button @click="handleChangeName">点我name变化</button>
</template> <script> import {ref, reactive} from 'vue' export default {
name: 'App',
setup() {
let age = ref(19) // age 已经不是数字了,是RefImpl的对象
let name = ref('lqz')
let handleAdd = () => {
console.log('我要开始加了,age是', age)
age.value = age.value + 1
console.log('我要开始加了,age是', age.value)
}
function handleChangeName(){
name.value=name.value+'?'
console.log(name)
} return {
age, name, handleClick, handleAdd,handleChangeName
} }
}
</script>

5 计算和监听属性

5.1 计算属性

# computed 的配置项中的写法,不建议用了
computed:{
fullName(){
return this.firstName+this.lastName
}
}, # vue3 新写法
let person = reactive({
firstName: '',
lastName: '',
})
let fullName = computed(() => {
return person.firstName + person.lastName
}) # 计算属性取值和修改值
let fullName = computed({
get() {
return person.firstName + person.lastName
},
set(value) {
person.firstName = value.slice(0, 1)
person.lastName = value.slice(1)
},
})

准备:

使用计算属性:

之前的写法:(不建议使用,还是可以用)

现在的写法:

需要导入computed函数。

换一种写法:

计算属性反向改值

修改计算属性的值,反向修改变量。

获取属性触发get,修改属性触发set。

修改计算属性时,反向修改变量:

value是计算属性经过修改之后的值。

export default {
name: 'App',
// computed:{
// fullName:function (){}
// },
setup() {
// 1 计算属性案例1
// let firstName = ref('刘')
// let lastName = ref('清政')
// // 定义计算属性
// let fullName = computed(() => {
// return firstName.value + lastName.value
// }) // 2 计算属性案例2
let person = reactive({
firstName: '刘',
lastName: '清政',
})
// 定义计算属性
person.fullName = computed({
get() {
return person.firstName + '-' + person.lastName
},
set(value) {
console.log(value)
const nameArr = value.split('-')
person.firstName = nameArr[0]
person.lastName = nameArr[1] }
})
return {
person
} }
}

5.2 监听属性

# 组合式api写法,只要name发生变化,就会触发匿名函数执行
let name = ref('lqz')
watch(name, (newName, oldName) => {
console.log('name变了')
console.log('老的', oldName)
console.log('新的', newName)
}) # watchEffect 用法,只要age变化,就会执行,age不变化,就不会执行
watchEffect(() => {
console.log(age.value)
})

watch也需要导入。

只要变量变化,触发匿名函数执行:

查看前端:

watchEffect

只要里面使用到的变量发送了变化,这个匿名函数就会执行。

代码:

import {computed, watch, ref, reactive, watchEffect} from 'vue'

export default {
name: 'App',
setup() {
// 1 计算属性案例1
let name = ref('lqz') // 定义监听属性
watch(name, (newValue, old) => {
console.log('name变了')
// console.log(old)
// console.log(newValue)
})
// vue3 多的watchEffect,只要函数中使用的变量发生变化,它就会触发
watchEffect(() => {
// 只要该函数中使用的变量发生变化,它就会触发
// let a = name.value + '?'
console.log('watchEffect配置的回调执行了')
})
return {
name
} }
}

6 生命周期

# Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有两个被更名:
- vue2 vue3
beforeCreate ===> beforeCreate
created ===> created
beforeMount ===> beforeMount
mounted ===> mounted
beforeUpdate ===> beforeUpdate
updated ===> updated
beforeDestroy ===> beforeUnmount
destroyed ===> unmounted beforeDestroy ===改名为===> beforeUnmount
destroyed ===改名为===> unmounted # Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:
beforeCreate ===> setup()
created ===> setup()
beforeMount ===> onBeforeMount
mounted ===> onMounted
beforeUpdate ===> onBeforeUpdate
updated ===> onUpdated
beforeUnmount ===> onBeforeUnmount
unmounted ===> onUnmounted # 以前写在created中的代码,现在直接写在setup开始即可
let show = ref(false)
axios.get().then(res=>{
show.value=res.data.show
})

setup在beforeCreate之前执行。

准备:在组件中写生命周期钩子函数

导入:

查看:

不推荐配置项写法,将生命周期函数统统写在setup中:

页面一加载,向后端发送请求:

直接在setup中间写。

7 hooks

# 什么是hook?——
本质是一个函数,把setup函数中使用的Composition API进行了封装。
类似于vue2.x中的mixin。
自定义hook的优势: 复用代码, 让setup中的逻辑更清楚易懂

7.1 hook/usePoint.js

import {onMounted, onUnmounted, reactive} from "vue";

export default function () {
let p = reactive({
x: 0,
y: 0
}) function getPoint(event) {
console.log(event)
p.x = event.pageX
p.y = event.pageY
} // 声明周期钩子的onMounted,当页面挂载就会执行
onMounted(() => {
// 给数鼠标点击增加监听,当点击鼠标,就会执行这个函数
window.addEventListener('click', getPoint)
})
// 组件被销毁时,把功能去掉
onUnmounted(() => {
window.removeEventListener('click', getPoint)
}) return p
}

7.2 在想使用的组件中引入使用即可

<template>
<h2>x坐标是:{{ p.x }},y坐标是:{{ p.y }}</h2>
</template> <script>
import {reactive, onMounted, onUnmounted} from 'vue'
import usePoint from '../hook/uesPoint.js' export default {
name: "Point",
setup() {
let p = usePoint()
return {p}
}
} </script> <style scoped> </style>

8 toRefs

# 以后setup的返回值可以直接使用
setup() {
let data = reactive({
name: 'lqz',
age: 19,
gender: '男'
})
return {...toRefs(data)}
}
# 以后在模板中直接用 {{name}}
export default {
name: 'App', setup() {
let data = reactive({
name: 'lqz',
age: 19,
isShow: true
}) function handleShow() {
console.log('ssdaf')
data.isShow = !data.isShow
data.age++
} return {
...toRefs(data),
handleShow
// data
} }
}

使用torefs:

在前端无需使用data.name,这种方式使用插值:

...toRefs(data)解构赋值,相当于;

只使用...:

9 script setup的作用和lang=ts

<script setup>
import {ref} from 'vue'
let name = ref('lqz')
let handleClick = () => {
alert('美女')
}
</script> # 以后 这个script中的代码直接放到 setup函数中,不用return了 #lang=ts
里面代码使用ts写,而ts完全兼容js,继续写js代码没问题

Vue3高版本,可以在script标签中直接定义变量,会自动放入setup函数中:

导入组件后无需注册直接使用:

以后都不需要导入导出组件了。

支持ts代码;

查看elementui写的Vue3:

父传子需要使用defineProps接受:

10 后台管理模板

# vue-admin-template-master
-跑起来
-package.json 第7行加入
"dev": "set NODE_OPTIONS=--openssl-legacy-provider & vue-cli-service serve",
-网址:github.com/PanJiaChen/Vue-admin-template # java版的若依
带权限控制的后台管理模块 ---前端---> vue-element-admin # python :
django-vue-admin ---前端---> D2Admin # python flask-vue-admin # go:gin-vue-admin # element前端 + Vue rbac后台管理
https://gitee.com/liuqingzheng/vue_admin
https://gitee.com/liuqingzheng/rbac_manager

练习

#  创建vue3项目,在setup中写看美女案例
# 练习监听属性和计算顺序
# 从后端接口拿数据展示在页面上
-------------------------------------
# app

随机图片

<template>
<h1 class="text-center">随机美女图片</h1>
<div class="text-center">
<img @click="" :src="default_img" alt="" style="width: 300px"> </div>
<br>
<div class="text-center">
<button @click="startFunc" class="btn btn-success ">点我开始随机</button> <!-- 当没有给函数传参时,会把点击事件传进来 -->
<button @click="stopFunc" class="btn btn-success ">点我停止随机</button>
</div> </template> <script setup>
import {ref, reactive} from 'vue' let imgList = reactive(['https://img2.woyaogexing.com/2022/10/23/af963193e9fb67ee!400x400.jpg',
'https://img2.woyaogexing.com/2022/10/22/95afdd5cd39d556d!400x400.jpg',
'https://img2.woyaogexing.com/2022/10/21/f06c65142fe50c19!400x400.jpg',
'https://img2.woyaogexing.com/2022/10/20/c0135f7e74050a74!400x400.jpg',])
let default_img = ref('https://img2.woyaogexing.com/2022/10/20/c0135f7e74050a74!400x400.jpg')
let timeTool = null function stopFunc() {
clearInterval(timeTool)
timeTool = null
} function startFunc() {
if (timeTool === null) { // 第二次点击的时候timeTool不为null,而是存放一个定时器。
timeTool = setInterval(() => {
let i = Math.floor(Math.random() * imgList.length)
default_img.value = imgList[i]
}, 20)
}
} </script> <style scoped> </style>

监听属性和计算属性

<template>
<input type="text" v-model="userInput">
<input type="text" v-model="cuteName">
</template> <script setup>
import {watch, ref, computed} from "vue"; let userInput = ref('') let cuteName = computed({
get() { // 调用计算属性时会触发
if (userInput.value.length === 0) {
return ''
} else {
return '= = cute--->' + userInput.value
}
}, // 修改、设置计算属性时会触发,value是修改之后的值
set(value) {
userInput.value = ''
},
}) watch(userInput, (newName, oldName) => { // 每次修改userInput都会触发该函数
if (newName.length >= 8) {
alert('= = 你输入的名字好长')
}
}
) </script> <style scoped> </style>

与后端交互

<template>
<h2>serverView</h2>
<h2>{{ show }}</h2>
</template> <script setup>
import axios from 'axios'
import {ref} from "vue"; let show = ref('')
axios.get('http://127.0.0.1:8000/api/v1/movies/').then(res => {
show.value = res.data
})
</script> <style scoped> </style>

【vue3】创建vue3项目的两种方式 setup函数 ref和reactive 计算和监听属性 生命周期 hooks toRefs script setup的作用和lang=ts 后台管理模板的更多相关文章

  1. vue3介绍-vue3创建项目-setup函数-ref和reactive-计算属性和监听-生命周期-toRefs-script setup的作用和lang=ts-vue后台管理模板

    目录 vue3介绍-vue3创建项目-setup函数-ref和reactive-计算属性和监听-生命周期-toRefs-script setup的作用和lang=ts-vue后台管理模板 昨日内容回顾 ...

  2. 创建Django项目的两种方式

    有两种方式可创建django项目: 方式一:命令行 1. cmd 命令行,进入到指定的目录,执行:django-admin startproject mydiary [mydiary 为项目名],创建 ...

  3. Eclipse中构建maven项目的两种方式

    Eclipse中构建maven项目的两种方式 方式一: 1.构建maven项目 1.1 新建meven项目,可在Other中找到maven文件夹 1.2 进入maven项目后,点击next 1.3 在 ...

  4. 创建安卓模拟器的两种方式及常用Android命令介绍

    创建安卓模拟器有以下两种方式: 1>通过图形界面创建,在Eclipse中单击Windows->Android Virtual Device Manager启动图形界面窗口 2>如果用 ...

  5. 创建Java多线程的两种方式和线程异常

    一.使用多线程的两种方法  使用多线程的两种方法有:继承Thread类和实现runable接口. 二.继承Thread类 来看一下thread类的源代码: class Thread implement ...

  6. git创建项目的两种方式

    场景1: 将本地内容推送给远程库 1.创建版本库 git init 将此目录转换为git可管理的仓库 git config --global user.name "xx" 或 gi ...

  7. Linux部署springboot项目,两种方式

    部署jar包(官方推荐) 在linux服务器上运行Jar文件时通常的方法是: $ java -jar test.jar 这种方式特点是ssh窗口关闭时,程序中止运行.或者是运行时没法切出去执行其他任务 ...

  8. Java进阶知识16 Spring创建IOC容器的两种方式

    1.直接得到 IOC 容器对象 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app ...

  9. JS定义函数的两种方式:函数声明和函数表达式

    函数声明 关于函数声明的方式,它的一个重要的特性就是函数声明提升(function declaration hoisting),意思是在执行代码之前会先读取函数声明.这就意味着可以把函数声明放在调用它 ...

  10. 【java并发】传统线程技术中创建线程的两种方式

    传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式 ...

随机推荐

  1. HTTP响应状态码([RFC9110])

    本内容翻译自[RFC9110]15. Status Codes,不足之处请自行查阅文档. 15. 状态码 响应的状态码是一个三位整数代码,用于描述请求的结果和响应的语义,包括请求是否成功以及附带了什么 ...

  2. LOG日志系统

    # coding=utf-8 import datetime import logging import os import sys from logging.handlers import Time ...

  3. String.trim()含义

    就是去除两端空格,目前只用到了这个.

  4. Vue入门(1)安装vue环境,创建Vue2 Vue3的项目并且安装IIS环境和发布到IIS

    Vue环境的搭建 一.     背景 vue的运行方式有两种 一种是在页面引用vue的js包, 一种是搭建脚手架来vue框架. 我们在这里使用的是第二种方式. 需要安装的软件 npm 16.13.1 ...

  5. [QOJ1359] Setting Maps

    题目链接 \(k=1\) 的时候显然是最小割.把一个点 \(u\) 拆成 两个点,中间连流量为 \(c_u\) 的边. 那么考虑扩展到 \(k\) 更大的情况.把上图的每个入点和出点都拆成 \(k\) ...

  6. [ARC161F] Everywhere is Sparser than Whole (Judge)

    Problem Statement We define the density of a non-empty simple undirected graph as $\displaystyle\fra ...

  7. 8 HTTP 的请求方法

    目录 标准请求方法 GET/HEAD GET 方法 HEAD方法 POST/PUT POST PUT 非常用方法 DELETE 方法 CONNECT 方法 OPTIONS 方法 TRACE 方法 拓展 ...

  8. jenkins pipeline语法、自动生成、部署案例

    Jenkins Pipeline是一套插件,支持在Jenkins中实现持续集成和持续交付: pipeline的编写都要写入到一个名为Jenkinsfile的文件中. 流水线脚本管理 Jenkinsfi ...

  9. cache操作:clean、invalidate与flush的含义

    前言 本文试图搞清楚cache几个操作:clean.invalidate与flush的含义.由于只用过ARM和RISC-V,所以是从ARM和RISC-V的角度来说明. cache line cache ...

  10. Python——第五章:csv模块

    未来我们会使用爬虫获取到一些json文件,例如去英雄联盟官方爬取英雄的数据库 查看代码 {"hero":[{"heroId":"1",&qu ...