createApp
import { createApp } from "vue";import App from "./App.vue";createApp(App).mount("#app");
为什么
相比Vue2 new Vue()创建Vue实例,从同一个Vue构造函数创建的每个根实例共享相同的全局配置:
- 在测试阶段,全局配置很容易意外地污染其他测试用例
 - 全局配置使得在同一页面上的多个“app”之间共享同一个 Vue 副本非常困难,但全局配置不同。
 
在应用之间共享配置
在应用之间共享配置 (如组件或指令) 的一种方法是创建工厂功能,如下所示
import { createApp } from 'vue'import Foo from './Foo.vue'import Bar from './Bar.vue'const createMyApp = options => {const app = createApp(options)app.directive('focus', /* ... */)return app}createMyApp(Foo).mount('#foo')createMyApp(Bar).mount('#bar')//现在,Foo 和 Bar 实例及其后代中都可以使用 focus 指令。
组合式 API
为了更关注逻辑
setup() {// ref 是一个函数,它接受一个参数,返回的就是一个神奇的 响应式对象 。我们初始化的这个 0 作为参数包裹到这个对象中去,在未来可以检测到改变并作出对应的相应。const count = ref(0)const double = computed(() => {return count.value * 2})const increase = () => {count.value++}return {count,increase,double}}
为什么不用之前的组件的选项 data、computed、methods、watch 组织逻辑在大多数情况下都有效。然而,当我们的组件变得更大时,逻辑关注点的列表也会增长。这可能会导致组件难以阅读和理解,尤其是对于那些一开始就没有编写这些组件的人来说。而通过setup可以将该部分抽离成函数,让其他开发者就不用关心该部分逻辑了.
reactive
import { ref, computed, reactive, toRefs } from 'vue'interface DataProps {count: number;double: number;increase: () => void;}setup() {const data: DataProps = reactive({count: 0,increase: () => { data.count++},double: computed(() => data.count * 2)})const refData = toRefs(data)return {...refData}}
使用 ref 还是 reactive 可以选择这样的准则
- 第一,就像刚才的原生 javascript 的代码一样,像你平常写普通的 js 代码选择原始类型和对象类型一样来选择是使用 ref 还是 reactive。
 - 第二,所有场景都使用 reactive,但是要记得使用 
toRefs保证 reactive 对象属性保持响应性。toRefs()函数可以将reactive()创建出来的响应式对象,转换为普通对象,只不过这个对象上的每个属性节点,都是ref()类型的响应式数据
 
生命周期
- beforeCreate -> 不需要
 - created -> 不需要
 - beforeMount -> onBeforeMount
 - mounted -> onMounted
 - beforeUpdate -> onBeforeUpdate
 - updated -> onUpdated
 - beforeUnmount -> onBeforeUnmount
 - unmounted -> onUnmounted
 - errorCaptured -> onErrorCaptured
 - renderTracked -> onRenderTracked
 - renderTriggered -> onRenderTriggered
 
watch
// watch 简单应用watch(data, () => {document.title = 'updated ' + data.count})// watch 的两个参数,代表新的值和旧的值watch(refData.count, (newValue, oldValue) => {console.log('old', oldValue)console.log('new', newValue)document.title = 'updated ' + data.count})// watch 多个值,返回的也是多个值的数组watch([greetings, data], (newValue, oldValue) => {console.log('old', oldValue)console.log('new', newValue)document.title = 'updated' + greetings.value + data.count})// 使用 getter 的写法 watch reactive 对象中的一项watch([greetings, () => data.count], (newValue, oldValue) => {console.log('old', oldValue)console.log('new', newValue)document.title = 'updated' + greetings.value + data.count})
全局 API 修改
Vue2 的全局配置
import Vue from 'vue'import App from './App.vue'Vue.config.ignoredElements = [/^app-/]Vue.use(/* ... */)Vue.mixin(/* ... */)Vue.component(/* ... */)Vue.directive(/* ... */)Vue.prototype.customProperty = () => {}new Vue({render: h => h(App)}).$mount('#app')
Vue3 的修改
import { createApp } from 'vue'import App from './App.vue'const app = createApp(App)// 这个时候 app 就是一个 App 的实例,现在再设置任何的配置是在不同的 app 实例上面的,不会像vue2 一样发生任何的冲突。app.config.isCustomElement = tag => tag.startsWith('app-')app.use(/* ... */)app.mixin(/* ... */)app.component(/* ... */)app.directive(/* ... */)app.config.globalProperties.customProperty = () => {}// 当配置结束以后,我们再把 App 使用 mount 方法挂载到固定的 DOM 的节点上。app.mount(App, '#app')
