你准备好迎接vue3.0了吗


Posted in Javascript onApril 28, 2020

前言

本月21号晚上看了尤大大的直播,感觉vue3.0离我们越来越近了,预计年中正式发布,3.0的改变的确很大,性能提升了很多,很多东西也在靠向react。为了到时可以很快的转入vue3.0的阵营,从现在开始熟悉新的特性是很有必要的。
如果你想在v2.x中使用3.0的内容,可通过以下方式

npm install '@vue/composition-api'

在main.js中引入

import VueCompositionApi from '@vue/composition-api';
Vue.use(VueCompositionApi);

数据的双向绑定

V2.x中的数据双向绑定是通过object的defineProperty方法实现的,通过属性中的get和set方法中进行拦截操作。但是它无法监听数组的改变,除了使用以下几种方法可以:push()、pop()、shift()、unshift()、splice()、sort()、reverse(),如果直接使用index设置数组的某一项时是无法改变的。

V3.x中改用了proxy和Reflect实现双向绑定,它可以从更多方面对对象的变化进行监听,除了set 和 get 外,还提供了apply、setPrototypeOf、getPrototypeOf、deletePrototype、isExtensible、preventExtensions、getOwnPropertyDescriptor 、defineProperty、has、ownKeys、construct方法的监听。

对于proxy的实际应用我将在后期专门来讲解,本期以VU3.0的实践为主

直接上一斤的例子

<template>
  <div>
    <h3>数据绑定</h3>
    <div>
      <el-button @click="clicksingleVal">
        单向绑定 {{singleVal}}
      </el-button>
      <el-button @click="clickdoubleVal">
        双向绑定 {{doubleVal}}
      </el-button>
      <el-button @click="clickstateVal">
        状态绑定 {{stateVal}}
      </el-button>
    </div>
  </div>
</template>
​
​
<script>
import {ref, reactive, toRefs} from '@vue/composition-api'
export default {
  setup(){
    let singleVal = 1
    const doubleVal = ref(1)
    const state = reactive({
      stateVal: 1
    })
    const methods = {
      clicksingleVal(){
        singleVal++
        console.log(singleVal);
      },
      clickdoubleVal(){
        doubleVal.value++
      },
      clickstateVal(){
        state.stateVal++
      },
    }
    return{
      singleVal,
      doubleVal,
      ...toRefs(state),
      ...methods
    }
  }
}
</script>
<style>
</style>

如果你是第一次看到上面的写法可能会有点陌生,这就是在vue3.x中的写法。在v2.x中的data、methods、computed、watch等内容,在v3.x中全部都写在一个叫 setup 的函数中。在里面我们可以任意的定义变量、函数等,最后通过return返回,返回的内容可以在模板中进行使用。
对于绑定的数据在v3.x中进行了更加详细的分类,可以分为以下三种:

  • 单向绑定:var singleVal = 1,数据会变化,但是视图不会更新
  • 单个双向绑定:const doubleVal = ref(1),使用 doubleVal.value 改变
  • 双向绑定:需要使用 reactive ,使用 state.stateVal 改变值

我们来逐个的进行讲解:

  • 单向绑定,听名字就可以知道它并不具有双向绑定的特性或功能,它只会在视图初始化时绑定一次,这个变量即使后面发生了改变,视图也不会更新。可以从控制台看到singleVal 的值的确发生了变化,但界面中始终显示的为1。变量声明的方法和我们平时声明一个变量一样,如:let singleVal = 1,最后在return中返回。
  • 单个双向绑定,每次只能声明一个双向绑定的变量,通过ref函数创建一个包装对象,使它包含一个响应式的属性value。例如上面的const doubleVal = ref(1)。如果要改变它的值,需要改变的是它的属性value上的值,像这样一样doubleVal.value++。
  • 双向绑定,通过reactive创建一个响应式的对象,这样创建的对象并不是一个包装对象,因此不需要使用.value来取值,它等价于 Vue 2.x 的Vue.observable。

你准备好迎接vue3.0了吗

const state = reactive({
  stateVal: 1
})
return {
 ...state
}

对reactive的内容直接进行解构后返回,会导致响应式丢失,需要使用toRefs将reactive对象转为普通对象,这样结果对象上的每个属性都指向原始对象中对应属性的ref引用对象,保证了在使用对象解构或拓展运算符时响应式不会丢失。
对于事件方法,就和声明一个变量一样,在setup中声明,在return返回即可。

计算属性

引入computed方法,返回计算后的值,这里接着使用上面的例子,用total计算上面3个数的总和。

