vue2.0和vue3.0的区别
如何创建vue3.0项目
基于vue/cli配置vue3.0
- vue/cli脚手架必须是4.3.1版本以上
- 使用创建项目命令
vue create 项目名
- 最后加上
vue add vue-next
,创建3.0的项目
基于vite配置vue3.0
- 有尤雨溪开发的web开发工具,基于浏览器原生ES imports的开发服务器(利用浏览器解析imports,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用),同时不仅有vue文件的支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。
npm init vite-app 项目名
cd 项目名
npm i
npm run dev
掌握setup和响应式系统API
响应式系统工具集
ref
- 接收一个参数值并返回一个响应式且可改变的ref对象。
- ref对象拥有一个指向内部值的一个属性
.value
- 当ref在模板中使用的时候,他会自动解套,无需在模板内部额外写
.value
(意思是return出来以后,用小胡子就可以直接使用) - ref不是Proxy实现的。
unref
- 如果参数是一个ref,则返回它的value值,否则返回参数本身,他是val = isRef(val)? val.value:val的语法槽
let a = '你好',
b = ref(2)
console.log(unref(a,b)) //'你好',2
复制代码
toRef
toRefs
- 把响应式对象转为普通对象,该普通对象每一个property都是一个ref,和响应式对象property一一对应。
isRef
isProxy
- 检查一个对象是否由reactive或者readonly方法创建的代理
isReactive
- 检查一个对象是否由reactive创建的响应式代理。
- 如果这个代理是由reactive创建的,但是又被reactive创建的另一个代理包裹了一层,那么同样会返回true
isReaonly
- 检查一个对象是否由readonly创建的只读代理。
readonly
- 传入一个对象(响应式或者普通)或ref,返回一个原始对象的只读代理,一个只读的代理是深层的,对象内部任何嵌套的属性也只是只读的。
高级系统响应式API
customRef
computed
- 传入一个getter函数,返回一个默认不可手动修改的ref对象。
// 第一种写法:不可手动修改值
setup() {
let a = computed(()=>{
let total = state.supNum + state.oppNum
return ((state.supNum/total)*100).toFixed(2) + '%'
})
return{
a
}
}
//第二种写法:可以利用set修改,当a所依赖的值supNum和oppNum改变会触发get回调函数,如果修改a的值会触发set回调函数(a.vlue = a.vlue+1就会触发)
setup() {
let a = computed({
get:()=>{
let total = state.supNum + state.oppNum
return ((state.supNum/total)*100).toFixed(2) + '%'
}
set:(val)=>{
console.log(val,222)
}
})
return{
a
}
}
复制代码
watchEffect
watch
- watch完全等价于2.0的watch
- watch需要侦听特定的数据源,并在回调函数中执行。
- 默认情况是懒执行的,也就是说仅在侦听的源变更时才执行回调。第一次加载页面是不执行的,和watchEffect不一样。
//侦听单个数据
setup(){
watch(state,()=>{
console.log(state.supNum)
})
//侦听state下的某个数据
watch(()=>state.supNum,()=>{
console.log('你好'+state.supNum)
})
//侦听ref创建的响应式数据,输出改变后的值和之前的值
let x = ref(0)
setup(){
watch(x,(x,prevX)=>{
console.log(x,prevX)
})
}
//侦听多个数据用数组传参,数组中任意值改变都会触发watch函数
watch([x,y],([x,y],[prevx,prevy]=>{
console.log(x,y,prevx,prevy)//prevx,prevy改变之前的值
}))
复制代码
watchEffect和watch的区别
- 不需要手动传入依赖值。
- 每次初始化时会执行一次回调函数来获取依赖值。
- 无法获取原值,只能获取改变后的值。
setup
构建响应式数据
方法一,利用ref,一般处理简单值的响应式
- 原理还是基于defineProperty监听value值
<template>
<div>
<h3>{{ title }}</h3>
<div>
<p>支持人数:{{ supNum }}</p>
<p>反对人数:{{ oppNum }}</p>
<p>支持率:</p>
<button @click="change(0)">支持</button>
<button @click="change(1)">反对</button>
</div>
</div>
</template>
// 第一种直接使用ref,比较麻烦
setup() {
let supNum = ref(0),
oppNum = ref(0);
functiom change(x){
x == 0? supNum.value++:oppNum.value++
}
return{
supNum,
oppNum,
change,
}
}
// 第二种ref,创建一个ref对象
setup(){
let state = ref({
supNum:0
oppNum:0
})
function change(x){
x == 0? state.value.supNum++ : state.value.oppNum++
}
return{
state
}
//html在使用的时候,{{state.supNum}}
}
复制代码
方法二,利用 reactive
- 基于Proxy对数据进行深度的监听,以此构建响应式
- 接收一个普通对象然后返回该普通对象的响应式代理
- 响应式转换是深层的,会影对象内部所有嵌套的属性
setup() {
let state = reactive({
supNum: 0,
oppNum; 0
})
function change(x){
x == 0? state.supNum++ : state.oppNum++
// 比Object.defineProperty好用在于,对与数据或者并未初始化的对象成员,都可以随意的改变值,而且具备响应式的数据。
}
return{
...toRefs(state),
change
}
//html在使用的时候,{{supNum}}
}
复制代码
模板refs
<template>
<div>
<div ref="root">你好</div>
</div>
</template>
export default {
setup(){
let root = ref();
onMounted(()={
console.log(root.value) //返回值是div元素
})
return{
root
}
}
}
复制代码
生命周期函数
- beforeCreate=>使用setup
- create=>使用setup
- beforeMount=>onBeforeMount 第一次挂载之前
- mounted=>onMounted 第一次挂载之后
- beforeUpdate=>onBeforeUpdate 组件更新之前
- updated=>onUpdated 组件更新之后
- beforeDestroy=>onBeforeUnmount 组件销毁之前
- destoryed=>onUnmounted 组件销毁之后
- errorCaptured=>onErrorCaptured