vue3
一 Vue3的变化
1.性能的提升
-
打包大小减少41%
-
初次渲染快55%, 更新渲染快133%
-
内存减少54%
2、源码的升级
-
使用Proxy代替defineProperty实现响应式
-
重写虚拟DOM的实现和Tree-Shaking
3.拥抱TypeScript
Vue3可以更好的支持TypeScript
4.新的特性
1.Composition API(组合API)
- setup配置
- ref与reactive
- watch与watchEffect
- provide与inject
2.新的内置组件
- Fragment
- Teleport
- Suspense
3.其他改变
- 新的生命周期钩子
- data 选项应始终被声明为一个函数
- 移除keyCode支持作为 v-on 的修饰符
5 组合式API和配置项API
5.1 Options API 存在的问题
使用传统OptionsAPI中,新增或者修改一个需求,就需要分别在data,methods,computed里修改 。
5.2 Composition API 的优势
我们可以更加优雅的组织我们的代码,函数。让相关功能的代码更加有序的组织在一起。
6 项目分析
分析文件目录
main.js
Vue2项目的main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
看看vm是什么
const vm = new Vue({
render: h => h(App),
})
console.log(vm)
vm.$mount('#app')
我们再来看看Vue3项目中的main.js
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
我们来分析一下吧
// 引入的不再是Vue构造函数了,引入的是一个名为createApp的工厂函数
import { createApp } from 'vue'
import App from './App.vue'
// 创建应用实例对象——app(类似于之前Vue2中的vm,但app比vm更“轻”)
const app = createApp(App)
console.log(app)
// 挂载
app.mount('#app')
这里的app到底是啥,我们输出到控制台看看
App.vue
我们再来看看组件
在template标签里可以没有根标签了
<template>
<!-- Vue3组件中的模板结构可以没有根标签 -->
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>
二 创建Vue3.0工程
1.使用 vue-cli 创建
官方文档:https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-create
## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version
## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 创建
vue create vue_test
## 启动
cd vue_test
npm run serve
2.使用 vite 创建
官方文档:https://v3.cn.vuejs.org/guide/installation.html#vite
vite官网:https://vitejs.cn
介绍:https://cn.vitejs.dev/guide/why.html#the-problems
什么是vite?—— 新一代前端构建工具。
优势如下:
- 开发环境中,无需打包操作,可快速的冷启动。
- 轻量快速的热重载(HMR)。
- 真正的按需编译,不再等待整个应用编译完成。
传统构建 与 vite构建对比图
创建步骤
工具链,构建工具
-之前咱们再html中写,可能js可以引入
-可能写了一些 es高版本的语法----》转成低版本
-可能写 xx.vue,浏览器识别不了,浏览器只能识别:html,css,js
-咱们需要 有个东西可以一次性把 es高版本转成低版本,把xx.vue 转成xx.js的方式
-工具链:
webpack
vite
三、setup
setup是个函数,以后vue的代码,都写在这里面
1 里面可以定义变了
2 可以定义函数,可以定义匿名函数
3 如果想在templage中使用,必须return
4 如果要对变量加入响应式,需要使用ref包裹变量
5 data,methods都可以用,但是是setup函数先执行,才走其它
6 template中使用函数,变量,都优先用setup中的
7 setup最先执行,是再生命周期的beforeCreate前执行的,内部没有this,也不能用this了
-
setup为Vue3.0中一个新的配置项,值为一个函数
-
setup是所有Composition API(组合API)编写的位置
-
组件中所用到的:数据、方法等等,均要配置在setup中
-
setup函数的返回值:返回一个对象,对象中的属性、方法, 在模板中均可以直接使用
注意:
尽量不要与Vue2.x配置混用
- Vue2.x配置(data、methos、computed...)中可以访问到setup中的属性、方法。
- 但在setup中不能访问到Vue2.x配置(data、methos、computed...)。
- 如果有重名, setup优先。
<template>
{{name}}--{{age}}--{{xx}}
</template>
<script>
export default {
name: 'App',
data(){
return {
xx:this.name
}
},
setup(){
let name='lqz'
let age =19
return {
name,age
}
},
}
</script>
四、 ref函数
包裹变量,实现响应式
let name = ref('lqz')
<template>
<div class="home">
名字是:{{ name }},年龄是:{{ age }},爱好:{{ hobby }}
<br>
<button @click="handleAdd">点我涨年龄</button>
<br>
<button @click="handleChange">点击变名字</button>
</div>
</template>
<script>
// 导入ref函数
import {ref} from 'vue'
export default {
name: 'HomeView',
// 这样写支持
data() {
return {
// hobby: '篮球'
hobby: this.name + '爱打篮球'
}
},
methods: {
handleAdd() {
console.log('methods中的handleAdd')
}
},
// 以后我们写成这样,
setup() {
// 以后所有vue3的代码,都写在这里面
//原来写在data中定义变量
// 如果想在view中使用定义的变量,必须retur出去
// var:老语法 let:以后定义变量用这个 const :定义常量
// 1 定义变量,并再页面中渲染
// const name = 'lqz'
// const age = 19
// return {name,age}
// // return {name:name,age:age}
// 2 定义变量和函数,再页面中使用---->失去了响应式
// let name = 'lqz'
// let age = 19
// const handleAdd = () => {
// // alert('我被点了')
// // alert(add(4,5))
// age = age + 1
// console.log(age)
//
// }
//
// function add(a, b) {
// return a + b
// }
//
//
// return {name, age, handleAdd}
// 3 加入响应式
// let name = ref('lqz')
// let age = ref(19) // 他就变成了响应式
// const handleAdd = () => {
// console.log(age)
// console.log(typeof age)
// // age = age + 1
// // 以后需要用那个之,需要 对象.value才能取出来
// age.value = age.value + 1
// console.log(age)
//
// }
//
// const handleChange = () => {
// // name.value = '彭于晏'
// name.value = name.value+'nb'
// console.log(name)
// }
//
// return {name, age, handleAdd, handleChange}
// 4 研究一下,原来的data,methods还能不能用
let name = 'lqz'
let age = 19
// const handleAdd = () => {
// console.log('setup中的handleAdd')
// }
console.log('---',this)
return {name, age,}
}
}
</script>
五、 reactive函数
### 使用方式
let data = reactive({'name': 'lqz', 'age': 19, 'hobby': '篮球'})
const handelAdd = () => {
data.age += 1 // 使用reactive包裹的对象,直接当对象用即可
console.log(data)
}
return {data, handelAdd}
从定义数据角度对比:
ref用来定义:基本类型数据
reactive用来定义:对象(或数组)类型数据
从原理角度对比:
ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。
reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。
从使用角度对比:
ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。
reactive定义的数据:操作数据与读取数据:均不需要.value。
六、计算,监听属性
监听属性 就是使用watch,三种方式
# 1 方式一
// watch(name, (newValue, oldValue) => {
// console.log(oldValue)
// console.log(newValue)
// console.log('name 真的变了。。。。')
// })
# 2 监听属性之监听对象中的某个属性
let person = reactive({name: 'lqz', age: 19})
watch(() => person.name, () => {
console.log('person中的name变了')
})
const handleChanel = () => {
person.name = '刘亦菲'
}
# 3 同时监听多个变量
// const sum = ref(100)
// const msg = ref('很好')
// watch([sum, msg], (newValue, oldValue) => {
// console.log('sum或msg变化了', newValue, oldValue)
// })
计算属性 使用computed ,只有取值触发或取值赋值触发函数
1 基本使用
// let newName = computed(() => {
// return name.value + 'nb'
// })
2 了解:计算属性可以取值用,还可以改值
let newName = computed({
get() {
// 使用计算属性,会触发这里
return name.value + '=nb'
},
set(value) {
// 只要计算属性发生变化,就会执行这里
// 只要newName变了,name理应该也变,需要我们写代码变
let res=value.split('=')
name.value=res[0]
console.log('计算属性变了,变成', value)
}
七、生命周期
vue3不建议使用 配置项api,把所有代码都写在setup函数中
-以后没有:destory这俩了,换成了unmounted
-可以写配置项api(练习一下)
beforeCreate
created
beforeMoun
mounted
beforeUpdate
updated
beforeUnmount
unmounted
-但是不建议了(以后写组合式aip)
beforeCreate===>setup()
created=======>setup()
beforeMount ===>onBeforeMount
mounted=======>onMounted
beforeUpdate===>onBeforeUpdate
updated =======>onUpdated
beforeUnmount ==>onBeforeUnmount
unmounted =====>onUnmounted
八 toRef
...{对象}---》相当于解压
再setup函数中return时,使用return {...toRefs(data)},以后再templte中直接使用内层的变量即可
setup() {
console.log('执行了')
let a={hobby:'篮球',gender:'男'}
let b ={...a,name:'lqz'}
console.log(b)
var data = reactive({name: 'lqz', age: 19})
const handleClick = () => {
alert('美女')
}
const handleAdd=()=>{
data.age+=1
}
// ...toRefs(data) 等同于 {name:data.name,age:data.age}
// return {name: data.name, age: data.age, handleClick}
return {...toRefs(data),handleClick,handleAdd}
}
九 vue3 setup写法
<script setup>
// <script setup> 表示,这个script里的所有东西是setup函数,原来写在setup中的,现在顶格写即可
import {ref, toRefs} from 'vue'
import HelloWorld from '@/components/HelloWorld.vue'
let name = ref('lqz')
const handelClick = () => {
name.value = '彭于晏'
}
// watch,computed
// 生命周期钩子
// 组件导入,自动注册
// 不需要return
</script>