avatar

关于vue3

vue3 官方文档

https://www.vue3js.cn/docs/zh/guide/list.html

https://www.vue3js.cn/docs/zh/guide/migration/introduction.html#%E6%A6%82%E8%A7%88

Vue JSON Schema Form

https://github.com/lljj-x/vue-json-schema-form

https://vue-json-schema-form.lljj.me/zh/guide/basic-config.html

安装 与 配置

当前 node 版本 10.16.3

安装 vue/cli

安装的版本是 4.5.10

视频版本是 4.5.6 最新的话 当前是 4.5.4

执行 npm i -g @vue/cli

创建项目

执行 vue create 项目名称

选择 vue3 配置

vue3: babel ts,eslint,unit-jest

默认:babel eslint
,

  • 然后 选择 3.x(preview)

  • use class-style (n)

  • use babel alongside TypeScript (y)

  • pick a linter / formatter config:(ESLint + Prettier)

  • pick additional lint features:(all select)

  • pick a unit testing solution : (Jest)

  • where do you prefer placing config for babel,eslint,etc.?(in dedicated config files)

  • save this as a preset for the future projects?(y) 命名

  • pick the package manager to use when installing dependencies:(use yarn) 默认使用 yarn 效率高 性能好 速度快

代码格式化工具 prettier

Prettier 说自己是一个 Opinionated code formatter,就是说:你必须认同我的观点,按照我说的做。否则你就别用我,硬着头皮用就会处处不爽!

固执己见的 prettier

  • An opinionated code formatter
  • Supports many languages 支持很多语言
  • Integrates with most editors 可以和很多 IDE 集成,例如 vscode、 subline Text
  • Has few options 有一些选项

其实就是 Opinionated 的最直接体现。除了必要的设置项,不会再给你们更多。给你设置项越多,你们越乱,你们就会继续争吵!

苹果手机就一个 Home 键,老子就这样,接受不了的滚去安卓。安卓三个键,左侧是返回键,右侧是属性键?你换手机的时候可不一定是这样,你还要手动设置成自己习惯的。偶尔用一下别人的安卓,可能就和你的不一样。键多了就形成了混乱,还是一个键好。这也是 Prettier 的设计哲学,Prettier 就是代码格式化工具中的 Apple。

图解

上图左侧是手写代码,中间是 AST(去掉了任何代码风格),右侧是重新输出的结果。

Prettier 就是在这个 AST 上重新按照自己的风格输出代码。

项目中配置 prettier

创建文件

目录下创建 .prettier

给予一些配置

1
2
3
4
5
6
{
"semi": false,
"singleQuote": true,
"arrowParens": "always",
"trailingComma": "all"
}

在编辑器去配置一下

勾选 format on save

推荐:workspace 工作区 当前项目应用

勾选完 会在项目里生成一个 .vscode 文件夹 里面就有配置

我本身的 vscode 配置 会根据 eslint 格式化

用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
// vscode默认启用了根据文件类型自动设置tabsize的选项
"editor.detectIndentation": false,
// 重新设定tabsize
"editor.tabSize": 2,
// #每次保存的时候自动格式化
"editor.formatOnSave": true,
//编辑器默认的代码检查规则关闭
"javascript.format.enable": true,
// #去掉代码结尾的分号
"prettier.semi": false,
// #使用带引号替代双引号
"prettier.singleQuote": true,
// #让函数(名)和后面的括号之间加个空格
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
// #这个按用户自身习惯选择
"vetur.format.defaultFormatter.html": "js-beautify-html",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.format.enable": true,
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"prettier.vueIndentScriptAndStyle": true,
"prettier.requireConfig": true,
"explorer.confirmDelete": false,
// "[vue]": {
// "editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
// },
}

工作区:

1
// 自由配置

开始学习

定义组件

defineComponent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { defineComponent, PropType } from 'vue'
import HelloWorld from './components/HelloWorld.vue'

interface Config {
name: string
}

export default defineComponent({
name: 'App',
props: {
age: {
type: Number as PropType<number>,
},
config: {
type: Object as PropType<Config>,
required: true,
},
},
components: {
HelloWorld,
},
data() {
return {
name: 'jokcy',
}
},
mounted() {
this.config
},
})

如何提取 props 定义

1
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App" :age="12" />
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

<template>
<div class="hello">
{{ msg }}
<br />
{{ age }}
</div>
</template>


const PropType = {
msg: {
type: String,
},
age: {
type: Number,
},
}
export default defineComponent({
name: 'HelloWorld',
props: PropType,
mounted() {
this.age
},
})
</script>

关于 h 函数()

参数

  • 节点类型
  • 节点属性
  • 子节点

type props children

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { createApp, defineComponent, h } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
const img = require('./assets/logo.png') //eslint-disable-line

const App = defineComponent({
render() {
return h('div', { id: 'app' }, [
h('img', {
alt: 'Vue logo',
src: img,
}),
h(HelloWorld, {
msg: 'Welcome to Your Vue.js + TypeScript App',
age: 12,
}),
])
},
})

createApp(App).mount('#app')