import {computed, ref, reactive, toRefs} from '@vue/composition-api' 
export default {
  setup(){
    ...
    const total = computed(() =>{
      return singleVal + doubleVal.value + state.stateVal
    })
    ...
    return{
      ...,
      total
    }
  }
}

你准备好迎接vue3.0了吗

从演示效果中我们还可以看出一点,单向绑定的数据改变不会触发计算属性方法。

数据监听

同样还是写在setup中,也比较简单,没有什么可讲解的

import {computed, ref, reactive, toRefs, watch} from '@vue/composition-api'
...
watch(() => state.stateVal, (newVal, oldVal ) =>{
  console.log(newVal, oldVal);
})
...

你准备好迎接vue3.0了吗

生命周期

vue3.0中取消了 beforeCreate 和 created 两个周期,因为setup会在这个这个周期前执行,因此你可以在setup中进行你需要的处理。其他的生命周期全部以on开头。

import {
  onBeforeMount,
  onMounted,
  onBeforeUnmount,
  onBeforeUpdate,
  onDeactivated,
  onUnmounted,
  onUpdated
} from '@vue/composition-api'
export default {
  setup(){
    onBeforeMount(() =>{
      console.log('onBeforeMount');
    })
    onMounted(() =>{
      console.log('onMounted');
    })
    onBeforeUnmount(() =>{
      console.log('onBeforeUnmount');
    })
    onBeforeUpdate(() =>{
      console.log('onBeforeUpdate');
    })
    onDeactivated(() =>{
      console.log('onDeactivated');
    })
    onUnmounted(() =>{
      console.log('onUnmounted');
    })
    onUpdated(() =>{
      console.log('onUpdated');
    })
  }
}

Mixin

vue3.0中使用函数式的API代替原有的mixin,mixin很容易引起命名重合和覆盖引入mixin的页面属性。

在vue3.0中以一个API的形式存在,当你需要时,将其引入。直接看例子

mixin.vue

<template>
  <div>
    <h3>mixins</h3>
    <div>
      <el-input v-model="searchValue" type="text" @change="onSearch"/>
      <div>
        <ul>
          <li v-for="name in names" :key="name.id" v-show="name.show">
            {{name.value}}
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>
​
<script>
import searchName from './searchName.js'
export default {
  setup(){
    let list = [
      {id: 1, value: 'vue', show: true},
      {id: 2, value: 'react', show: true},
      {id: 3, value: 'angular', show: true},
      {id: 4, value: 'elementui', show: true},
      {id: 5, value: 'ant', show: true},
      {id: 6, value: 'javascript', show: true},
      {id: 7, value: 'css', show: true},
    ]
    var {onSearch, names, searchValue} = searchName(list)
    return {
      onSearch,
      names,
      searchValue
    }
  }
}
</script>
<style>
</style>

searchName.js

import {reactive, toRefs} from '@vue/composition-api'
​
export default function searchName(names){
  const state = reactive({
    names: names,
    searchValue: ''
  })
  const onSearch = () => {
    state.names.forEach(name => {
      name.show = name.value.includes(state.searchValue)
    })
  }
  return {
    ...toRefs(state),
    onSearch
  }
}

上面我们将搜索功能独立到一个js文件中。在 searchName.js 中定义了一些属性和方法,这里的属性也是具有响应式的,最后返回这些内容。在组件中,先引入这个js文件,调用searchName方法,传入需要的参数。在该组件中的searchValue和names两个响应式数据并非自身的所有,而是来自searchName.js中,通过下面演示可以看到,他们的确也具有响应式的特性。

你准备好迎接vue3.0了吗

EventBus

  • setup接收两个参数
  • props:等同于V2.x中的 props:{},用于接收父组件传递的参数

ctx:上下文环境。在2.x中的this指向的是全局VUE实例,可以使用this.routerthis.router、this.router、this.commit、this.emit3.0访thisthisundefinedctx.root.emit等方法进行路由的跳转等操作。而在3.0中不能直接访问到this,如果你尝试输出this,你回看到它的值是undefined。但可以通过ctx.root.emit等方法进行路由的跳转等操作。而在3.0中不能直接访问到this,如果你尝试输出this,你回看到它的值是undefined。但可以通过ctx.root.root.$emit将内容挂在到 $root 上,以使得任何地方都可以访问到。

setup(props, ctx){
 ...
 const total = computed(() =>{
   let total = singleVal + doubleVal.value + state.stateVal
   ctx.root.$root.$emit('handleClick', {number: total })
   return total 
 })
 ...
}
...
ctx.root.$root.$on('handleClick', (val) =>{
  console.log('我是通过ctx.root.$root.$on触发的,接收的值为:' + val.number);
  state.otherTotal = val.number
})
...

