让你30分钟快速掌握vue3教程


Posted in Javascript onOctober 26, 2020

经过了漫长的迭代,Vue 3.0终于在上2020-09-18发布了,带了翻天覆地的变化,使用了Typescript 进行了大规模的重构,带来了Composition API RFC版本,类似React Hook 一样的写Vue,可以自定义自己的hook ,让使用者更加的灵活,接下来总结一下vue 3.0 带来的部分新特性。

  • setup()
  • ref()
  • reactive()
  • isRef()
  • toRefs()
  • computed()
  • watch()
  • LifeCycle Hooks(新的生命周期)
  • Template refs
  • globalProperties
  • Suspense

Vue2与Vue3的对比

  • 对TypeScript支持不友好(所有属性都放在了this对象上,难以推倒组件的数据类型)
  • 大量的API挂载在Vue对象的原型上,难以实现TreeShaking。
  • 架构层面对跨平台dom渲染开发支持不友好
  • CompositionAPI。受ReactHook启发
  • 更方便的支持了 jsx
  • Vue 3 的 Template 支持多个根标签,Vue 2 不支持
  • 对虚拟DOM进行了重写、对模板的编译进行了优化操作...

一、setup 函数

setup() 函数是 vue3 中,专门为组件提供的新属性。它为我们使用 vue3 的 Composition API 新特性提供了统一的入口, setup 函数会在 beforeCreate 之后、created 之前执行, vue3也是取消了这两个钩子,统一用setup代替, 该函数相当于一个生命周期函数,vue中过去的data,methods,watch等全部都用对应的新增api写在setup()函数中

setup(props, context) {
  context.attrs
  context.slots
  context.parent
  context.root
  context.emit
  context.refs
  
  return {
    
  }
 }
  • props: 用来接收 props 数据
  • context 用来定义上下文, 上下文对象中包含了一些有用的属性,这些属性在 vue 2.x 中需要通过 this 才能访问到, 在 setup() 函数中无法访问到 this,是个 undefined
  • 返回值: return {}, 返回响应式数据, 模版中需要使用的函数

二、reactive 函数

reactive() 函数接收一个普通对象,返回一个响应式的数据对象, 想要使用创建的响应式数据也很简单,创建出来之后,在setup中return出去,直接在template中调用即可

<template>
 {{name}} // test
<template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
export default defineComponent({
 setup(props, context) {
 
  let state = reactive({
   name: 'test'
  });
  
  return state
 }
});
</script>

三、ref() 函数

ref() 函数用来根据给定的值创建一个响应式的数据对象,ref() 函数调用的返回值是一个对象,这个对象上只包含一个 value 属性, 只在setup函数内部访问ref函数需要加.value

<template>
  <div class="mine">
    {{count}} // 10
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
 setup() {
  const count = ref<number>(10)
  // 在js 中获取ref 中定义的值, 需要通过value属性
  console.log(count.value);
  return {
    count
  }
  }
});
</script>

在 reactive 对象中访问 ref 创建的响应式数据

<template>
  <div class="mine">
    {{count}} -{{t}} // 10 -100
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
export default defineComponent({
 setup() {
  const count = ref<number>(10)
  const obj = reactive({
   t: 100,
   count
  })
  // 通过reactive 来获取ref 的值时,不需要使用.value属性
  console.log(obj.count);
  return {
    ...toRefs(obj)
  }
  }
});
</script>

四、isRef() 函数

isRef() 用来判断某个值是否为 ref() 创建出来的对象

<script lang="ts">
import { defineComponent, isRef, ref } from 'vue';
export default defineComponent({
 setup(props, context) {
  const name: string = 'vue'
  const age = ref<number>(18)
  console.log(isRef(age)); // true
  console.log(isRef(name)); // false

  return {
   age,
   name
  }
 }
});
</script>

五、toRefs() 函数

