ts + setup
本文是对
vue3.x
语法的实践,不会单独的介绍某个具体的API
语法,详细语法请参考 vue官网;此次文章中使用的是script setup + ts
的用法,个人比较喜欢的一种语法,感觉是vue3
关于ts
的终极实践。
顶层属性
任何在 script setup
声明的顶层的绑定 (包括变量,函数声明,以及 import 引入的内容) 都能在模板中直接使用; 但仅仅是使用,由于不是响应式数据,没有双向绑定,所以不会在页面上同步更新。
<template>
<div>
<h1>{{ hello }}</h1>
<p>
{{ count }}
<button @click="handleClick">add</button>
</p>
</div>
</template>
<script lang="ts" setup>
// 如果只是单类型,则 vue 会自动推到,不用加类型
let hello: string | undefined = "hello, vue";
// vue 根据后面的值,自动推导。
let count = 0;
function handleClick(): void {
console.log(count);
count++;
}
</script>
响应式数据
ref
: 用来给基本数据类型
绑定响应式数据,访问时需要通过.value
的形式,tamplate
不需要.value
,会被解析。reactive
: 用来给复杂数据类型
绑定响应式数据,直接访问即可。
<template>
<div>
<h1>{{ title }}</h1>
<p>
当前等级:{{ count }}
<button @click="handleAdd">升级</button>
</p>
<p>宠物:{{ userInfo.pet }}</p>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive } from "vue";
// 设置基本数据类型时,使用 ref
const title = ref<string>("响应式数据");
// 也可以根据设置的默认数据推导当前类型
let count = ref(0);
// 用户信息 --- reactive 用来绑定复杂数据类型
interface IUserInfo {
name: string,
pet: string | undefined,
level: number
}
const userInfo = reactive<IUserInfo>({
name: "zs",
level: 0,
pet: undefined,
})
// 升级
function handleAdd(): void {
count.value++;
// 复杂数据类型,不需要通过 .value 的形式获取数据
userInfo.level = count.value;
userInfo.pet = count.value >= 5 ? '马' : undefined; // 达到 5 级 解锁宠物
}
</script>
使用 watch
优化上面的例子
- 从
vue
中结构watch
; watch
是一个函数,可以一次写多个,也可以一次性监听多个例子;
<template>
<div>
<h1>{{ title }}</h1>
<p>
当前等级:{{ count }}
<button @click="handleAdd">升级</button>
</p>
<p>宠物:{{ userInfo.pet }}</p>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, watch } from "vue";
// 设置基本数据类型时,使用 ref
const title = ref<string>("响应式数据");
// 也可以根据设置的默认数据推导当前类型
let count = ref(0);
// 用户信息 --- reactive 用来绑定复杂数据类型
interface IUserInfo {
name: string,
pet: string | undefined,
level: number
}
const userInfo = reactive<IUserInfo>({
name: "zs",
level: 0,
pet: undefined,
})
// 使用 watch 监听 count 的变化
watch(count, (nl, od) => {
if (nl >= 5) {
userInfo.level = count.value;
userInfo.pet = count.value >= 5 ? '马' : undefined; // 达到 5 级 解锁宠物
}
})
// 升级
function handleAdd(): void {
count.value++;
}
</script>
使用 computed
<template>
<div>
<h1>{{ title }}</h1>
<p>
当前等级:{{ count }}
<button @click="handleAdd">升级</button>
</p>
<p>宠物:{{ userInfo.pet }}</p>
<p>{{ showAddictionPrevention }}</p>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, watch, computed } from "vue";
// 设置基本数据类型时,使用 ref
const title = ref<string>("响应式数据");
// 也可以根据设置的默认数据推导当前类型
let count = ref(0);
// 用户信息 --- reactive 用来绑定复杂数据类型
interface IUserInfo {
name: string,
pet: string | undefined,
level: number
}
const userInfo = reactive<IUserInfo>({
name: "zs",
level: 0,
pet: undefined,
})
// 是否显示防沉迷
const showAddictionPrevention = computed(() => {
if (count.value === 0) return "Welcome";
if (count.value >= 5) return "登录时间过长";
return '';
})
// watch: 监听一个属性;
watch(count, (nl, od) => {
if (nl >= 5) {
userInfo.level = count.value;
userInfo.pet = count.value >= 5 ? '马' : undefined; // 达到 5 级 解锁宠物
}
})
// 升级
function handleAdd(): void {
count.value++;
}
</script>
使用生命周期
将 生命周期方法
从 vue
结构后,它是一个函数,传入 callback
后即可执行。
<template>
<div>
<h1>{{ title }}</h1>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from "vue";
// 设置基本数据类型时,使用 ref
const title = ref<string>("Props And Emits");
onMounted(() => {
console.log("加载完成...");
});
</script>
props and emit
这是基于 ts
的写法,所以按照泛型的形式传入,如果不是 ts
,可以按照 vue
的语法进行实现。
<!-- Father.vue -->
<template>
<div>
<h1>{{ title }}</h1>
<Child :count="count" @change="handleChange"/>
</div>
</template>
<script lang="ts" setup>
import { ref, } from "vue";
// 子组件不需要注册,可以直接使用
import Child from "./Child.vue";
// 设置基本数据类型时,使用 ref
const title = ref<string>("Props And Emits");
const count = ref<number>(1);
function handleChange(val: number):void {
count.value = val;
}
</script>
<!-- Child.vue -->
<template>
<div>
<h2>Child</h2>
<p>{{ props.count }}</p>
<button @click="handleAdd">add</button>
</div>
</template>
<script lang="ts" setup>
import { defineProps, defineEmits } from "vue";
// 使用
interface IProps {
count: number
}
const props = defineProps<IProps>();
const emit = defineEmits<{
(event: 'change', total: number): void
}>()
function handleAdd(): void {
emit("change", props.count + 1);
}
</script>