vue3 + ts

这篇具有很好参考价值的文章主要介绍了vue3 + ts。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在 vue3.2 中,我们只需在script标签中添加setup。就可以做到,组件只需引入不用注册,属性和方法也不用 return 才能于 template 中使用,也不用写setup函数,也不用写export default ,甚至是自定义指令也可以在我们的template中自动获得。

一、模板语法

1.使用 JavaScript 表达式

我们仅在模板中绑定了一些简单的属性名。但是 Vue 实际上在所有的数据绑定中都支持完整的 JavaScript 表达式:

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div :id="`list-${id}`"></div>

2.调用函数

可以在绑定的表达式中使用一个组件暴露的方法:

<span :title="toTitleDate(date)">
  {{ formatDate(date) }}
</span>

3.ref 获取元素

<template>
  <div id="haha" ref="haha"></div>
</template>

得给 ref 指定类型 HTMLElement

setup() {
  let haha = ref<HTMLElement|null>(null)
  console.log(haha)
    
  return {
    haha,
  }
},
haha.style.fontSize = '20px'

4.reactive 

在模板使用直接 {{obj.name}} 即可

修改直接修改 obj[name] = ‘xxx’

ref 和 reactive的区别:

  • ref: 用来给基本数据类型绑定响应式数据,访问时需要通过 .value 的形式, tamplate 会自动解析,不需要 .value

  • reactive: 用来给 复杂数据类型 绑定响应式数据,直接访问即可

<template>
  <div>
    <p>{{title}}</p>
    <h4>{{userInfo}}</h4>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
type Person = {
    name: string;
    age: number;
    gender: string;
};
const title = ref<string>("彼时彼刻,恰如此时此刻");
const userInfo = reactive<Person>({
  name: '树哥',
  age: 18
})
</script>

5.toRefs

setup() {
  const user = reactive({
    name: '小浪',
    age: 21,
  })

  let userObj = toRefs(user)

  return {
    ...userObj,
  }
}

6.ref 和 reactive的区别?

在功能方面,ref 和 reactive,都是可以实现响应式数据!

在语法层面,两个有差异。ref定义的响应式数据需要用[data].value的方式进行更改数据;reactive定义的数据需要[data].[prpoerty]的方式更改数据。

const actTitle: Ref<string> = ref('活动名称');

const actData = reactive({
    list: [],
    total: 0,
    curentPage: 1,
    pageSize: 10
});

actTitle.value = '活动名称2';

actData.total = 100;

但是在应用的层面,还是有差异的,通常来说:单个的普通类型的数据,我们使用ref来定义响应式。表单场景中,描述一个表单的key:value这种对象的场景,使用reactive;在一些场景下,某一个模块的一组数据,通常也使用reactive的方式,定义数据。

那么,对象是不是非要使用reactive来定义呢?其实不是的,都可以,根据自己的业务场景,具体问题具体分析!ref他强调的是一个数据的value的更改,reactive强调的是定义的对象的某一个属性的更改。

7. 周期函数   onMounted

import { defineComponent, ref, onMounted } from 'vue';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        onMounted(() => {
            // 处理业务,一般进行数据请求
        })
        return {
            counter
        }
    }
})

8.store使用

import { useStore } from "vuex";

 const store = useStore();
 const storeData = computed(() => store);          // 配合computed,获取store的值。

import { useStore } from "vuex";
import { defineComponent, ref, computed } from 'vue';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        const store = useStore();
        const storeData = computed(() => store); // 配合computed,获取store的值。
        return {
            counter,
            storeData
        }
    }
})

9.router的使用

        import { useRouter } from "vue-router";

        const router = useRouter();
        const onClick = () => {
            router.push({ name: "AddGift" });
        }

import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { defineComponent, ref, computed } from 'vue';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        const router = useRouter();
        const onClick = () => {
            router.push({ name: "AddGift" });
        }
        return {
            counter,
            onClick
        }
    }
})

10.关注点分离

关注点分离,应该分两层意思:第一层意思就是,Vue3的setup,本身就把相关的数据,处理逻辑放到一起,这就是一种关注点的聚合,更方便我们看业务代码。