toRefs() 函数可以将 reactive() 创建出来的响应式对象,转换为普通的对象,只不过,这个对象上的每个属性节点,都是 ref() 类型的响应式数据

<template>
 <div class="mine">
  {{name}} // test
  {{age}} // 18
 </div>
</template>

<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
export default defineComponent({
 setup(props, context) {
  let state = reactive({
   name: 'test'
  });

  const age = ref(18)
  
  return {
   ...toRefs(state),
   age
  }
 }
});
</script>

六、computed()

该函数用来创造计算属性,和过去一样,它返回的值是一个ref对象。 里面可以传方法,或者一个对象,对象中包含set()、get()方法

6.1 创建只读的计算属性

import { computed, defineComponent, ref } from 'vue';
export default defineComponent({
 setup(props, context) {
  const age = ref(18)

  // 根据 age 的值,创建一个响应式的计算属性 readOnlyAge,它会根据依赖的 ref 自动计算并返回一个新的 ref
  const readOnlyAge = computed(() => age.value++) // 19

  return {
   age,
   readOnlyAge
  }
 }
});
</script>

6.2 通过set()、get()方法创建一个可读可写的计算属性

<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
export default defineComponent({
 setup(props, context) {
  const age = ref<number>(18)

  const computedAge = computed({
   get: () => age.value + 1,
   set: value => age.value + value
  })
  // 为计算属性赋值的操作,会触发 set 函数, 触发 set 函数后,age 的值会被更新
  age.value = 100
  return {
   age,
   computedAge
  }
 }
});
</script>

七、 watch() 函数

watch 函数用来侦听特定的数据源,并在回调函数中执行副作用。默认情况是懒执行的,也就是说仅在侦听的源数据变更时才执行回调。

7.1 监听用reactive声明的数据源

<script lang="ts">
import { computed, defineComponent, reactive, toRefs, watch } from 'vue';
interface Person {
 name: string,
 age: number
}
export default defineComponent({
 setup(props, context) {
  const state = reactive<Person>({ name: 'vue', age: 10 })

  watch(
   () => state.age,
   (age, preAge) => {
    console.log(age); // 100
    console.log(preAge); // 10
   }
  )
  // 修改age 时会触发watch 的回调, 打印变更前后的值
  state.age = 100
  return {
   ...toRefs(state)
  }
 }
});
</script>

7.2 监听用ref声明的数据源

<script lang="ts">
import { defineComponent, ref, watch } from 'vue';
interface Person {
 name: string,
 age: number
}
export default defineComponent({
 setup(props, context) {
  const age = ref<number>(10);

  watch(age, () => console.log(age.value)); // 100
  
  // 修改age 时会触发watch 的回调, 打印变更后的值
  age.value = 100
  return {
   age
  }
 }
});
</script>

7.3 同时监听多个值

<script lang="ts">
import { computed, defineComponent, reactive, toRefs, watch } from 'vue';
interface Person {
 name: string,
 age: number
}
export default defineComponent({
 setup(props, context) {
  const state = reactive<Person>({ name: 'vue', age: 10 })

  watch(
   [() => state.age, () => state.name],
   ([newName, newAge], [oldName, oldAge]) => {
    console.log(newName);
    console.log(newAge);

    console.log(oldName);
    console.log(oldAge);
   }
  )
  // 修改age 时会触发watch 的回调, 打印变更前后的值, 此时需要注意, 更改其中一个值, 都会执行watch的回调
  state.age = 100
  state.name = 'vue3'
  return {
   ...toRefs(state)
  }
 }
});
</script>

7.4 stop 停止监听

在 setup() 函数内创建的 watch 监视,会在当前组件被销毁的时候自动停止。如果想要明确地停止某个监视,可以调用 watch() 函数的返回值即可,语法如下:

