main.js 中的变化

vue3不存在构造函数

vue2的main.js

  1. import Vue from 'vue'
  2. import App from './App.vue'
  3. Vue.config.productionTip = false
  4. new Vue({
  5. render: h => h(App),
  6. }).$mount('#app')

vue3的main.js

  1. import { createApp } from 'vue'
  2. import App from './App.vue'
  3. import './index.css'
  4. createApp(App).mount('#app')

你会发现vue3中不存在构造函数Vue

vue3中使用插件

从上面你可以看出vue3中没有vue的构造函数,只有vue的实例对象来使用插件
示例代码

  1. import { createApp } from 'vue'
  2. import App from './App.vue'
  3. import './index.css'
  4. let app = createApp(App)
  5. console.log(app,'createApp')
  6. app.use('插件名')
  7. app.mount('#app')

组件中的变化

多个根元素

vue2 中使用的是单个根元素

  1. <template>
  2. <div id="app">
  3. <img alt="Vue logo" src="./assets/logo.png" />
  4. <HelloWorld msg="Welcome to Your Vue.js App" />
  5. </div>
  6. </template>

而vue3的可以使用多个根元素

  1. <template>
  2. <img alt="Vue logo" src="./assets/logo.png" />
  3. <HelloWorld msg="Hello Vue 3.0 + Vite" />
  4. </template>

组件中的this指向

来看一下代码在vue2与vue3中运行的差异
示例代码

  1. <template>
  2. <div>{{ count }}</div>
  3. <button @click="handleClick">click</button>
  4. </template>
  5. <script>
  6. export default {
  7. name: 'App',
  8. data(){
  9. return{
  10. count:0,
  11. }
  12. },
  13. methods:{
  14. handleClick(){
  15. console.log(this,"vue中的this")
  16. }
  17. }
  18. }
  19. </script>

vue2运行的效果图
image.png
vue3运行的效果图
image.png
你会发现到啦vue3中组件中打印的this是一个代理,而不是vue2组件中打印的vue实例
查看Proxy 中代理对象
image.png
你会发现很像vue2中的组件实例啦
这是为啥,看一张vue3的组件实例代理
vue3的组件实例代理.jpg
从上图就可以看出vue2与vue3的区别,vue3在组件实例上套一个代理对象那个,this指向就会指向组件代理对象

重点 option API 与 composition API

何为option API

  1. export default {
  2. name: 'App',
  3. components: {
  4. },
  5. data(){
  6. return{
  7. count:0,
  8. }
  9. },
  10. methods:{
  11. handleClick(){
  12. console.log(this,"vue中的this")
  13. }
  14. }
  15. }

如上面的代码这项就是配置式API也就是option API ,这种格式也就是我们vue2基础格式

option API 与 composition API的区别

option API的逻辑代码 composition API的逻辑代码
不需要看代码只需要看划分区域的颜色
option api.jpeg composition api.jpg
左图中你可以看出option API 中颜色非常混乱,这也就是导致逻辑非常混乱那吗后期维护与阅读起来非常困难,而大型项目中会出现复杂组件,这就会让vue2 开发复杂项目非常吃力,这就是配置式API的问题

代码还是一样的代码,当使用composition API 后如右图,它将他们合并到一起,这样就不会显的颜色混乱,不就是低耦合高内聚相同的东西堆积到一起,甚至可以将每个颜色区域的代码提出去做成模块,这就是option API与composition API 的区别
当其项目简单,只有一个功能,没多少代码时可以使用option API

何为composition API

API setup

官方解释为:
image.png
从官方的解释提取的重点

  • 自执行,setup函数在生命周期函数之前被调用
  • this 执行unfinished,无法通过this得到组件的实例
  • setup函数必须有返回值,返回值会被附着在组件实例里
  • 缺点:无法响应式

