vue3基础知识(结合TypeScript)

一.使用vite创建项目

不选择vue-cli脚手架,换成使用vite,vite最大特点就是快,不需要进行打包,热加载快 是一个通用的脚手架工具

这里出了一个问题,就是vetur不支持vue3,所以HelloWorld组件就不能正常使用,需要把它卸载换成

二.ESlint初步使用

安装配置eslint:

添加rules之后:

eslint.config.js:(检测有没有分号)

js 复制代码
import globals from "globals";
import tseslint from "typescript-eslint";


/** @type {import('eslint').Linter.Config[]} */
export default [
  { files: ["**/*.{js,mjs,cjs,ts}"] },
  { languageOptions: { globals: globals.browser } },
  ...tseslint.configs.recommended,
  {
    rules: {
      semi: 2
    }
  },
];

代码中也会有相应的提示:

extends字段:添加规则组

后期和vite结合,添加vue和typeScript的规则组

三.响应式API:ref、reactive

ref:

js 复制代码
<script lang="ts">
import { defineComponent,ref } from 'vue';
export default defineComponent({
     name:'APP',
     setup()
     {
         const count=ref(0); //声明响应式对象
         const increase=()=>{
          count.value++; //这里要加上value
         }
         return {
          count,
          increase
         }
     }
})
</script>

<template>
  <div>
    <h1>{{ count }}</h1>
    <button type="button" v-on:click="increase">increase</button>
    
    <a href="https://vite.dev" target="_blank">
      <img src="/vite.svg" class="logo" alt="Vite logo" />
    </a>
    <a href="https://vuejs.org/" target="_blank">
      <img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
    </a>
  </div>
</template>

reactive:参数必须是一个对象

怎么把响应式对象和TS结合起来呢,使用泛型来定义ref的类型,value++之前进行判断

js 复制代码
<script lang="ts">
import { defineComponent,ref,reactive} from 'vue';
export default defineComponent({
     name:'APP',
     setup()
     {
         const count=ref<string | number>(0); //声明响应式对象
         const user=reactive({
             name:'viking',
             age:30,
         })
         const increase=()=>{
          if(typeof count.value==='number')
          count.value++; //这里要加上value
          user.age++; //不用加value进行访问
         }

         return {
          count,
          increase,
          user,
         }
     }
})
</script>

给reactive标记类型:

js 复制代码
<script lang="ts">
import { defineComponent,ref,reactive} from 'vue';
interface person {
  name:string,
  age:number
}
export default defineComponent({
     name:'APP',
     setup()
     {
         const count=ref<string | number>(0); //声明响应式对象
         const user:person = reactive({
             name:'viking',
             age:30,
         })
         const increase=()=>{
          if(typeof count.value==='number')
          count.value++; //这里要加上value
          user.age++; //不用加value进行访问
         }

         return {
          count,
          increase,
          user,
         }
     }
})
</script>

四.computed计算属性

js 复制代码
 <button type="button" :disabled="user.age<10">{{ user.age>=10 ?'可以参与':'不可以参与'}}</button>

如果要都写表达式的话,会使模板变得很复杂,所以就可以使用计算属性

js 复制代码
const buttonStatus=computed(()=>{
              return {
                text:user.age>=10?'可以参加':'不可以参加',
                disable:user.age<10
              }
         })
js 复制代码
<button type="button" :disabled="buttonStatus.disable">{{ buttonStatus.text }}</button>

计算属性在数据更新的时候才会重新计算

五.watch监听器

js 复制代码
watch(count,(newValue,oldValue)=>{
              console.log('old',oldValue);
              console.log('new',newValue);
              document.title=`目前点击的数是${newValue}`
         })

不能直接监听一个对象的属性,要添加在箭头函数返回值后面

js 复制代码
watch(()=>user.age,(newValue,oldValue)=>{
              console.log('old age',oldValue);
              console.log('new age',newValue);
              document.title=`目前点击的数是${newValue}`
         })

或者直接传入一个参数

js 复制代码
watch(user,(newValue,oldValue)=>{
              console.log('old age',oldValue);
              console.log('new age',newValue);
              document.title=`目前点击的数是${newValue}`
         })

