# Vue3的变化 # 1.性能的提升 打包大小减少41% 初次渲染快55%, 更新渲染快133% 内存减少54% # 2.源码的升级 使用Proxy代替defineProperty实现响应式 重写虚拟DOM的实现和Tree-Shaking # 3.拥抱TypeScript Vue3可以更好的支持TypeScript # 4.新的特性 Composition API(组合API) setup配置 ref与reactive watch与watchEffect provide与inject 新的内置组件 Fragment Teleport Suspense 其他改变 新的生命周期钩子 data 选项应始终被声明为一个函数
# 组合式api 都写到一个函数中,定义变量和定义方法,定义计算属性都是放在一起,不是拆到不同的地方 # 配置项api:之前vue2中的写法 new Vue({ data:{ name:'lqz' }, methods:{ # 使用变量 } })
# vue3的app实例 也是个对象,但是以后我们使用东西,不是从this中拿了,this当没了 # vue2的app实例 就是咱们再组件中用的this this.$store this.$refs.... # 以后真正的vue3的语法,写法可能变了
### vue3 完全兼容vue2 ### # vue 3 项目创建有两种方式 -vue-cli -vue create vue_cli_test -路由选择,选择vue3即可 -跟之前创建vue2是一样的 -vite:vue_vute_test npm init vue@latest 按下图选择 下载好之后 需要先npm install # 工具链,构建工具 -之前咱们再html中写,可能js可以引入 -可能写了一些 es高版本的语法----》转成低版本 -可能写 xx.vue,浏览器识别不了,浏览器只能识别:html,css,js -咱们需要 有个东西可以一次性把 es高版本转成低版本,把xx.vue 转成xx.js的方式 -工具链: webpack vite
![096376eab3015b61bde8616a0ec88c6](C:\Users\ADMINI~1\AppData\Local\Temp\WeChat Files\096376eab3015b61bde8616a0ec88c6.png)
# setup是个函数 以后vue的代码 都写在这里面 1.里面可以定义变量 2.可以定义函数,可以定义匿名函数 3.如果想在template中使用,必须return 4.如果要对变量加入响应式,需要使用ref包裹变量 5.data,methods都可以用,但是是setup函数先执行,才走其他 6.template中使用函数,变量,都是优先用setup中的 7.setup最先执行,是再生命周期的beforeCreate前执行的,内部没有this,也不能用this了
// 包裹变量 实现响应式 let name = ref('xxx') <template> <div class="home"> 名字是:{{ name }},年龄是:{{ age }},爱好:{{hobby}} <br> <button @click="handleAdd">点我涨年龄</button> <hr> <button @click="handleChange">点击变名字</button> </div> </template> <script> // 导入ref函数 import {ref} from "vue"; export default { name: 'HomeView', // 这样写还是支持 data() { return { // name: 'xxx', // age: 18, // hobby:'足球', hobby:this.name + '爱打篮球' } }, methods: { handleAdd() { console.log('methods中的handleAdd') } }, // 以后写成这个形式 setup(){ // 以后所有vue3的代码 都写在这里面 // 原来写在data中定义变量 // 如果想在view中使用定义的变量,必须return出去 // var--老语法 let--以后定义变量用这个 const--定义常量 // 1 定义变量,并再页面中渲染 // let name = 'xxx' // let age = 19 // return {name,age} // 2 定义变量和函数,在页面中使用----->失去了响应式 // let name = 'xxx' // let age = 19 // const handleAdd = ()=>{ // // alert('我被点了') // age += 1 // console.log(age) // } // return {name,age,handleAdd} // 3 加入响应式 // let name = ref('xxx') // let age = ref(18) // 用ref包裹着就变成了响应式 // const handleAdd = () => { // console.log(age.value) // // 以后需要用哪个值 就对象.value才能取出来 // age.value = age.value + 1 // } // const handleChange = ()=>{ // name.value = 'zzz' // // name.value = name.value + 'nb' // console.log(name) // } // return {name,age,handleAdd,handleChange} // 研究一下,原来的data,methods还能不能用 let name = 'xxx' let age = 19 console.log('---',this) return {name,age} } } </script>
# 使用方式 let data = reactive({'name': 'xxx', '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
<template> <div class="home"> <h1>首页</h1> <!-- 名字是:{{name.value}}--> 名字是:{{data.name}}-----年龄是:{{data.age}} <button @click="handleAdd">点我加年龄</button> </div> </template> <script> import {ref,reactive} from "vue"; export default { name: 'HomeView', setup(){ // 1 要让变量有响应式 要用ref包裹一下,包裹的都是字符串,数字,布尔 // js中再使用这个变量取值赋值是要 变量名.value才能拿到 // template中使用变量不要用 .value // let name = ref('xxx') // name.value = 'zzz' // return {name} // 2 如果想让对象有响应式 reactive let data = reactive({'name':'xxx','age':19,'hobby':'足球'}) const handleAdd = () => { data.age += 1 } return {data,handleAdd} } } </script>
### 监听属性 就是使用watch 三种方式 # 1 方式一 // 1.监听属性之监听普通属性 // let name = ref('xxx') // const handleClick = () => { // name.value = 'zzz' // } // // vue3的写法 // watch(name,(newValue,oldValue)=>{ // console.log(oldValue) // console.log(newValue) // console.log('name 真的变了') // }) # 2 监听属性之监听对象中的某个属性 // let person = reactive({name:'xxx',age:19}) // watch(()=>person.name,()=>{ // console.log('person中的name变了') // }) // const handleClick = () => { // person.name = 'zzz' // } // return {person,handleClick} # 3 同时监听多个变量 let sum = ref(100) let msg = ref('很好') watch([sum,msg],(newValue,oldValue)=>{ console.log('sum或msg变化了', newValue, oldValue) }) const handleClick = () =>{ sum.value = 200 } return {sum,msg,handleClick} ### 计算属性 使用computed 只有取值触发或取值赋值触发函数 # 1 基本使用 // 1 原来写法照常使用 // let name = ref('') // let newName = computed(()=>{ // return name.value + 'nb' // }) // return {name,newName} # 2 了解:计算属性可以取值用,还可以改值 let name = ref('') let newName = computed({ get(){ // 使用计算属性 会触发这里 return name.value + '=nb' }, set(value){ // 只要计算属性发生变化 就会执行这里 // 只要newName变了 name理应也变 需要我们写代码变 let res = value.split('=') name.value = res[0] console.log('计算属性变了,变成',value) } }) return {name,newName}
# 8个生命周期钩子 # vue3不建议使用 配置项api 把所有代码都写在setup函数中 以后没有:beforedestory和destory这俩了,换成了unmounted 可以写配置项api beforeCreate created beforeMoun mounted beforeUpdate updated beforeUnmount unmounted ### 但是不建议了(以后写组合式aip) import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount, onUnmounted, reactive} from 'vue' setup(){ // 生命周期钩子 // beforeCreate===>setup() // created=======>setup() // beforeMount ===>onBeforeMount // mounted=======>onMounted // beforeUpdate===>onBeforeUpdate // updated =======>onUpdated // beforeUnmount ==>onBeforeUnmount // unmounted =====>onUnmounted let t = setInterval(()=>{ console.log('hello world') },3000) onBeforeUnmount(()=>{ console.log('onBeforeUnmount') clearInterval(t) t = null }) onUnmounted(()=>{ console.log('onUnmounted') }) }
// ...{对象}----》相当于解压 // 在setup函数中return时,使用return {...toRefs(data)},以后在template中直接使用内层的变量即可 import {toRefs} from "vue"; setup(){ // let a = {hobby:'足球',gender:'男'} // let b = {...a,name:'zzz'} // let c = {...toRefs(a),name:'zzz'} // console.log(b) // {hobby: '足球', gender: '男', name: 'zzz'} // console.log(c) // {hobby: ObjectRefImpl, gender: ObjectRefImpl, name: 'zzz'} let data = reactive({name:'xxx',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,handleAdd} return {...toRefs(data),handleClick,handleAdd} },
<script setup> // <script setup> 表示,这个script里的所有东西是setup函数,原来写在setup中的,现在顶格写即可 import {ref} from "vue"; let name = ref('xxx') const handleClick = () => { name.value = 'zzz' } // watch,computed // 生命周期钩子 // 组件导入,自动注册 // 不需要return </script>