第二层意思,就是当setup变的更大的时候,我们可以在setup内部,提取相关的一块业务,做到第二层的关注点分离。

import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { defineComponent, ref, computed } from 'vue';
import useMerchantList from './merchant.js';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        const router = useRouter();
        const onClick = () => {
            router.push({ name: "AddGift" });
        }
        // 在该示例中,我们把获取商家列表的相关业务分离出去。也就是下面的merchant.ts
        const {merchantList} = useMerchantList();
        return {
            counter,
            onClick,
            merchantList
        }
    }
})

merchant.ts    

import { getMerchantlist } from "@/api/rights/gift";
import { ref, onMounted } from "vue";

export default function useMerchantList(): Record<string, any> {
  const merchantList = ref([]);
  const fetchMerchantList = async () => {
    let res = await getMerchantlist({});
    merchantList.value = res.data.child;
  };

  onMounted(fetchMerchantList);

  return {
    merchantList
  };
}

11.interface

使用TS进行业务开发,一个核心的思维是,先关注数据结构,再根据数据结构进行页面开发。以前的前端开发模式是,先写页面,后关注数据。

比如要写一个礼品列表的页面,我们可能要定义这么一些interface。总而言之,我们需要关注的是:页面数据的interface、接口返回的数据类型、接口的入参类型等等。

// 礼品创建、编辑、列表中的每一项,都会是这个数据类型。
interface IGiftItem {
  id: string | number;
  name: string;
  desc: string;
  [key: string]: any;
}

// 全局相应的类型定义
// 而且一般来说,我们不确认,接口返回的类型到底是什么(可能是null、可能是对象、也可能是数组),所以使用范型来定义interface
interface IRes<T> {
    code: number;
    msg: string;
    data: T
}
// 接口返回数据类型定义

interface IGiftInfo {
    list: Array<IGiftItem>;
    pageNum: number;
    pageSize: number;
    total: number;
}

在一个常见的接口请求中,我们一般使用TS这么定义一个数据请求,数据请求的req类型,数据请求的res类型。

export const getGiftlist = (
  params: Record<string, any>
): Promise<IRes<IGiftInfo>> => {
  return Http.get("/apis/gift/list", params);
};

12.支持多个v-model

//父组件
<template>
  <child v-model="name" v-model:email="email" />
  <p>姓名:{{ name }}</p>
  <p>邮箱:{{ email }}</p>
</template>

<script lang="ts" setup>
import child from './child.vue'
import { ref } from 'vue'

const name = ref<string>('张三')
const email = ref<string>('666@qq.com')
</script>
// 子组件
<template>
  <button @click="updateName">更新name</button>
  <button @click="updateEmail">更新email</button>
</template>

<script lang="ts" setup>
// 定义emit
const emits = defineEmits<{
  (e: 'update:modelValue', value: string): void
  (e: 'update:email', value: string): void
}>()

const updateName = () => {
  emits('update:modelValue', '李四')
}

const updateEmail = () => {
  emits('update:email', '123456@qq.com')
}
</script>

如果v-model没有使用参数,则其默认值为modelValue,如上面的第一个v-model,注意此时不再是像Vue2那样使用$emit('input')了,而是统一使用update:xxx的方式。

13.watch   

watch(data,()=>{},{})

  • 参数一,监听的数据

  • 参数二,数据改变时触发的回调函数(newVal,oldVal)

  • 参数三,options配置项,为一个对象

  • 1、监听ref定义的一个响应式数据

<script setup lang="ts">
import { ref, watch } from "vue";

const str = ref('彼时彼刻')

//3s后改变str的值
setTimeout(() => { str.value = '恰如此时此刻' }, 3000)

watch(str, (newV, oldV) => {
  console.log(newV, oldV) //恰如此时此刻 彼时彼刻
})

</script>
  • 2、监听多个ref

这时候写法变为数组形式

<script setup lang="ts">
import { ref, watch } from "vue";

let name = ref('树哥')
let age = ref(18)

//3s后改变值
setTimeout(() => {
  name.value = '我叫树哥'
  age.value = 19
}, 3000)