立即监听执行器,加上 {immediate:true}

六.生命周期、模板引用

js 复制代码
onMounted(()=>{
            console.log('mounted');
          })
onUpdated(()=>{
console.log('updated');
})

onMounted用得是最多的,加载完毕的时候进行一些操作,比如发送异步请求

模板引用

js 复制代码
const headline=ref(null);
<h1 ref="headline">{{ count }}</h1>

//onmounted中:
onMounted(()=>{
            console.log('mounted',headline.value);
          })

可以访问到dom节点:

使用TS的联合类型定义:(组件未加载完毕的时候可能是null)

js 复制代码
const headline=ref<null|HTMLElement>(null);
js 复制代码
onMounted(()=>{
            if(headline.value)
            console.log('mounted',headline.value);
          })

七.组件基础-属性Props

MyFile组件:

js 复制代码
<template>
    <div class="profile-component"></div>
    <h1>name:{{ name }}</h1>
    <h1>age:{{ age }}</h1>
    <h1>doubleAge:{{ doubleAge }}</h1>
 </template>
 
 <script lang="ts">
 import { computed, defineComponent } from 'vue';
 export default defineComponent ({
     name:'MyFile',
     props:{
         name:{
             type:String,
             required:true
            
         },
         age:{
             type:Number,
             default:30
         }
     },
     setup(props) {
         const doubleAge=computed(()=>props.age*2)
         return{
             doubleAge
         }
     },
 })
 </script>
 
 <style scoped>
 
 </style>

在App.vue中给它传值:

js 复制代码
<MyFile name="lyt"/>

把属性修改成一个对象:使用TS来标注类型(PropType)

js 复制代码
<template>
    <div class="profile-component"></div>
    <h1>name:{{ user.name }}</h1>
    <h1>age:{{ user.age }}</h1>
    <h1>doubleAge:{{ doubleAge }}</h1>
 </template>
 
 <script lang="ts">
 import type { PropType } from 'vue';
 import { computed, defineComponent} from 'vue';
 interface Person{
    name:string,
    age:number
 }
 export default defineComponent ({
     name:'MyFile',
     props:{
         user:{
            type:Object as PropType<Person>,
            required:true
         }

     },
     setup(props) {
        const doubleAge=computed(()=>props.user.age*2)
        return {
            doubleAge
        }
     },
 })
 </script>
 
 <style scoped>
 
 </style>

在App.vue中使用要进行改变:

js 复制代码
<MyFile :user="user"/>

八.组件自定义事件

子组件显示和隐藏功能:emit中添加了change事件,把isHidden的value传给父组件

js 复制代码
<template>
    <div class="profile-component"></div>
    <h1>name:{{ user.name }}</h1>
    <h1 v-if="!isHidden">age:{{ user.age }}</h1>
    <h1 v-if="!isHidden">doubleAge:{{ doubleAge }}</h1>
    <button type="button" @click="toggleHide">{{ isHidden?'显示':'隐藏' }}</button>
 </template>
 
 <script lang="ts">
 import type { PropType } from 'vue';
 import { computed, defineComponent,ref} from 'vue';
 interface Person{
    name:string,
    age:number
 }
 export default defineComponent ({
     name:'MyFile',
     props:{
         user:{
            type:Object as PropType<Person>,
            required:true
         }
     },
     emits:['change'],
     setup(props,ctx) {
        const isHidden=ref(false);
        const doubleAge=computed(()=>props.user.age*2)
        const toggleHide=()=>{
            isHidden.value=!isHidden.value
            ctx.emit('change',isHidden.value)
        }
        return {
            doubleAge,
            isHidden,
            toggleHide
        }
     },
 })
 </script>
 
 <style scoped>
 
 </style>

App.vue中写相应的事件:获取到子组件的状态

js 复制代码
const onChange=(hidden:boolean)=>{
             document.title=hidden?'隐藏':'显示'
          }
          
          
 <MyFile :user="user" @change="onChange"/>   
          
相关推荐
mldong7 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排8 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60618 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角9 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!10 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰10 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi11 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen12 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马13 小时前
AI源码分析:拆解模型底层实现逻辑
前端
IT_陈寒13 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端