关于此分类

关于初识 vue3分类主要是记录一些通过 vue3 进行的实践与学习记录。

此文主要记录一些在 vue3 中的一些语法改变(只记录composition api语法),当然使用@vue/composition-api插件也可以令vue2适用本文所记录的语法。

本文会随着作者日常使用进行补充及内容修正

数据相关(data)

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
<template>
<div>
<!-- vue模式下展示ref数据不需要加.value -->
<div>当前title:{{ title }}</div>
<input v-model="title" type="text" />
<div>当前用户名:{{ form.name }}</div>
<div>当前用户名:{{ form.password }}</div>
<div>
<input v-model="form.name" type="text" />
<input v-model="form.password" type="text" />
</div>
</div>
</template>

<script lang="ts">
import { ref, reactive } from 'vue'
export default {
setup() {
// 定义响应式普通数据
const title = ref<string>('小康')
// 定义响应式引用数据
const form = reactive({
name: '小康',
password: '12334'
})
// 需要将变量或方法return视图中才可以使用
return { title, form }
}
}
</script>

<style></style>
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
<template>
<div>
<!-- vue模式下展示ref数据不需要加.value -->
<div>当前title:{{ title }}</div>
<input v-model="title" type="text" />
<div>当前用户名:{{ form.name }}</div>
<div>当前用户名:{{ form.password }}</div>
<div>
<input v-model="form.name" type="text" />
<input v-model="form.password" type="text" />
</div>
</div>
</template>

<script lang="ts" setup>
// script setup 模式下视图可以直接使用定义的变量
import { ref, reactive } from 'vue'
// 定义响应式普通数据
const title = ref<string>('小康')
// 定义响应式引用数据
const form = reactive({
name: '小康',
password: '12334'
})
</script>
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, ref, reactive } from 'vue'
export default defineComponent({
setup() {
// 定义响应式普通数据
const title = ref('小康')
// 定义响应式引用数据
const form = reactive({
name: '小康',
password: '12334'
})

return () => {
return (
<div>
<div>当前title:{title.value}</div>
<input type='text' v-model={title.value} />
<div>当前用户名:{form.name}</div>
<div>当前用户名:{form.password}</div>
<div>
<input type='text' v-model={form.name} />
<input type='text' v-model={form.password} />
</div>
</div>
)
}
}
})

自定义 v-model

父组件调用子组件并通过 v-model 绑定一个值,在子组件中直接触发事件进行修改。

emit 使用参考下文

