vue的初始化改了:
// 旧版
let vm = new Vue({
el: '#app',
data: {}
})
// 新版,且data必须为function了
createApp({
data() {
return {}
}
}).mount('#app')
常用部分的改动
新增部分:vue3新增的最大亮点就是新加了setup,几乎替代了data,methods,mounted等生命周期,且setup中无法访问this
新增了setup函数,用于减少数据的冗杂。但个人感觉就是把其他地方的数据统一放到了setup中。
<template> <!-- 或者使用$emit给父级传值 --> <button @click="$emit('toFather', '传给父级的值')"></button> </template> import {toRefs, ref} from 'vue' export default{ porps: ['msg', 'obj'], // setup接受2个参数 // props:即上面的props,且因为是响应式,不接受es6的解构,如果希望解构,则使用vue提供的toRefs方法 // context: setup(props, context) { // 如果想通过解耦取props的值,则需要用toRefs,如果或者props.msg.value直接取值 const {obj} = toRefs(props); // 通过toRefs方法的数据如果要取值需要.value,这是因为vue3采用了Proxy console.log(obj.value); // 变量声明的方法改变了, // 需要通过ref来 // 且需要在外面import引入ref, // 且声明的变量的取值需要xx.value, // 且要实现像data中一样暴露声明的变量,需要在setup中return出去 // 比如:我声明一个变量name,需要用ref,ref中放初始值 const name = ref(''); // 如果我想要获取我声明变量的值,则需要: console.log(name.value); // '' // 如果我想要对外暴露,则需要return出去: return { name } } }
新增了$attr,它是props的加强版,且包含方法,具体可以看下面:
参考资料:vue3 组件传值之 props 与 attrs 的区别
// Father.vue <template> <div> <Son :msg="message" @toFather="getMsgFromSon" @qita="ck" :onQita="ck" @qita2="ck"></Son> </div> </template> <script> import Son from './Son.vue' import {ref} from 'vue' export default { name: "Father", components: { Son, }, setup() { const message = ref('信息'); const getMsgFromSon = (val) => { console.log(val) }; const ck = () => { console.log(1) }; return { message, getMsgFromSon, ck } } } </script> <style scoped> </style> // Son.vue <template> <div> <span>{{msg}}</span> <button @click="clickFn">按钮</button> <button @click="onQita2">按钮2</button> </div> </template> <script> export default { name: "Son", props: { msg: String, onQita: Function, onQita2: Function }, emits: ['toFather'], setup(props, context) { const clickFn = () => { context.emit('toFather', '传给父级的信息') }; console.log(props.msg) console.log(props.onQita) console.log(props, context); return { clickFn } } } </script> <style scoped> </style>
props需要先声明才能取值,attrs不用声明就可以用,attrs是通过setup第二个参数context取的
context.attrs.xx
。比如此时props把所有都声明了,那么attrs中就不会出现:
又比如此时props不声明onQita2,那么attrs中就会出现:
- props声明过的属性和方法,attrs中不会再出现。
修改部分:
- 改动了cdn的引入,vue2的引入为
<script src="https://unpkg.com/vue"></script>
,vue3是<script src="https://unpkg.com/vue@next"></script>
修改了父子组件原本emit和props的通信。
父级向自己使用props传值,父级写法不变,子级在html中正常使用,但在setup中需要通过props.msg.value取值,或者用toRefs解耦
const {msg} = toRefs(props)
,却取值还是msg.value。子级向父级传值,子级中增加
emits: ['toFather']
,emits中声明了子级调用父级的方法,执行为:context.emit('toFather', '传给父级')
,而父级监听子级的传递方式不变。具体实现如下:
// Father.vue <template> <div> <Son :msg="message" @toFather="getMsgFromSon"></Son> </div> </template> <script> import Son from './Son.vue' import {ref} from 'vue' export default { name: "Father", components: { Son, }, setup() { const message = ref('信息'); const getMsgFromSon = (val) => { console.log(val) }; return { message, getMsgFromSon, } } } </script> // Son.vue <template> <div> <span>{{msg}}</span> <button @click="clickFn">按钮</button> <!-- 或者使用$emit给父级传值 --> <button @click="$emit('toFather', '给父级的值')">按钮2</button> </div> </template> <script> export default { name: "Son", props: { msg: String }, emits: ['toFather'], setup(props, context) { const clickFn = () => { context.emit('toFather', '传给父级的信息') }; console.log(props, context); return { clickFn } } } </script>
mixin混淆不再是深层混淆了,现在改为只混淆第一层
const Mixin = { data() { return { user: { id: 0, name: 1, age: 2 } } } } const old = { mixins: [Mixin], data() { return { user:{ id: 2 } } }, mounted() { console.log(this.user); } } // 旧版:{id:2,name:1,age:2} // 新版:{id:2}
- 全局变量的设置由
Vue.prototype.xx
改为Vue.config.globalProperties.xx
。 修改了keyCodes,原本支持键盘码,现在只支持名了:
// 旧版 <input @keyup.13="subimit"/> // 新版:同时匹配q和Q <input @keyup.q="quit"/> // 匹配pagedown按键 <input @keyup.page-down="quit"/> // 匹配逗号 <input @keyup.,="quit"/> // 对于特殊字符"、'、/、=、> 和 .。,通过监听器的event.key实现
- 插槽统一,统一了普通插槽和作用域插槽,以前:
this.$scopedSlots.header
,现在:this.$slots.header()
- v-if和v-for同时在一个元素上,v-if优先,原本v-for优先。
v-model改变:
// 旧版 // 旧版中v-model是:value和@input的简写,比如 // 简写 <Father v-model="title"></Father> // 全写 <Father :value="title" @input="title"></Father> // 新版 // 父级 <Father v-model:msg="message"></Father> // 子级-父级可以不用设置@update:msg="message = $event"方法,即可实现子级点击后改变父级传入的props.msg.value <div> <span>{{msg}}</span> <button @click="$emit('update:msg', '传给父级的信息')">按钮</button> </div>
删除部分
- 删除了
$on
,$off
,$once
,还有过滤器filters
,vue3推荐大家使用computed
代替filters
。 删除了
Vue.extend
,改为Vue.createApp()
,因为两者比较相似:// vue2 // 创建构造器 const Profile = Vue.extend({ template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data() { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 创建一个 Profile 的实例,并将它挂载到一个元素上 new Profile().$mount('#mount-point') // vue3 const Profile = { template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data() { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } } Vue.createApp(Profile).mount('#mount-point')
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。