<script lang="ts">
import { set } from 'lodash';
import { computed, defineComponent, reactive, toRefs, watch } from 'vue';
interface Person {
 name: string,
 age: number
}
export default defineComponent({
 setup(props, context) {
  const state = reactive<Person>({ name: 'vue', age: 10 })

  const stop = watch(
   [() => state.age, () => state.name],
   ([newName, newAge], [oldName, oldAge]) => {
    console.log(newName);
    console.log(newAge);

    console.log(oldName);
    console.log(oldAge);
   }
  )
  // 修改age 时会触发watch 的回调, 打印变更前后的值, 此时需要注意, 更改其中一个值, 都会执行watch的回调
  state.age = 100
  state.name = 'vue3'

  setTimeout(()=> { 
   stop()
   // 此时修改时, 不会触发watch 回调
   state.age = 1000
   state.name = 'vue3-'
  }, 1000) // 1秒之后讲取消watch的监听
  
  return {
   ...toRefs(state)
  }
 }
});
</script>

八、LifeCycle Hooks(新的生命后期)

新版的生命周期函数,可以按需导入到组件中,且只能在 setup() 函数中使用, 但是也可以在setup 外定义, 在 setup 中使用

<script lang="ts">
import { set } from 'lodash';
import { defineComponent, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onErrorCaptured, onMounted, onUnmounted, onUpdated } from 'vue';
export default defineComponent({
 setup(props, context) {
  onBeforeMount(()=> {
   console.log('beformounted!')
  })
  onMounted(() => {
   console.log('mounted!')
  })

  onBeforeUpdate(()=> {
   console.log('beforupdated!')
  })
  onUpdated(() => {
   console.log('updated!')
  })

  onBeforeUnmount(()=> {
   console.log('beforunmounted!')
  })
  onUnmounted(() => {
   console.log('unmounted!')
  })

  onErrorCaptured(()=> {
   console.log('errorCaptured!')
  })

  return {}
 }
});
</script>

九、Template refs

通过refs 来回去真实dom元素, 这个和react 的用法一样,为了获得对模板内元素或组件实例的引用,我们可以像往常一样在setup()中声明一个ref并返回它

  • 还是跟往常一样,在 html 中写入 ref 的名称
  • 在steup 中定义一个 ref
  • steup 中返回 ref的实例
  • onMounted 中可以得到 ref的RefImpl的对象, 通过.value 获取真实dom
<template>
 <!--第一步:还是跟往常一样,在 html 中写入 ref 的名称-->
 <div class="mine" ref="elmRefs">
  <span>1111</span>
 </div>
</template>

<script lang="ts">
import { set } from 'lodash';
import { defineComponent, onMounted, ref } from 'vue';
export default defineComponent({
 setup(props, context) {
  // 获取真实dom
  const elmRefs = ref<null | HTMLElement>(null);
  onMounted (() => {
   console.log(elmRefs.value); // 得到一个 RefImpl 的对象, 通过 .value 访问到数据
  })

  return {
   elmRefs
  }
 }
});
</script>

十、vue 的全局配置

通过vue 实例上config来配置,包含Vue应用程序全局配置的对象。您可以在挂载应用程序之前修改下面列出的属性:

const app = Vue.createApp({})

app.config = {...}

为组件渲染功能和观察程序期间的未捕获错误分配处理程序。错误和应用程序实例将调用处理程序

app.config.errorHandler = (err, vm, info) => {}

可以在应用程序内的任何组件实例中访问的全局属性,组件的属性将具有优先权。这可以代替Vue 2.xVue.prototype扩展:

const app = Vue.createApp({})

app.config.globalProperties.$http = 'xxxxxxxxs'

可以在组件用通过 getCurrentInstance() 来获取全局globalProperties 中配置的信息,getCurrentInstance 方法获取当前组件的实例,然后通过 ctx 属性获得当前上下文,这样我们就能在setup中使用router和vuex, 通过这个属性我们就可以操作变量、全局属性、组件属性等等

setup( ) {
 const { ctx } = getCurrentInstance();
 ctx.$http  
}

十一、Suspense 组件