1
2
3
4
5
6
7
8
<div>
<span> v-model-setup 当前title:{{ title }}</span>
<v-model-setup v-model:title="title" />
</div>
<script setup lang="ts">
import { ref } from 'vue'
const title = ref('父组件的标题')
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<button @click="changeTitle">修改传入title值</button>
</template>
<script lang="ts">
export default {
emits: ['update:title'],
// setup参数参考 https://v3.cn.vuejs.org/guide/composition-api-setup.html#%E5%8F%82%E6%95%B0
setup(props, context) {
const changeTitle = () => {
context.emit('update:title', '子组件修改的值')
}
return { changeTitle }
}
}
</script>
1
2
3
4
5
6
7
8
9
10
<template>
<button @click="changeTitle">修改传入title值</button>
</template>
<script setup lang="ts">
// script setup模式下需要使用defineEmits进行定义emit
const emit = defineEmits(['update:title'])
const changeTitle = () => {
emit('update:title', 'script setup子组件修改的值')
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
import { defineComponent } from 'vue'
export default defineComponent({
emits: ['update:title'],
// setup参数参考 https://v3.cn.vuejs.org/guide/composition-api-setup.html#%E5%8F%82%E6%95%B0
setup(props, context) {
const changeTitle = () => {
context.emit('update:title', 'tsx子组件修改的值')
}
return () => {
return <button onClick={changeTitle}>修改父组件的的值</button>
}
}
})

接收父组件的值(props)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { PropType } from 'vue'
export default {
props: {
title: {
type: String as PropType<string>,
required: false,
default: '没有传入title'
}
},
// setup 第一个参数可以取到props
setup(props, context) {
return { props }
}
}
1
2
3
4
5
6
7
8
9
10
11
<script setup lang="ts">
import { PropType } from 'vue'
// script setup模式下需要使用defineProps进行定义emit
const props = defineProps({
title: {
type: String as PropType<string>,
required: false,
default: '没有传入title'
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { defineComponent, PropType } from 'vue'
export default defineComponent({
props: {
title: {
type: String as PropType<string>,
required: false,
default: '没有传入title'
}
},
// setup 第一个参数可以取到props
setup(props, context) {
return () => {
return <div>子组件接收的title的值为:{props.title}</div>
}
}
})

如果需要将props中的值解构,则需要使用toRefs函数

1
const { title } = toRefs(props)

方法相关(methods)

事件相关无太大变化,@eventName="eventFun"即可。

自定义监听事件(emit)

1
2
3
4
5
6
7
8
9
10
11
export default {
// 为了便于维护,定义好触发的emits
emits: ['test'],
// setup参数参考 https://v3.cn.vuejs.org/guide/composition-api-setup.html#%E5%8F%82%E6%95%B0
setup(props, context) {
const changeTitle = () => {
context.emit('test', '子组件修改的值')
}
return { changeTitle }
}
}
1
2
3
4
5
// script setup模式下需要使用defineEmits进行定义emit
const emit = defineEmits(['test'])
const changeTitle = () => {
emit('test', 'script setup子组件修改的值')
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { defineComponent } from 'vue'
export default defineComponent({
// 为了便于维护,定义好触发的emits
emits: ['test'],
// setup参数参考 https://v3.cn.vuejs.org/guide/composition-api-setup.html#%E5%8F%82%E6%95%B0
setup(props, context) {
const changeTitle = () => {
context.emit('test', 'tsx子组件修改的值')
}
return () => {
return <button onClick={changeTitle}>修改父组件的的值</button>
}
}
})

计算属性(computed)和监听器(watch)

更过细节参考

计算属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div>当前value原值{{ val }}</div>
<div>当前计算属性newVal的值{{ newVal }}</div>
<button @click="change">val+1</button>
</template>
<script lang="ts">
import { ref, computed } from 'vue'
export default {
// setup参数参考 https://v3.cn.vuejs.org/guide/composition-api-setup.html#%E5%8F%82%E6%95%B0
setup() {
const val = ref(1)
const newVal = computed(() => {
// 返回val加10的结果
return val.value + 10
})
const change = () => {
val.value += 1
}
return { val, newVal, change }
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<div>当前value原值{{ val }}</div>
<div>当前计算属性newVal的值{{ newVal }}</div>
<button @click="change">val+1</button>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'

const val = ref(1)
const newVal = computed(() => {
// 返回val加10的结果
return val.value + 10
})
const change = () => {
val.value += 1
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { ref, computed, defineComponent } from 'vue'
export default defineComponent({
// setup参数参考 https://v3.cn.vuejs.org/guide/composition-api-setup.html#%E5%8F%82%E6%95%B0
setup() {
const val = ref(1)
const newVal = computed(() => {
// 返回val加10的结果
return val.value + 10
})
const change = () => {
val.value += 1
}
return () => {
return (
<div>
<div>当前value原值{val.value}</div>
<div>当前计算属性newVal的值{newVal.value}</div>
<button onClick={change}>val+1</button>
</div>
)
}
}
})

监听器(watch)

基础用法(监听单个值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { ref, watch } from 'vue'
export default {
// setup参数参考 https://v3.cn.vuejs.org/guide/composition-api-setup.html#%E5%8F%82%E6%95%B0
setup() {
const val = ref(1)

watch(val, () => {
console.log(val.value + '发生了变化')
})
const change = () => {
val.value += 1
}
return { val, change }
}
}
1
2
3
4
5
6
7
8
9
import { ref, watch } from 'vue'

const val = ref(1)
watch(val, () => {
console.log(val.value + '发生了变化')
})
const change = () => {
val.value += 1
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { ref, watch, defineComponent } from 'vue'
export default defineComponent({
// setup参数参考 https://v3.cn.vuejs.org/guide/composition-api-setup.html#%E5%8F%82%E6%95%B0
setup() {
const val = ref(1)
watch(val, () => {
console.log(val.value + '发生了变化')
})
const change = () => {
val.value += 1
}
return () => {
return (
<div>
<div>当前value原值{val.value}</div>
<button onClick={change}>val+1</button>
</div>
)
}
}
})

获取组件引用

在 vue2 中获取引用通过this.$ref,然后 vue3 中并没有this,因此获取 ref 时的方式也发生了变化。

1
<div ref="wrapper"></div>
1
const wrapper = ref<HTMLElement | null>(null)

在 vue3.2 更新中,引用子组件需要在子组件中进行``

1
2
3
4
<script>
const r = ref('test')
defineExpose({ r })
</script>