watch([name, age], (newV, oldV) => {
  console.log(newV, oldV) // ['我叫树哥', 19]  ['树哥', 18]
})

</script>
  • 3、监听Reactive定义的响应式对象

<script setup lang="ts">
import { reactive, watch } from "vue";

let info = reactive({
  name: '树哥',
  age: 18
})

//3s后改变值
setTimeout(() => {
  info.age = 19
}, 3000)

watch(info, (newV, oldV) => {
  console.log(newV, oldV) 
})

</script>
  • 4、监听reactive 定义响应式对象的单一属性

    <script setup lang="ts">
    import { reactive, watch } from "vue";
    
    let info = reactive({
      name: '树哥',
      age: 18
    })
    
    //3s后改变值
    setTimeout(() => {
      info.age = 19
    }, 3000)
    
    
    watch(()=>info.age, (newV, oldV) => {
      console.log(newV, oldV) // 19 18
    }
    
    </script>
  • 停止监听

当 watchEffect 在组件的 setup() 函数或生命周期钩子被调用时,侦听器会被链接到该组件的生命周期,并在组件卸载时自动停止。

但是我们采用异步的方式创建了一个监听器,这个时候监听器没有与当前组件绑定,所以即使组件销毁了,监听器依然存在。

这个时候我们可以显式调用停止监听

<script setup lang="ts">
import { watchEffect } from 'vue'
// 它会自动停止
watchEffect(() => {})
// ...这个则不会!
setTimeout(() => {
  watchEffect(() => {})
}, 100)

const stop = watchEffect(() => {
  /* ... */
})

// 显式调用
stop()
</script>

(以下一样)

不同数据类型的监听

  基础数据类型的监听:

const name = ref<string>('张三')


watch(name, (newValue, oldValue) => {
  console.log('watch===', newValue, oldValue)
})

复杂数据类型的监听:

interface UserInfo {
  name: string
  age: number
}

const userInfo = reactive<UserInfo>({
  name: '张三',
  age: 10
})
// 监听整个对象
watch(userInfo, (newValue, oldValue) => {
  console.log('watch userInfo', newValue, oldValue)
})

// 监听某个属性
watch(() => userInfo.name,  (newValue, oldValue) => {
  console.log('watch name', newValue, oldValue)
})

支持监听多个源

const name = ref<string>('张三')
const userInfo = reactive({
  age: 18
})

// 同时监听name和userInfo的age属性
watch([name, () => userInfo.age]([newName, newAge], [oldName, oldAge]) => {
  // 
})

14.watchwatchEffect区别:

1、watch是惰性执行,也就是只有监听的值发生变化的时候才会执行,但是watchEffect不同,每次代码加载watchEffect都会执行(忽略watch第三个参数的配置,如果修改配置项也可以实现立即执行)

2、watch需要传递监听的对象,watchEffect不需要

3、watch只能监听响应式数据:ref定义的属性和reactive定义的对象,如果直接监听reactive定义对象中的属性是不允许的,除非使用函数转换一下

4、watchEffect如果监听reactive定义的对象是不起作用的,只能监听对象中的属性。

15.computed文章来源地址https://www.toymoban.com/news/detail-469424.html

<template>
  <div>
    <p>{{title}}</p>
    <h4>{{userInfo}}</h4>
    <h1>{{add}}</h1>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive,computed } from "vue";
const count = ref(0)

// 推导得到的类型:ComputedRef<number>
const add = computed(() => count.value +1)

</script>

