main.js 中的变化
vue3不存在构造函数
vue2的main.js
import Vue from 'vue'import App from './App.vue'Vue.config.productionTip = falsenew Vue({render: h => h(App),}).$mount('#app')
vue3的main.js
import { createApp } from 'vue'import App from './App.vue'import './index.css'createApp(App).mount('#app')
vue3中使用插件
从上面你可以看出vue3中没有vue的构造函数,只有vue的实例对象来使用插件
示例代码
import { createApp } from 'vue'import App from './App.vue'import './index.css'let app = createApp(App)console.log(app,'createApp')app.use('插件名')app.mount('#app')
组件中的变化
多个根元素
vue2 中使用的是单个根元素
<template><div id="app"><img alt="Vue logo" src="./assets/logo.png" /><HelloWorld msg="Welcome to Your Vue.js App" /></div></template>
而vue3的可以使用多个根元素
<template><img alt="Vue logo" src="./assets/logo.png" /><HelloWorld msg="Hello Vue 3.0 + Vite" /></template>
组件中的this指向
来看一下代码在vue2与vue3中运行的差异
示例代码
<template><div>{{ count }}</div><button @click="handleClick">click</button></template><script>export default {name: 'App',data(){return{count:0,}},methods:{handleClick(){console.log(this,"vue中的this")}}}</script>
vue2运行的效果图
vue3运行的效果图
你会发现到啦vue3中组件中打印的this是一个代理,而不是vue2组件中打印的vue实例
查看Proxy 中代理对象
你会发现很像vue2中的组件实例啦
这是为啥,看一张vue3的组件实例代理
从上图就可以看出vue2与vue3的区别,vue3在组件实例上套一个代理对象那个,this指向就会指向组件代理对象
重点 option API 与 composition API
何为option API
export default {name: 'App',components: {},data(){return{count:0,}},methods:{handleClick(){console.log(this,"vue中的this")}}}
如上面的代码这项就是配置式API也就是option API ,这种格式也就是我们vue2基础格式
option API 与 composition API的区别
option API的逻辑代码 composition API的逻辑代码
不需要看代码只需要看划分区域的颜色

左图中你可以看出option API 中颜色非常混乱,这也就是导致逻辑非常混乱那吗后期维护与阅读起来非常困难,而大型项目中会出现复杂组件,这就会让vue2 开发复杂项目非常吃力,这就是配置式API的问题
代码还是一样的代码,当使用composition API 后如右图,它将他们合并到一起,这样就不会显的颜色混乱,不就是低耦合高内聚相同的东西堆积到一起,甚至可以将每个颜色区域的代码提出去做成模块,这就是option API与composition API 的区别
当其项目简单,只有一个功能,没多少代码时可以使用option API
何为composition API
API setup
官方解释为:
从官方的解释提取的重点
- 自执行,setup函数在生命周期函数之前被调用
- this 执行unfinished,无法通过this得到组件的实例
- setup函数必须有返回值,返回值会被附着在组件实例里
- 缺点:无法响应式
个人示例代码
<template><div>{{ count }}</div><div><button @click="increase">increase</button></div></template><script>export default {name: 'App',/*** 自动自行* 当该组件中的属性被赋值完成执行,也就是说在所有生命周期函数之前调用*/setup(){console.log(this) // this 指向unfinished的 无法通过this得到组件的实例console.log('所有生命周期钩子函数之前调用')let count = 0;const increase = ()=>{count++; //变量无法响应式}/*** 返回的东西会被附着在组件实例里*/return {count,increase,}},beforeCreate(){console.log('beforeCreate') // 在setup函数之后执行}}</script>
效果图:变量无法响应式
可是使用API ref 来解决变量无法响应式,ref的用法看下方
API ref— 响应式变量
使用方法
import { ref } from 'vue'const counter = ref(0)
setup 中的示例中变量无法响应式 使用API ref弥补该功能
<template><div>{{ count }}</div><div><button @click="count++">increase</button></div></template><script>import { ref } from "vue";export default {name: 'App',setup(){console.log(this) // this 指向unfinished的 无法通过this得到组件的实例console.log('所有生命周期钩子函数之前调用')// 让其变量成为响应式let count = ref(0);/*** 返回的东西会被附着在组件实例里*/return {count,}},beforeCreate(){console.log('beforeCreate')}}</script>
ref 重点
控制打印setup里的count
你会此时setup中count成为啦一个对象,其中有一个value值是一个访问器属性,那吗API ref干啦啥呢
ref 定义啦一个对象,对象中有个属性,该属性是一个访问器,读取时就返回该值,修改时,就重新渲染并触发响应式
那吗setup里的count是一个对象,那吗元素模板中为啥使用count,而不是count.value
我们查看一下元素上count 适合类型
<div>{{ typeof count }}</div>

你会发现他是number类型
这是为啥???
从上图可以看出,vue3对API ref 做出特殊处理,在setup里访问count,组件代理对象会去访问count.value
而元素模板上的count 访问的是组件实例中的count值,此时组件实例中count的是拆分过的
- setup环境下(也就是写在setup函数内) count 是一个对象,需要是使用count.value 来获取修改值
- 实例代理中(也就是在实例环境下,比如元素模板中),count 是一个count.value ,使用count就可以啦
示例
<template><div>{{ count }}</div><div>{{ typeof count }}</div><div><button @click="increase">increase</button></div></template><script>import { ref } from "vue";export default {name: "App",setup() {console.log(this); // this 指向unfinished的 无法通过this得到组件的实例console.log("所有生命周期钩子函数之前调用");// 让其变量成为响应式let count = ref(0);console.log(count, "count");// 单击事件const increase = () => {// 该事件写在setup环境下,此时count是一个对象,修改其值需要使用count.valuecount.value++;};/*** 返回的东西会被附着在组件实例里*/return {count,increase,};},beforeCreate() {console.log("beforeCreate");},};</script>
注意:官方建议区分ref的值,在变量名后面添加ref,以此来区分正常变量与ref 的响应式变量