createVNode

上面的 h()可以改成 createVNone 是一样的

参数:type props children patchFlag dynamicProps isBlockNode

setup 的运用和其意义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 获取名字 {{state.name}}

setup(props, {slots,attrs, emit}){

const state = reactive({
name:'jocky'
})

setInterval(()=>{
state.name +='1'
},1000)
return {
state
}
}

使用 ref

1
import {ref} form 'vue';
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// {{name}}
setup(props, {slots,attrs, emit}){

//{value:xxx}
const nameRef = ref('jokcy')

setInterval(()=>{
state.name +='1'
},1000)

return {
name:nameRef
}
}

computed

1
import {ref computed} form 'vue';
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// {{name}}:{{name2}}
setup(props, {slots,attrs, emit}){

//{value:xxx}
const nameRef = ref('jokcy')

setInterval(()=>{
state.name +='1'
},1000)
const computedNameRef = computed(()=>{
return nameRef.value + '2'
})
return {
name:nameRef,
name2:computedNameRef
}
}

watchEffect

1
import {watchEffect} form 'vue';

nameRef 变化后执行操作

1
2
3
watchEffect(() => {
console.log(nameRef.value)
})

setup 返回 render 函数的用法

setup 只会执行一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { createApp, defineComponent, h, reactive, ref } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
const img = require('./assets/logo.png') //eslint-disable-line

const App = defineComponent({
setup() {
const state = reactive({
name: 'jokcy',
})

const numberRef = ref(123)
// 初始化

return () => {
// 在这
return h('div', { id: 'app' }, [
h('img', {
alt: 'Vue logo',
src: img,
}),
h('p', state.name + numberRef.value),
])
}
},
})

createApp(App).mount('#app')

区别

观察下面的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { createApp, defineComponent, h, reactive, ref } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
const img = require('./assets/logo.png') //eslint-disable-line

const App = defineComponent({
setup() {
const state = reactive({
name: 'jokcy',
})

const numberRef = ref(123)
setInterval(() => {
numberRef.value += 1
}, 1000)
const number = numberRef.value
return () => {
return h('div', { id: 'app' }, [
h('img', {
alt: 'Vue logo',
src: img,
}),
h('p', state.name + number),
])
}
},
})

createApp(App).mount('#app')

第二个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { createApp, defineComponent, h, reactive, ref } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
const img = require('./assets/logo.png') //eslint-disable-line

const App = defineComponent({
setup() {
const state = reactive({
name: 'jokcy',
})

const numberRef = ref(123)
setInterval(() => {
numberRef.value += 1
}, 1000)

return () => {
const number = numberRef.value
return h('div', { id: 'app' }, [
h('img', {
alt: 'Vue logo',
src: img,
}),
h('p', state.name + number),
])
}
},
})

createApp(App).mount('#app')

第二个会实时变化 第一个不会

使用 jsx 开发 vue3 组件(推荐)

两种 jsx 库:

  • vueComponent/jsx (推荐)
  • HcySunYang/vue-next-jsx

jsx-next

安装 yarn add @vue/babel-plugin-jsx -D

github 地址: https://github.com/vuejs/jsx-next

然后在 babel.confing.js 里配置

1
plugins: ['@vue/babel-plugin-jsx'],

入口 main.ts

1
2
3
4
5
import { createApp } from 'vue'

import App from './App'

createApp(App).mount('#app')

文件 App.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { defineComponent, reactive, ref } from 'vue'
const img = require('./assets/logo.png') //eslint-disable-line

const App = defineComponent({
setup() {
const state = reactive({
name: 'jokcy',
})
const numberRef = ref(1)
setInterval(() => {
numberRef.value += 1
}, 1000)

return () => {
const number = numberRef.value

return (
<div id="app">
<img src={img} alt="Vue logo"></img>
<p>{state.name + number}</p>
</div>
)
}
},
})

export default App

为什么 vscode 没有对 props 类型进行提醒

因为.vue 文件 不是 ts 去支持和识别 我们定义出来的类型 所以没有提醒

解决 改成 tsx 开发 那编辑器就会自然提醒

json-schema

什么是 json-schema

定义 json 数据的

校验数据

ajv.js.org

json-schema.org

如何试用 ajv 来定义和检验 json-schema

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Node.js require:
const Ajv = require('ajv').default

const schema = {
type: 'object',
properties: {
name: {
type: 'string',
// minLength: 10,
},
age: {
type: 'number',
},
pets: {
type: 'array',
items: {
type: 'string',
},
},
isWorker: {
type: 'boolean',
},
},
}

const ajv = new Ajv() // options can be passed, e.g. {allErrors: true}
const validate = ajv.compile(schema)
const valid = validate({
name: 'jokcy',
age: 12,
pets: ['那么'],
isWorker: true,
})
if (!valid) console.log(validate.errors)

json-schema 的 fomart 和自定义 format

文章作者: 张复明
文章链接: https://hexo.zhangaming.com/2021/01/13/vue-3/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 阿明的博客
打赏
  • 微信
    微信
  • 支付寶
    支付寶

评论