相干库版本要求
- 脚手架 Vue CLI
v4.5
或 Vite - Vue Router
v4.0
- Vuex
v4.0
- Element Plus 地址:https://element-plus.gitee.io…
- Ant Design
v2.0
地址:https://2x.antdv.com/ -
可能须要手动装置的 插件
@vue/compiler-sfc
^3.0.7- …
构建
npm i -g @vue/cli
vue create <Project Name> // 抉择装置配置后实现
// 或者采纳可视化构建形式
vue ui
迁徙
将所有库更新到反对 Vue3
的版本后,执行 npm i
装置依赖,接下须要手动更改各项 API 调用以及插件的装置形式。
全局 API 的更换
入口文件 main.js
:
// Vue2.x,vue 实例形式为应用 Vue 构造函数实例化
import Vue from 'vue'
import App from './App.vue'
import router from '@/router'
new Vue({
router,
render: h => h(App)
}).$mount('#app')
// Vue3.0,调用 createApp 办法创立实例
import {createApp} from "vue"; // 从 vue 模块引入的不再是一个构造函数,而是一个对象
import App from './App.vue'
import router from "@/router";
const app = createApp(App);
app
.use(router)
.mount("#app");
路由 @/router/index
// 联合 Vue2.x 版本的 router 创立形式是基于构造函数 Router 的实例化,并
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router) // 须要调用 构造函数 Vue 的静态方法 use 装置一次,将 router 提供的办法和属性挂载到 Vue 原型上
const router = new Router({...})
// Vue3.0,同样相似的形式,vue-router 模块裸露进去的为一个对象而不再是一个构造函数,须要调用外面的 createRouter 办法创立 router
import {createRouter} from "vue-router";
// 无需再调用 Vue.use 装置插件
const router = createRouter({routes:[...]
})
Vuex @/store/index.js
// Vue2.x 装置形式
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({...})
// Vue3.0 装置形式
import {createStore} from "vuex";
const store = createStore({...});
Vue.prototype
=> app.config.globalProperties
Vue2.x 最罕用的全局变量设置是通过在构造函数 Vue
的原型上挂上罕用的属性和办法
let someProps = 'some things'
Vue.prototype.$someProps = someProps
// 组件中拜访
console.log(this.$someProps); // 'some things'
// 通过原型拜访
import Vue from 'vue'
console.log(Vue.prototype.$someProps); // 'some things'
比照 Vue3.0 应用 app.config.globalProperties
main.js
import {createApp} from 'vue'
const app = createApp()
let someProps = 'some things'
app.config.globalPropertis.$someProps =someProps
...
export defaul app; // 须要将 app 实例裸露进来
// 通过调用 API 获取以后实例拜访全局 property
import {getCurrentInstance} from "vue";
const currentInstance = getCurrentInstance(); // 获取以后实例
console.log(currentInstance.appContext.config.globalProperties)
// 组件中通过 this 拜访 全局 property
// SomeComp.vue
console.log(this.$someProps) // 'some things'
// 通过引入实例拜访
import app from '@/main.js'
console.log(app.config.globalProperties.$someProps); // 'some things'
留神: 通过引入实例拜访是须要与我的项目的 app 根实例建立联系,而并非从新创立 app 实例,因而在 main.js
入口文件处要将 app 对外裸露。
Provide / Inject
跨层级组件传值个别不用用全局属性时,能够思考到 provide
/ inject
// Provide.vue
import {provide} from "vue";
setup() {
let str = "provide str";
provide("str", str);
}
// Inject.vue
import {inject} from "vue";
setup() {let injectStr = inject("str");
console.log(injectStr); // 'provide str'
}
组件注册
// Vue2.x 注册形式
import Vue from 'vue'
import someComp from './someComp.vue'
Vue.component('SomeComp',someComp)
// 比照 Vue3.x 注册
import {createApp} from 'vue'
import someComp from './someComp.vue'
const app = createApp()
app.component('SomeComp',someComp)
自定义插件装置
// somePlugin.js
export default {install(Vue,config){
...
Vue.prototype.$pluginHandler = ()=>{...}
}
}
// main.js
import Vue from 'vue'
import somePlugin from './somePlugin.js'
Vue.use(somePlugin)
比照 Vue3.0
// somePlugin.js
export default {install(app){
// 通过参数 app 传递实例的援用
...
app.config.globalProperties.$pluginHandler = ()=>{...}
}
}
// main.js
import {createApp} from 'vue
import somePlugin from './somePlugin.js'
const app = createApp()
app.use(somePlugin)
小结
全局 API 组织形式的重构(由从原型上共享改为以模块裸露)的益处:
- 联合 Treeshaking 和便于打包工具确定依赖关系,将无用的内容去除,按需输出,失去体积更小的生产包。
- 在须要不同的独立的 Vue 实例场景下,以在原型上操作的形式,仍然会使不同实例之间内容产生分割,因而取代的新形式将实现这种隔离。
新个性
组合式 API setup
Vue2.x 组件构造可能会相似如下:
// src/components/SomeComp.vue
export default {data:()=>({res1:[],
res2:[],
res3:[]}) ,
methods: {handler1(){
// ...
// 解决失去数据并赋值给 res1
},
handler2(){
// ...
// 解决失去数据并赋值给 res2
},
handler3(){
// ...
// 解决失去数据并赋值给 res3
}
},
}
官网给图:
Vue3.0 应用 setup
将相干逻辑组织在一块,便于解读、保护。
export default {setup(props,context){
// ---------- 业务逻辑 1 ------------
const res1 = ref([])
const handler1 = ()=>{
// ...
// 解决失去数据并赋值给 res1
}
// ---------- 业务逻辑 2 ------------
const res2 = ref([])
const handler2 = ()=>{
// ...
// 解决失去数据并赋值给 res2
}
// ---------- 业务逻辑 3 ------------
const res3 = ref([])
const handler3 = ()=>{
// ...
// 解决失去数据并赋值给 res3
}
// ------- 将属性裸露给组件 ---------
return {
res1,
handler1,
res2,
handler2,
res3,
handler3
}
}
}
在 setup
中注册 生命周期钩子
可将须要在某个生命周期执行的办法,在对应的钩子注册办法通过回调传入,届时会在对应的生命周期所触发。
import {onBeforeMount, onMounted} from 'vue'
export default {setup(){onBeforeMount(()=>{conosle.log('onBeforeMount')
})
onMounted(()=>{conosle.log('onMounted1')
})
onMounted(()=>{conosle.log('onMounted2')
})
}
}
watch
、computed
新的用法
import {watch , computed} from 'vue'
export default {
props: {
someProp: {default: () => 0,
type: Number,
},
},
setup(props) {const { someProp} = toRefs(props);
watch(someProp, (newValue) => {console.log(newValue);
});
let computedVal = computed(() => someProp.value * 10);
return {computedVal,};
}
};
响应性 API
reactive
以援用类型的数据创立一个响应式对象,即以组件data()
返回的对象创立响应式的原理。ref
以根底类型的数据创立响应式对象,并会将原始值包裹在一个对象的value
属性下。(测试发现其实也能够依据援用类型创立,但响应性不高)toRefs
将响应式对象转换为一般对象(不便解构获取值),并且后果中的每个property
放弃对响应式对象的指向。若不必该办法转换,取到的值将不具备响应性,也不为ref
。
import {reactive, ref} from "vue";
export default {setup() {
// let num = 0; // 视图不更新
let num = ref(0); // 视图更新
setInterval(() => {num.value++}, 500);
// let obj = {num: 0}; // 视图不更新
let obj = reactive({num: 0}); // 视图更新
setInterval(() => {
obj.num++;
console.log(obj); // 数据更新
}, 500);
// let {time} = foo; // 视图不更新
let {time} = toRefs(foo);
setInterval(() => {time.value = Date.now();
console.log(time.value === foo.time); // true
}, 1000);
return {
num,
obj
};
}
};
异步更改响应式对象进行视图更新时,须要留神:将 已裸露的属性 指向 新的响应式对象 是有效的操作,要响应则须要间接对 在 setup 阶段裸露的响应式对象 进行操作。
import {reactive, ref} from "vue";
export default{setup(){let arr = reactive([])
setInterval(()=>{// arr = [1,2,3] // 不更新
// arr = reactive([1,2,3]) // 不更新
arr.push(1,2,3) // 更新
},1000)
// 或者外面包一层,并在该对象在属性节点上进行从新指向的形式
let obj = reactive({arr:[]
})
setInterval(()=>{obj.arr = [1,2,3] // 更新
},1000)
// 但在第二种形式下,以构造的形式拜访属性尽管没有问题,但勿在解构赋予的变量上做雷同的错误操作。例如:let {arr} = obj
setInterval(()=>{arr = reactive([1,2,3]) // 模板上的 {{arr}} 是 obj.arr,此时指向了新的响应式对象,因而不会更新
},1000)
export {
arr,
obj
}
}
}