个人示例代码

  1. <template>
  2. <div>{{ count }}</div>
  3. <div>
  4. <button @click="increase">increase</button>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. name: 'App',
  10. /**
  11. * 自动自行
  12. * 当该组件中的属性被赋值完成执行,也就是说在所有生命周期函数之前调用
  13. */
  14. setup(){
  15. console.log(this) // this 指向unfinished的 无法通过this得到组件的实例
  16. console.log('所有生命周期钩子函数之前调用')
  17. let count = 0;
  18. const increase = ()=>{
  19. count++; //变量无法响应式
  20. }
  21. /**
  22. * 返回的东西会被附着在组件实例里
  23. */
  24. return {
  25. count,
  26. increase,
  27. }
  28. },
  29. beforeCreate(){
  30. console.log('beforeCreate') // 在setup函数之后执行
  31. }
  32. }
  33. </script>

效果图:变量无法响应式
vue3setup无法响应式数据.gif
可是使用API ref 来解决变量无法响应式,ref的用法看下方

API ref— 响应式变量

使用方法

  1. import { ref } from 'vue'
  2. const counter = ref(0)

setup 中的示例中变量无法响应式 使用API ref弥补该功能

  1. <template>
  2. <div>{{ count }}</div>
  3. <div>
  4. <button @click="count++">increase</button>
  5. </div>
  6. </template>
  7. <script>
  8. import { ref } from "vue";
  9. export default {
  10. name: 'App',
  11. setup(){
  12. console.log(this) // this 指向unfinished的 无法通过this得到组件的实例
  13. console.log('所有生命周期钩子函数之前调用')
  14. // 让其变量成为响应式
  15. let count = ref(0);
  16. /**
  17. * 返回的东西会被附着在组件实例里
  18. */
  19. return {
  20. count,
  21. }
  22. },
  23. beforeCreate(){
  24. console.log('beforeCreate')
  25. }
  26. }
  27. </script>

效果图
vue3setup变量响应式数据.gif

ref 重点

控制打印setup里的count
image.png
你会此时setup中count成为啦一个对象,其中有一个value值是一个访问器属性,那吗API ref干啦啥呢
ref 定义啦一个对象,对象中有个属性,该属性是一个访问器,读取时就返回该值,修改时,就重新渲染并触发响应式
那吗setup里的count是一个对象,那吗元素模板中为啥使用count,而不是count.value
我们查看一下元素上count 适合类型

  1. <div>{{ typeof count }}</div>

image.png
你会发现他是number类型
这是为啥???
vue3对ref的特殊处理.jpg
从上图可以看出,vue3对API ref 做出特殊处理,在setup里访问count,组件代理对象会去访问count.value
而元素模板上的count 访问的是组件实例中的count值,此时组件实例中count的是拆分过的

  • setup环境下(也就是写在setup函数内) count 是一个对象,需要是使用count.value 来获取修改值
  • 实例代理中(也就是在实例环境下,比如元素模板中),count 是一个count.value ,使用count就可以啦

示例

  1. <template>
  2. <div>{{ count }}</div>
  3. <div>{{ typeof count }}</div>
  4. <div>
  5. <button @click="increase">increase</button>
  6. </div>
  7. </template>
  8. <script>
  9. import { ref } from "vue";
  10. export default {
  11. name: "App",
  12. setup() {
  13. console.log(this); // this 指向unfinished的 无法通过this得到组件的实例
  14. console.log("所有生命周期钩子函数之前调用");
  15. // 让其变量成为响应式
  16. let count = ref(0);
  17. console.log(count, "count");
  18. // 单击事件
  19. const increase = () => {
  20. // 该事件写在setup环境下,此时count是一个对象,修改其值需要使用count.value
  21. count.value++;
  22. };
  23. /**
  24. * 返回的东西会被附着在组件实例里
  25. */
  26. return {
  27. count,
  28. increase,
  29. };
  30. },
  31. beforeCreate() {
  32. console.log("beforeCreate");
  33. },
  34. };
  35. </script>

注意:官方建议区分ref的值,在变量名后面添加ref,以此来区分正常变量与ref 的响应式变量