在开始介绍 Vue 的 Suspense 组件之前,我们有必要先了解一下 React 的 Suspense 组件,因为他们的功能类似。

React.lazy 接受一个函数,这个函数需要动态调用 import()。它必须返回一个 Promise,该 Promise 需要 resolve 一个 default export 的 React 组件。

import React, { Suspense } from 'react';
 
 
const myComponent = React.lazy(() => import('./Component'));
 
 
function MyComponent() {
 return (
  <div>
   <Suspense fallback={<div>Loading...</div>}>
    <myComponent />
   </Suspense>
  </div>
 );
}

Vue3 也新增了 React.lazy 类似功能的 defineAsyncComponent 函数,处理动态引入(的组件)。defineAsyncComponent可以接受返回承诺的工厂函数。当您从服务器检索到组件定义时,应该调用Promise的解析回调。您还可以调用reject(reason)来指示负载已经失败

import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() =>
 import('./components/AsyncComponent.vue')
)

app.component('async-component', AsyncComp)

Vue3 也新增了 Suspense 组件:

<template>
 <Suspense>
  <template #default>
   <my-component />
  </template>
  <template #fallback>
   Loading ...
  </template>
 </Suspense>
</template>

<script lang='ts'>
 import { defineComponent, defineAsyncComponent } from "vue";
 const MyComponent = defineAsyncComponent(() => import('./Component'));

export default defineComponent({
  components: {
   MyComponent
  },
  setup() {
   return {}
  }
})

</script>

十二、vue 3.x 完整组件模版结构

一个完成的vue 3.x 完整组件模版结构包含了:组件名称、 props、components、setup(hooks、computed、watch、methods 等)

<template>
 <div class="mine" ref="elmRefs">
  <span>{{name}}</span>
  <br>
  <span>{{count}}</span>
  <div>
   <button @click="handleClick">测试按钮</button>
  </div>

  <ul>
   <li v-for="item in list" :key="item.id">{{item.name}}</li>
  </ul>
 </div>
</template>

<script lang="ts">
import { computed, defineComponent, getCurrentInstance, onMounted, PropType, reactive, ref, toRefs } from 'vue';

interface IState {
 count: 0,
 name: string,
 list: Array<object>
}

export default defineComponent({
 name: 'demo',
 // 父组件传子组件参数
 props: {
  name: {
   type: String as PropType<null | ''>,
   default: 'vue3.x'
  },
  list: {
   type: Array as PropType<object[]>,
   default: () => []
  }
 },
 components: {
  /// TODO 组件注册
 },
 emits: ["emits-name"], // 为了提示作用
 setup (props, context) {
  console.log(props.name)
  console.log(props.list)
  
  
  const state = reactive<IState>({
   name: 'vue 3.0 组件',
   count: 0,
   list: [
    {
     name: 'vue',
     id: 1
    },
    {
     name: 'vuex',
     id: 2
    }
   ]
  })

  const a = computed(() => state.name)

  onMounted(() => {

  })

  function handleClick () {
   state.count ++
   // 调用父组件的方法
   context.emit('emits-name', state.count)
  }
 
  return {
   ...toRefs(state),
   handleClick
  }
 }
});
</script>

vue 3 的生态

  • 官网
  • 源码
  • vite构建器
  • 脚手架:https://cli.vuejs.org/
  • vue-router-next
  • vuex4.0

UI 组件库

vant2.x

Ant Design of Vue 2.x

element-plus

