官网vue2和vue3混杂在一起介绍比较,读起来比较费劲,本文是官网主要知识点的提炼和总结,定位于比较长时间没开发,已经遗忘的情况下,快速查询常用功能,不用再比较费劲地再看官网。初学者还是去官网学。
通过脚手架 Vite:
npm init vite hello-vue3 -- --template vue # 或 yarn create vite hello-vue3 --template vue
通过脚手架 vue-cli:
npm install -g @vue/cli # 或 yarn global add @vue/cli
vue create hello-vue3
# 选择 vue 3 preset
组合式api可以通过setup配置项目使用,不过这种写起来比较麻烦,不做介绍了,vue3.2 提供了单文件组件
使用包含value的对象方式,是为了防止传递过程中响应性丢失。
unplugin-auto-import插件,使用方法请自行百度。
{{name}}
声明提供的事件,同事支持对事件进行校验。
vue3 v-on
的 .native
修饰符已被移除。没有用defineEmits什么的事件,都会被当做组件的原生组件,应用到根元素上。看这里
自定义事件还支持进行验证,详细看这里
暴露属性和方法给外部使用
defineProps、defineEmits、defineExpose 不需要引入,可以直接使用。
此外
destroyed
生命周期选项被重命名为 unmounted
beforeDestroy
生命周期选项被重命名为 beforeUnmount
当侦听一个数组时,只有当数组被替换时才会触发回调。如果你需要在数组被改变时触发回调,必须指定 deep
选项。
import { createApp } from 'vue'
import MyComponent from '@/components/MyComponent'
const app = createApp({})
// 注册一个名为my-component的组件
app.component('my-component', MyComponent)
// 检索注册的组件(始终返回构造函数)
const MyComponent = app.component('my-component')
全局注册指令使用app.directive,指令钩子已做了重命名,更好理解了。
过滤器移除了,可以采用config.globalProperties定义全局函数替代。config.globalProperties本身是用于替代 Vue.prototype
,可以参考这里
在网上查到其他人注册全局方法的思路
代码集中在setup中会使代码变大,可将代码按逻辑独立出去
import { ref, computed } from 'vue'
// 独立逻辑代码
export default function useSearch(param) {
const searchQuery = ref('')
const search = function(){
}
return {
searchQuery,
search
}
}
一起使用 可以和普通的
一起使用。普通的
在有这些需要的情况下或许会被使用到:
声明的选项,例如 inheritAttrs
或通过插件启用的自定义的选项。
await
中可以使用顶层
await
。结果代码会被编译成 async setup()
:
另外,await 的表达式会自动编译成在 await
之后保留当前组件实例上下文的格式。
注意
async setup()
必须与 Suspense
组合使用,Suspense
目前还是处于实验阶段的特性。我们打算在将来的某个发布版本中开发完成并提供文档 - 如果你现在感兴趣,可以参照 tests 看它是如何工作的。
A
teleport 内部的元素将渲染到id为modals的元素中。
// 在入口中
app.provide('guide', 'Vue 3 Guide')
// 在子组件中
export default {
inject: {
book: {
from: 'guide'
}
},
template: `{{ book }}`
}
app.component('my-component', {
props: {
title: String
},
emits: ['update:title'],
template: `
`
})
hello
reactive
返回对象的响应式副本,看了网上一些人说:“ref正对基础数据类型,reactive针对对象”。其实试了一下,ref也可以用于复杂对象,建议模板中使用更多的是用ref,ref可以很轻松的对整个对象进行替换,如果是reactive,需要对每一个键进行赋值,才会变化。
toRaw
返回 reactive 或 readonly 代理的原始对象。这是一个“逃生舱”,可用于临时读取数据而无需承担代理访问/跟踪的开销,也可用于写入数据而避免触发更改。不建议保留对原始对象的持久引用。请谨慎使用。
const foo = {}
const reactiveFoo = reactive(foo)
console.log(toRaw(reactiveFoo) === foo) // true
shallowReactive
创建一个响应式代理,它跟踪其自身 property 的响应性,但不执行嵌套对象的深层响应式转换 (暴露原始值)。
const state = shallowReactive({
foo: 1,
nested: {
bar: 2
}
})
// 改变 state 本身的性质是响应式的
state.foo++
// ...但是不转换嵌套对象
isReactive(state.nested) // false
state.nested.bar++ // 非响应式
与 reactive 不同,任何使用 ref 的 property 都不会被代理自动解包
ref
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property
unref
如果参数是一个 ref,则返回内部值,否则返回参数本身
toRef
响应型对象一旦被销毁或展开,其响应式特性就会丢失。toRef
可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。
toRefs
将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref。
const state = reactive({
foo: 1,
bar: 2
})
const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:
{
foo: Ref,
bar: Ref
}
*/
// ref 和原始 property 已经“链接”起来了
state.foo++
console.log(stateAsRefs.foo.value) // 2
stateAsRefs.foo.value++
console.log(state.foo) // 3
当从组合式函数返回响应式对象时,toRefs
非常有用,这样消费组件就可以在不丢失响应性的情况下对返回的对象进行解构/展开:
function useFeatureX() {
const state = reactive({
foo: 1,
bar: 2
})
// 操作 state 的逻辑
// 返回时转换为ref
return toRefs(state)
}
export default {
setup() {
// 可以在不失去响应性的情况下解构
const { foo, bar } = useFeatureX()
return {
foo,
bar
}
}
}
toRefs
只会为源对象中包含的 property 生成 ref。如果要为特定的 property 创建 ref,则应当使用 toRef
computed
接受一个具有 get
和 set
函数的对象,用来创建可写的 ref 对象。
watchEffect
立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。
const count = ref(0)
watchEffect(() => console.log(count.value))
// -> logs 0
setTimeout(() => {
count.value++
// -> logs 1
}, 100)
watch
watch
需要侦听特定的数据源,并在单独的回调函数中执行副作用。默认情况下,它也是惰性的——即回调仅在侦听源发生变化时被调用。
插槽没有什么变化,直接看文档
1、支持了多根节点的组件
2、同一个元素上,v-if
比 v-for
优先级更高
3、createApp
返回一个应用实例,替代Vue 2.x 有许多全局 API 和配置,避免了测试期间的全局污染。
4、全局api采用具名导出,更好的支持 tree-shaking
5、 的
key
应该设置在 标签上 (而不是设置在它的子节点上)。
6、v-bind 的绑定顺序会影响渲染结果。
7、数式组件的性能提升可以忽略不计,因此我们建议只使用有状态的组件
8、异步组件用defineAsyncComponent定义,具体看这里,路由异步组件不用defineAsyncComponent,还是按vue-router路由懒加载来
9、$attrs
现在包含了所有传递给组件的 attribute,包括 class
和 style
$attrs
中的 attribute 将不再被自动添加到根元素中,而是由开发者决定在哪添加。
10、data选项
非兼容:组件选项 data
的声明不再接收纯 JavaScript object
,而是接收一个 function
。
非兼容:当合并来自 mixin 或 extend 的多个 data
返回值时,合并操作现在是浅层次的而非深层次的 (只合并根级属性)
11、过渡类名 v-enter
修改为 v-enter-from
、过渡类名 v-leave
修改为 v-leave-from
12、
没有特殊指令的标记 (v-if/else-if/else
、v-for
或 v-slot
) 的 现在被视为普通元素,并将渲染为原生的
元素,而不是渲染其内部内容。
13、监听组件生命周期
14、被移除
1、$on
,$off
和 $once
实例方法已被移除,组件实例不再实现事件触发接口。
2、对内联模板特性的支持已被移除
3、$children
已被移除,采用$refs代替
4、$destroy
5、全局函数 set
和 delete
以及实例方法 $set
和 $delete
15、获取上下文对象
import { getCurrentInstance } from "vue";
setup(){
//解构赋值 设置别名that 也可不写 :that 直接ctx
let {ctx} = getCurrentInstance()
ctx.$forceUpdate()
}
vue-router 4采用vue3重写,大部分的 Vue Router API 都没有变化,变化部分可看这里,不过采用手脚架工具构建完之后,其实这些变化用到的很少。更常用到的是组合式api,与组合式api相关的可看这里。
vuex 4 采用vue3重写,大部分都没什么变化,变化部分看这里, 不过采用手脚架工具构建完之后,其实这些变化用到的很少。更常用到的是组合式api,与组合式api相关的可看这里。
1、Vue-Meta 尚未支持vue3,只看到beta版的
2、element plus 在Safari 13 date-picker placeholder失效、也选不了时间。Safari15是正常的。
本文只提炼了开发中常用的知识点,详细可还是到官网学习,懂vue2的人可从迁移指南开始阅读。
其实,个人感觉,setup的方式反而使代码变得有些混乱了,一个变量你可能只是在某个函数和模板中用到,这时你可能需要放到函数附近。写着写着可能有其他函数也要用到,这时可能又得把它放到顶部。各种函数也散落一地,感觉又回到了jquery没有约束的时代。虽然可以将部分相关性比较大的代码独立出去,但其实挺麻烦。不知各位大佬怎么看。