vue3实战

330 阅读3分钟

vue3相关文档

在这里插入图片描述 开源项目

vue-pure-admin (opens new window)是使用vue3 vite2 Element-Plus TypeScript

展示一下官网api,以及使用

  • 应用配置

    1. errorHandler
    2. warnHandler
    3. globalProperties
    4. optionMergeStrategies
    5. performance
    6. compilerOptions 3.1+
  • 应用API

    1. component
    2. config
    3. directive
    4. mixin
    5. mount
    6. provide
    7. unmount
    8. use
    9. version
  • 全局API

    1. createApp
    2. h
    3. defineComponent
    4. defineAsyncComponent
    5. defineCustomElement
    6. resolveDynamicComponent
    7. resolveDirective
    8. withDirectives
    9. createRenderer
    10. nextTick
    11. mergeProps
    12. useCssModule
    13. ersion
  • 选项

    1. Data
      • data
      • props
      • computed
      • methods
      • watch
      • emits
      • expose
    2. DOM
      • template
      • render
    3. 生命周期钩子
      • beforeCreate
      • created
      • beforeMount
      • mounted
      • beforeUpdate
      • updated
      • activated
      • deactivated
      • beforeUnmount
      • unmounted
      • errorCaptured
      • renderTracked
      • renderTriggered
    4. 选项/资源
      • directives
      • components
    5. 组合
      • mixins
      • extends
      • provide inject
      • setup
    6. 杂项
      • name
      • inheritAttrs
      • compilerOptions
      • delimiters
  • 实例property

    1. $data
    2. $props
    3. $el
    4. $options
    5. $parent
    6. $root
    7. $slots
    8. $refs
    9. $attrs
  • 实例方法

    1. $watch
    2. $emit
    3. $forceUpdate
    4. $nextTick
  • 指令

    1. v-text
    2. v-html
    3. v-show
    4. v-if
    5. v-else
    6. v-else-if
    7. v-for
    8. v-on
    9. v-bind
    10. v-model
    11. v-slot
    12. v-pre
    13. v- cloak
    14. v-once
    15. v-memo
    16. v-is
  • 特殊attribute

    1. key
    2. ref
    3. is
  • 内置组件

    1. component
    2. transition
    3. transition-group
    4. keep-alive
    5. slot
    6. teleport
  • 响应性API

    1. 响应性基础 API
    2. Refs
    3. Computed 与 watch
    4. Effect 作用域 API
  • 组合式API

    1. setup
    2. 生命周期钩子
    3. Provide / Inject
    4. getCurrentInstance
  • 单文件组件

    1. 规范
    2. 工具
    3. <script setup>
    4. 特性

api使用方法

<body>
    <div id="app">
        <button @click="add">afdas</button>
        {{count}}  {{doubleCount}}
    </div>
    <script>
        const { reactive, createApp, computed, watch, onMounted, ref , toRefs } = Vue
        createApp({
            setup() {
                // 在这里写代码
            }
        }).mount('#app')
    </script>
</body>

globalProperties

app.config.globalProperties.foo = 
getCurrentInstance().proxy.foo // 'bar'

ref

<template>
	<div>{{a}}</div> <div>{{b}}</div>
</template>
import { ref } from '@vue/runtime-core'
setup(props){
   let a = ref(0);{ _isRef:true,value:1 }
   let b = ref(0);
   console.log(a.value,b.value)
   return {
     a,
     b
   }
 }
<template>
	<div>{{obj.a}}</div> <div>{{obj.b}}</div>
</template>
import { ref } from '@vue/runtime-core'
setup(props){
   let obj = ref({
     a:0,
     b:0
   })
   console.log(obj.a.value , obj.b.value)
   return {
     obj
   }
 }

unref

let supNum= ref(0)
console.log(unref(supNum)) // 0
val = isRef(val) ? val.value : val

toRefs

<template>
	<div>{{a}}</div> <div>{{b}}</div>
</template>
import { reactive , toRefs } from '@vue/runtime-core'
setup(props){
   let obj = reactive({
     a:10,
     b:20
   })
   obj.a = 1
   obj.b = 2
   return {
      ...toRefs(obj) //一个,则用toRef(obj, 'foo')
   }
 }

reactive

<template>
	<div>{{state.supNum}}</div> <div>{{state.oppNum}}</div>
</template>
import { reactive } from '@vue/runtime-core'
setup(props){
   let state = reactive({
     supNum:0,
     oppNum:0
   })   
   function change(lx){
     lx === 0 ? state.supNum++ : state.oppNum++;
   }
   return {
     state,
     change
   }
 }

toRaw

const foo = {}
const reactiveFoo = reactive(foo)
toRaw(reactiveFoo) === foo // true

readonly

readonly(
    reactive({ count: 0 })
).count ++ // 变更副本将失败并导致警告

isProxy

isProxy(reactive({ count: 0 })) //true

isReactive

isReactive(reactive({ count: 0 })) //true

isReadonly

isReadonly(readonly(reactive({ count: 0 }))) // true

computed