到了这里,关于vue3 + ts的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3 script setup 语法糖用了才知道有多爽 (一)

    这里是完整的目录图片,由于整篇文章篇幅太长,拆分成了几篇来展示 vue3 使用的越来越广泛, 公司项目开始使用 vue3 ,在 vue 3.2 之后新加入了 script setup 语法糖,上手开始看项目发现对于语法糖的使用有一些迷惑,特此整理,在整理这些内容的同时查阅了大量的资料,自己在这个过程

    2024年02月16日
    浏览(33)
  • vue3组合式api <script setup> props 父子组件的写法

    父组件传入子组个的变量, 子组件是无法直接修改的, 只能通过 emit的方式, 让父组件修改, 之后子组件更新 父组件的写法没有变, 子组件的写法就有很大的变化了

    2024年02月10日
    浏览(42)
  • vue3基础(五)watch(浅监听及深度监听),鼠标及键盘修饰符,v-model,对象写法,class使用数组,字符串模版,自定义组件标签上添加事件无效,使用data时用别名替代,solt输出内容

    监听中的 方法名 与 需要监听的 变量名 一致 如果没有(例如aa), 不会报错 ,但监听不到 所以上图会 输出1 ,而不会输出2 newValue改变后的值,oldValue改变前的值 watch 可以监听 computed 计算属性中的方法,变量等等 点击go按钮,调用change方法修改kk的值,computed中有kk,所以

    2024年02月15日
    浏览(56)
  • Vue教程:如何使用Div标签实现单选框与多选框按钮以便我们随意调整样式

    前言: 在写Vue项目时,我们经常会用到单选框以及复选框,以往我们常用的是Element里面的单选框以及复选框,但是呢这里面的选框都不容易调整,假如我们需要不同的样式以及大小,就很难去实现想要的结果,本章教程就为大家讲解,如何使用div标签去实现单选,多选的这

    2024年01月18日
    浏览(34)
  • vue3获取标签元素

    在Vue2中,我们获取元素都是通过给元素一个  ref  属性,然后通过  this.$refs.xx  来访问的,但这在Vue3中已经不再适用了。 来看看Vue3中是如何获取元素的吧: 获取元素的操作一共分为以下几个步骤: 先给目标元素的  ref  属性设置一个值,假设为  el 然后在  setup  函数中

    2024年02月12日
    浏览(45)
  • Vue3标签(Tag)

    参数 说明 类型 默认值 必传 closable 标签是否可以关闭 boolean false false color 标签颜色,预置多种常用颜色: \\\'success\\\' , \\\'processing\\\' , \\\'error\\\' , \\\'warn\\\' , \\\'pink\\\' , \\\'red\\\' , \\\'yellow\\\' , \\\'orange\\\' , \\\'cyan\\\' , \\\'green\\\' , \\\'blue\\\' , \\\'purple\\\' , \\\'geekblue\\\' , \\\'magenta\\\' , \\\'volcano\\\' , \\\'gold\\\' , \\\'lime\\\' string ‘’ false icon 设置图标 stri

    2024年02月16日
    浏览(34)
  • Vue3 项目中使用setup()函数报错,script setup cannot contain ES module exports

    当使用vue3+vite使用语法糖setup时,要注意写法. 第一种写法就是 script 标签里面配置 setup,另一种是:export default 类里配置 setup() 方法, 我们只需要使用一种方法即可,混用了就会报错了。 解决: 第一种 script setup import {ref} from \\\'vue\\\' import { Toast } from \\\'vant\\\'; import Index from \\\'../pag

    2023年04月08日
    浏览(45)
  • vue3 -- 使用audio标签播放音频

    公司系统内的审批页面,前端要根据后台推送的信息,使用’提示音’提醒用户进行对应审批操作。 vue3 项目 简介 | Vue.js (vuejs.org) TypeScript TypeScript: JavaScript With Syntax For Types. (typescriptlang.org) vite Vite | 下一代的前端工具链 (vitejs.dev) 下载好使用音频文件 音效网,保存本地。 将

    2024年02月01日
    浏览(42)
  • phpstorm添加vue 标签属性绑定提示和提示vue的方法提示

    把上面这些文字粘贴到点击右下角放大按钮 后的文本框里,然后保存即可实现标签属性提示 下面是提示js方法,把本地的vue.js 引入到编辑器即可

    2024年02月13日
    浏览(40)
  • 关于 vue3运行报错Internal server error: [@vue/compiler-sfc] <script setup> cannot contain ES 的处理方法

    大致的意思就是 script setup  不能使用ES模块导出 其实问题就出在,给官方给出的方法混用了 一种是: script  标签里面配置  setup 另一种是: export default  类里配置  setup()  方法 两者用一种就行了 第一种  第二种

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包