main.js 中的变化
vue3不存在构造函数
vue2的main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new 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.value
count.value++;
};
/**
* 返回的东西会被附着在组件实例里
*/
return {
count,
increase,
};
},
beforeCreate() {
console.log("beforeCreate");
},
};
</script>
注意:官方建议区分ref的值,在变量名后面添加ref,以此来区分正常变量与ref 的响应式变量