vue3新特征

Vue 3 数据响应式

Vue 2 的数据响应式底层实现是 Object.defineProperty(),对于数组则是拦截了数组的七个方法。这种方式存在的问题是对于对象没有办法检测到属性的添加或删除。对于基于数组索引的变化也不能检测到。

Vue 3 的数据响应式基于 ES6 的 Proxy 实现的,和 Mobx 6 相同。解决了上面提到的问题

  • Proxy 可以实现直接监听对象而非属性,所以对象的属性新增和删除也可以被监听
  • Proxy 可以直接监听数组的变化。因此数组直接修改下标对应的内容或长度也可以被监听
javascript 复制代码
const hero = {
    name: "赵云",
    hp: 100,
    sp: 100,
    equipment: ['马', '长枪']
}
const handler1 = {
    get(target, name, receiver) {
        return Reflect.get(target, name, receiver)
    },
    set(target, key, value, receiver) {
        console.log(`hero's ${key} change to ${value}`)
        return Reflect.set(target, key, value, receiver)
    }
}
const handler2 = {
    set(target, key, value, receiver) {
        console.log(`equipment's ${key} change to ${value}`)
        return Reflect.set(target, key, value, receiver)
    }
}
const heroProxy = new Proxy(hero, handler1)
const equipmentProxy = new Proxy(heroProxy.equipment, handler2)
heroProxy.equipment = equipmentProxy
//hero's equipment change to 马,长枪
heroProxy.name = "张飞"
//hero's name change to 张飞
heroProxy.equipment[2] = "盔甲"
//equipment's 2 change to 盔甲
heroProxy.level = 100
//hero's level change to 100

Composition API

主要目的是为了更方便的拆分,重用代码,Vue 2 如果要复用代码的话需要使用 mixin。官方有示例,我感觉 Composition API 有点类似 React 的 自定义 Hooks。

setup

在 setup 中没有 this,只能使用 props 和 context

javascript 复制代码
import {toRefs} from 'vue'
setup(props){
    // const {title} = props 
    // ES6 解构会消除 prop 的响应性,如果要解构要写成下面的样子
    const {title} = toRefs(props)
    console.log(title.value)
}

context 具有以下属性

  • props
  • attrs
  • slots
  • emit
生命周期钩子

setup 的生命周期钩子基本就是在选项式 API 的基础上加上 on

复制代码
javascript 复制代码
export default { setup(){ onMounted(()=>{ ... }) } }
ref 和 reactive

ref 和 reactive 都用于为数据添加响应式状态,但是 reactive 只接受对象类型的参数。一般数据为对象的话使用 reactive,基本类型使用 ref。 在 JS 中使用 ref 对象的值要加上 .value,在 Template 中使用则不需要。

复制代码
javascript 复制代码
const count = ref(0) console.log(count.value) // 0
Provide / Inject

跟 Vue 2 中的 Provide 和Inject 功能类似,可以用于组件间通信。可以将 provide 提供的数据变为 inject 的组件只读的。

复制代码
java 复制代码
<template>
  <MyMarker />
</template>
<script>
import { provide, reactive, readonly, ref } from 'vue'
import MyMarker from './MyMarker.vue

export default {
  components: {
    MyMarker
  },
  setup() {
    const location = ref('North Pole')
    const geolocation = reactive({
      longitude: 90,
      latitude: 135
    })
    const updateLocation = () => {
      location.value = 'South Pole'
    }
    provide('location', readonly(location))
    provide('geolocation', readonly(geolocation))
    provide('updateLocation', updateLocation)
  }
}
</script>
Teleport

可以把元素移动到我们想要的位置

复制代码
html 复制代码
<teleport to="body"> <div> ... </div> </teleport>

v-model 用法的变更

Vue 2 中的 v-model 相当于绑定 value prop 和 input 事件:

复制代码
html 复制代码
<ChildComponent v-model="pageTitle"> 
<!--是以下的简写:--> 
<ChildComponent :value="pageTitle" @input="pageTitle = $event"/>

而 Vue 3 中的 v-model 更像是.sync

复制代码
html 复制代码
<!-- Vue2 --> <ChildComponent :title.sync="pageTitle"/> 
<!-- Vue3 --> <ChildComponent v-model:title="pageTitle"/>

组件事件需要在 emits 选项中声明

组件需要在 emits 中声明触发的事件

复制代码
javascript 复制代码
export default { emits:['accept','cancel'] }

否则控制台会有警告

watchEffect

这个跟 MobX 的 autorun 非常像,它会立即执行传入的函数并响应式追踪其依赖,依赖变更久重新执行

复制代码
javascript 复制代码
const count = ref(0)
watchEffect(() => console.log(count.value))
// -> logs 0
setTimeout(() => {
  count.value++
  // -> logs 1
}, 100)
与 watch 的区别
  • watch 可以访问到侦听状态变化前后的值
  • watch 只有在侦听的源发生变化时才会执行回调
  • 可以更具体的说明什么情况下回调函数执行

v-for 中的 Ref

ref 可以绑定一个函数,来确定要绑定的 Dom 元素

复制代码
html 复制代码
 <div class="color-tabs-nav-item" v-for="(t,index) in titles" :ref="el => { if (index === selectedIndex) this.selectedItem = el }"
   :key="index">{{ t }}
 </div>

相关推荐
猿饵块23 分钟前
cmake--get_filename_component
java·前端·c++
好多吃的啊33 分钟前
背景图鼠标放上去切换图片过渡效果
开发语言·javascript·ecmascript
大表哥634 分钟前
在react中 使用redux
前端·react.js·前端框架
Passion不晚36 分钟前
打造民国风格炫酷个人网页:用HTML和CSS3传递民国风韵
javascript·html·css3
十月ooOO38 分钟前
【解决】chrome 谷歌浏览器,鼠标点击任何区域都是 Input 输入框的状态,能看到输入的光标
前端·chrome·计算机外设
qq_3391911439 分钟前
spring boot admin集成,springboot2.x集成监控
java·前端·spring boot
pan_junbiao1 小时前
Vue使用代理方式解决跨域问题
前端·javascript·vue.js
明天…ling1 小时前
Web前端开发
前端·css·网络·前端框架·html·web
子非鱼9211 小时前
【JavaScript】LeetCode:41-45
开发语言·javascript·leetcode·链表·二叉树
ROCKY_8171 小时前
web前端-HTML常用标签-综合案例
前端·html