到此这篇关于让你30分钟快速掌握vue3教程的文章就介绍到这了,更多相关vue3 入门内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
复选框全选与全不选操作实现思路
Aug 18 Javascript
JavaScript中的变量定义与储存介绍
Dec 31 Javascript
JavaScript中日期的相关操作方法总结
Oct 24 Javascript
Seajs 简易文档 提供简单、极致的模块化开发体验
Apr 13 Javascript
js调用webservice构造SOAP进行身份验证
Apr 27 Javascript
全面理解闭包机制
Jul 11 Javascript
原生js实现对Ajax的封装(仿jquery)
Jan 22 Javascript
关于javascript sort()排序你可能忽略的一点理解
Jul 18 Javascript
js原生方法被覆盖,从新赋值原生的方法
Jan 02 Javascript
layui点击弹框页面 表单请求的方法
Sep 21 Javascript
React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析
Jan 06 Javascript
浅谈Vue开发人员的7个最好的VSCode扩展
Jan 20 Vue.js
在vue项目中 实现定义全局变量 全局函数操作
Oct 26 #Javascript
vue3+typescript实现图片懒加载插件
Oct 26 #Javascript
原生js实现简单轮播图
Oct 26 #Javascript
vue项目开启Gzip压缩和性能优化操作
Oct 26 #Javascript
Vue检测屏幕变化来改变不同的charts样式实例
Oct 26 #Javascript
解决ant design vue中树形控件defaultExpandAll设置无效的问题
Oct 26 #Javascript
vue下载二进制流图片操作
Oct 26 #Javascript
You might like
php递归实现无限分类生成下拉列表的函数
2010/08/08 PHP
ThinkPHP模板判断输出Defined标签用法详解
2014/06/30 PHP
PHP Session机制简介及用法
2014/08/19 PHP
Windows2003下php5.4安装配置教程(Apache2.4)
2016/06/30 PHP
使用Apache的rewrite
2021/03/09 Servers
js prototype 格式化数字 By shawl.qiu
2007/04/02 Javascript
javascript 实用的文字链提示框效果
2010/06/30 Javascript
由JavaScript中call()方法引发的对面向对象继承机制call的思考
2011/09/12 Javascript
jquery+javascript编写国籍控件
2015/02/12 Javascript
jQuery中prepend()方法使用详解
2015/08/11 Javascript
BootStrap智能表单实战系列(六)表单编辑页面的数据绑定
2016/06/13 Javascript
Bootstrap 手风琴菜单的实现代码
2017/01/20 Javascript
JavaScript实现的原生态Tab标签页功能【兼容IE6】
2017/09/18 Javascript
js实现微信/QQ直接跳转到支付宝APP打开口令领红包功能
2018/01/09 Javascript
vue使用keep-alive保持滚动条位置的实现方法
2019/04/09 Javascript
微信小程序实现带参数的分享功能(两种方法)
2019/05/17 Javascript
使用webpack搭建pixi.js开发环境
2020/02/12 Javascript
Vue打包部署到Nginx时,css样式不生效的解决方式
2020/08/03 Javascript
vuecli项目构建SSR服务端渲染的实现
2020/10/30 Javascript
JavaScript实现下拉列表
2021/01/20 Javascript
[04:59]DOTA2-DPC中国联赛 正赛 Ehome vs iG 选手采访
2021/03/11 DOTA
python实用代码片段收集贴
2015/06/03 Python
Python 字典与字符串的互转实例
2017/01/13 Python
Python爬虫框架Scrapy实例代码
2018/03/04 Python
PyCharm代码整体缩进,反向缩进的方法
2018/06/25 Python
Django Rest framework之权限的实现示例
2018/12/17 Python
详解python:time模块用法
2019/03/25 Python
75条笑死人的知乎神回复,用60行代码就爬完了
2019/05/06 Python
Python matplotlib绘制饼状图功能示例
2019/09/10 Python
纯CSS3实现漂亮的input输入框动画样式库(Text input love)
2018/12/29 HTML / CSS
前端canvas动画如何转成mp4视频的方法
2019/06/17 HTML / CSS
如何掌握自荐信格式呢
2013/11/19 职场文书
党员公开承诺事项
2014/03/25 职场文书
感谢信格式范文
2015/01/22 职场文书
go web 预防跨站脚本的实现方式
2021/06/11 Golang
一起来看看Vue的核心原理剖析
2022/03/24 Vue.js