最后附上composition-api的github:https://github.com/vuejs/composition-api

到此这篇关于你准备好迎接vue3.0了吗的文章就介绍到这了,更多相关vue3.0内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript 文档的编码问题解决
Mar 01 Javascript
javascript string字符串优化问题
Jul 31 Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
Sep 14 Javascript
实现点击列表弹出列表索引的两种方式
Mar 08 Javascript
Javascript算符的优先级介绍
Mar 20 Javascript
Jquery 复选框取值兼容FF和IE8(测试有效)
Oct 29 Javascript
jQuery EasyUI 右键菜单--关闭标签/选项卡的简单实例
Oct 10 Javascript
Angular2 组件交互实例详解
Aug 24 Javascript
Vue项目中如何引入icon图标
Mar 28 Javascript
Vue使用Canvas绘制图片、矩形、线条、文字,下载图片
Apr 26 Javascript
JavaScript怎样在删除前添加确认弹出框?
May 27 Javascript
JavaScript前端开发时数值运算的小技巧
Jul 28 Javascript
JavaScript禁止右击保存图片,禁止拖拽图片的实现代码
Apr 28 #Javascript
JavaScript 禁止用户保存图片的实现代码
Apr 28 #Javascript
JS求解两数之和算法详解
Apr 28 #Javascript
jQuery插件simplePagination的使用方法示例
Apr 28 #jQuery
uni-app如何页面传参数的几种方法总结
Apr 28 #Javascript
JavaScript 双向链表操作实例分析【创建、增加、查找、删除等】
Apr 28 #Javascript
JS 创建对象的模式实例小结
Apr 28 #Javascript
You might like
YII Framework教程之异常处理详解
2016/03/14 PHP
Zend Framework入门应用实例详解
2016/12/11 PHP
使用laravel的Eloquent模型如何获取数据库的指定列
2019/10/17 PHP
EasyUi tabs的高度与宽度根据IE窗口的变化自适应代码
2010/10/26 Javascript
js对象的构造和继承实现代码
2010/12/05 Javascript
jQuery中的.bind()、.live()和.delegate()之间区别分析
2011/06/08 Javascript
简单的前端js+ajax 购物车框架(入门篇)
2011/10/29 Javascript
jQuery中closest()函数用法实例
2015/01/07 Javascript
PHP配置文件php.ini中打开错误报告的设置方法
2015/01/09 PHP
js分页工具实例
2015/01/28 Javascript
JavaScript中的toLocaleDateString()方法使用简介
2015/06/12 Javascript
关于JS中的apply,call,bind的深入解析
2016/04/05 Javascript
关于动态生成dom绑定事件失效的原因及解决方法
2016/08/06 Javascript
js 创建对象 经典模式全面了解
2016/08/16 Javascript
Bootstrap实现导航栏的2种方式
2016/11/28 Javascript
jQuery中库的引用方法
2018/01/06 jQuery
用Object.prototype.toString.call(obj)检测对象类型原因分析
2018/10/11 Javascript
vue 指令之气泡提示效果的实现代码
2018/10/18 Javascript
Javascript中弹窗confirm与prompt的区别
2018/10/26 Javascript
js html实现计算器功能
2018/11/13 Javascript
iSlider手机端图片滑动切换插件使用详解
2019/12/24 Javascript
[06:01]刀塔次级联赛top10第一期
2014/11/07 DOTA
详解Python中映射类型的内建函数和工厂函数
2015/08/19 Python
Python实现各种排序算法的代码示例总结
2015/12/11 Python
python中利用h5py模块读取h5文件中的主键方法
2018/06/05 Python
PyQt5基本控件使用详解:单选按钮、复选框、下拉框
2019/08/05 Python
opencv+python实现均值滤波
2020/02/19 Python
Django中FilePathField字段的用法
2020/05/21 Python
在pycharm中关掉ipython console/PyDev操作
2020/06/09 Python
欧洲最大的拼图游戏商店:JigsawPuzzle.co.uk
2018/07/04 全球购物
Melissa鞋英国官方网站:Nonnon
2019/05/01 全球购物
会计专业毕业生自我评价
2013/09/25 职场文书
餐饮业经理竞聘演讲稿
2014/01/14 职场文书
微笑面对生活演讲稿
2014/05/13 职场文书
结婚纪念日感言
2015/08/01 职场文书
2019个人工作总结
2019/06/21 职场文书