// computed值不可以直接修改,否则报错 
const plusOne = computed(()=>ref(0).value + 1)
plusOne.value // 2
plusOne++  
// 修改computed值方案
const count = ref(1);
const plusOne = computed({
    get:()=>count.value + 2,
    set:val => {count.value = val - 1 }
})
plusOne.value = 1 ;// 设置
console.log(plusOne.value);// 2 

生命周期函数

beforeCreate         setup
created              setup
beforeMount          onBeforeMount
mounted              onMounted
beforeUpdate         onBeforeUpdate
updated              onUpdated
beforeDestroy        onBeforeUnmount
destroyed            onUnmounted
errorCaptured        onErrorCaptured

定义组件

import { h, defineComponent } from "vue";
var IconifyIconOffline =  defineComponent({
  name: "IconifyIcon",
  components: { IconifyIcon },//这是另外一个组件
  props: {
    icon: {
      type: String,
      default: ""
    }
  },
  render() {
    const attrs = this.$attrs;
    return h(
      IconifyIcon,
      {
        icon: `${this.icon}`,
        ...attrs
      },
      {
        default: () => []
      }
    );
  }
});
const app = createApp(App);
app.component("IconifyIconOffline", IconifyIconOffline);
app.mount("#app");

安装的vscode插件

在这里插入图片描述

Ts

为什么 Vue 3 是用 TypeScript 编写的??? 静态类型系统可以帮助防止许多潜在的运行时错误

定义 Vue 组件 要让 TypeScript 正确推断 Vue 组件选项中的类型,需要使用 defineComponent 全局方法定义组件:

import { defineComponent } from 'vue'
const Component = defineComponent({
  // 已启用类型推断
})

如果你使用的是单文件组件,则通常会被写成:

<script lang="ts">
	import { defineComponent } from 'vue'
	export default defineComponent({
	  // 已启用类型推断
	})
</script>

在写vue的ts代码时候,很明显代码提示变强了 与 Options API 一起使用 对一个数字 做split操作时候,ts立马检测出错误来

this.count.split('') // => Property 'split' does not exist on type 'number'

如果你有一个复杂的类型或接口,你可以使用 type assertion 对其进行指明

interface Book {
  title: string
  year: number
}
const Component = defineComponent({
  data() {
    return {
      book: {
        title: 'Vue 3 Guide',     
        year: 2020
      } as Book
    }
  }
})

为 globalProperties 扩充类型

Vue 3 提供了一个 globalProperties 对象,用来添加可以被任意组件实例访问的全局 property。例如一个插件想要注入一个共享全局对象或函数。

// 用户定义

import axios from 'axios'
const app = Vue.createApp({})
app.config.globalProperties.$http = axios
// 验证数据的插件
export default {
  install(app, options) {
    app.config.globalProperties.$validate = (data: object, rule: object) => {
      // 检查对象是否合规
    }
  }
}

为了告诉 TypeScript 这些新 property,我们可以使用模块扩充 (module augmentation)。

在上述示例中,我们可以添加以下类型声明:

import axios from 'axios'
declare module '@vue/runtime-core' {
  export interface ComponentCustomProperties {
    $http: typeof axios
    $validate: (data: object, rule: object) => boolean
  }
}

我们可以把这些类型声明放在同一个文件里,或一个项目级别的 *.d.ts 文件 (例如在 TypeScript 会自动加载的 src/typings 文件夹中)。对于库/插件作者来说,这个文件应该被定义在 package.json 的 types property 里。

//node_modules/vue-router/package.json
{
    "types": "dist/vue-router.d.ts",
}

"types": "dist/vue-router.d.ts",

当命令行上指定了输入文件时,tsconfig.json文件会被忽略。 在声明文件tsconfig.json的exclude和include或者使用files字段下指定要检测的文件路径; files 只能使用相对路径 或者绝对路径

include/exclude 可以使用模糊匹配的字符代替 某一特征名的文件 点击下方链接查看说明

官网有说明,点这里查看

tsconfig.json文件可以是个空文件,那么所有默认的文件都会以默认配置选项编译。

默认所有可见的"@types"包会在编译过程中被包含进来,包括node_modules 内所有的

如果指定了typeRoots,只有typeRoots下面的包才会被包含进来
{
   "compilerOptions": {
       "typeRoots" : ["./typings"]
   }
}
如果指定了types,只有被列出来的包才会被包含进来
这个tsconfig.json文件将仅会包含 ./node_modules/@types/node,./node_modules/@types/lodash和./node_modules/@types/express
{
   "compilerOptions": {
        "types" : ["node", "lodash", "express"]
   }
}

默认所有可见的"@types"包会在编译过程中被包含进来 简单说就是 这样./node_modules/@types/,../node_modules/@types/和../../node_modules/@types/ 指定"types": [ ]来禁用自动引入@types包

可以继承别的包属性
 "extends": "./configs/base",

常用ts错误信息表

vite

基于浏览器原生ES imports的开发服务器,利用浏览器去解析imports,在服务器端按需编译返回,完全 跳过了打包这个概念,服务器随其随用 同时不仅有vue文件支持,还搞定了热更新,而且热更新的速度不会随着模块增加而变慢

vite官网

使用vite创建vue项目 create-vite-app包

npm init @vitejs/app <project-name>//可以选择创建vue项目  也可以创建react项目
cd <project-name>
npm install
npm run dev