Vue基础集合

目录

  • Vue
      • 1、渐进式框架
      • 2、Vue API 风格
        • 选项式API
        • 组合式API
        • 选择哪一种书写?
          • 在生产项目中:
      • 3、Vue开发前的准备
          • 创建Vue项目
          • 问:创建Vue项目的命令是什么?
      • 4、模板语法
        • 文本插值
          • 使用JS表达式
        • 原始 HTML
      • 5、属性绑定
        • 简写
        • 动态绑定多个值
      • 6、条件渲染
          • `v-if`和`v-show`的区别
      • 7、列表渲染
          • 遍历对象的时候名称要不一样
        • 通过key管理状态
        • 数组变化侦测
          • 变更方法
          • 替换一个数组
      • 8、事件处理
        • 内联事件处理器
        • 方法事件处理器
        • 事件修饰符
          • 阻止默认事件
          • 阻止冒泡事件
      • 9、计算属性
      • 10、Class绑定
      • 11、Style绑定
          • 绑定对象
          • 绑定数组
      • 12、侦听器
      • 13、表单输入绑定
      • 14、获取DOM操作(模板引用)
      • 15、组件基础
          • 局部注册组件
          • 全局注册组件
        • 传递 props(父类传递数据给子类)
          • props效验
        • 组件事件(子类传递数据给父类)
      • 16、插槽Slot
        • 插槽内容与出口
        • Slot传递数据
          • 父类传递数据给``
          • ``传递数据给父类
      • 17、Attributes 继承
        • 对 `class` 和 `style` 的合并
      • 18、生命周期钩子
        • 注册周期钩子
        • 生命周期图示
      • 19、异步组件
      • 20、依赖注入
        • Prop 逐级透传问题
        • 生命周期图示
      • 19、异步组件
      • 20、依赖注入
        • Prop 逐级透传问题

Vue

1、渐进式框架

Vue是一个框架,也是一个生态。其功能覆盖了大部分前端开发需求

  • 无需构建步骤,渐进式增强静态的HTML
  • 在任何页面中作为Web Components嵌入
  • 单页应用(SPA)
  • 渲染
  • jamstack\静态站点生成(SSG)
  • 开发桌面端、移动端、webGL,甚至是命令行终端的页面

2、Vue API 风格

Vue的组件可以按照两种不同的风格书写:选项式API(Vue2写法)和组合式API(Vue3写法)

大部分的核心概念在这两种风格之间都是相通的。

选项式API

import { createApp } from 'vue'

createApp({
  data() {
    return {
      count: 0
    }
  }
}).mount('#app')

组合式API

import { createApp, ref } from 'vue'

createApp({
  setup() {
    return {
      count: ref(0)
    }
  }
}).mount('#app')

选择哪一种书写?

在生产项目中:
  • 当你不需要使用构建工具,或者打算主要在低复杂度的场景下使用Vue,采用选项式API
  • 当你打算用Vue构建完整的单页应用,推荐采用组合式API+单文件组件

3、Vue开发前的准备

构建工具让我们能使用Vue单文件组件(SFC)。Vue官方的构建流程是基于Vite的,一个现代轻量的构建工具

安装15.0或更高版本的Node.js

创建Vue项目
npm init vue@latest
# 在cmd下运行

这一指令会安装和执行create-vue,它是Vue官方的项目脚本架工具。你会开看到一些可选功能提示

Need to install the following packages:
  [email protected]
Ok to proceed? (y) y

Vue.js - The Progressive JavaScript Framework

√ Project name: ... vue-1  #项目名称不要大写
√ Add TypeScript? ... No / Yes
√ Add JSX Support? ... No / Yes
√ Add Vue Router for Single Page Application development? ... No / Yes
√ Add Pinia for state management? ... No / Yes
√ Add Vitest for Unit Testing? ... No / Yes
√ Add an End-to-End Testing Solution? » No
√ Add ESLint for code quality? ... No / Yes

创建后按照提示安装依赖并打开服务器

cd 
npm install
npm run dev
问:创建Vue项目的命令是什么?
  • npm create-vue project
  • npm create vue project
  • npm create-react project
  • npm init vue@latest

4、模板语法

Vue使用一种基于HTML的模板语法,使我们能够声明式的将其组件实例的数据绑定到出现的DOM上。所有的Vue模板都是语法层面合法的HTML,可以被符合规范的浏览器和HTML解析器解析。

文本插值

最基本的数据绑定形式使文本插值,它使用的是“Mustache”语法(双大括号)

<span>Message: {{ msg }}span>
使用JS表达式

每个绑定仅支持单一表达式,也是一段能被求值的JS代码。一个简单的判断方法是是否可以合法的写在return后面

{{ number + 1 }}

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

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

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

因此,下面的例子都是无效的:

<!-- 这是一个语句,而非表达式 -->
{{ var a = 1 }}

<!-- 条件控制也不支持,请使用三元表达式 -->
{{ if (ok) { return message } }}

原始 HTML

双大括号会将数据解释为纯文本,而不是 HTML。若想插入 HTML,你需要使用 v-html 指令:

<p>Using text interpolation: {{ rawHtml }}p>
<p>Using v-html directive: <span v-html="rawHtml">span>p>

5、属性绑定

双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用 v-bind 指令:

<div v-bind:id="dynamicId">div>

v-bind 指令指示 Vue 将元素的 id attribute 与组件的 dynamicId 属性保持一致。如果绑定的值是 null 或者 undefined,那么该 attribute 将会从渲染的元素上移除。

简写

因为 v-bind 非常常用,我们提供了特定的简写语法:

<div :id="dynamicId">div>

动态绑定多个值

<script>
export default{
  data(){
    return{
      msg:"active",
      style:"app"
    }
  }
}
</script>

<template>
  <div :class="msg" :id="style">测试</div>
</template>
<style>
  #app{
    color: red;
  }
</style>

6、条件渲染

指令是带有 v- 前缀的特殊 attribute。Vue 提供了许多内置指令,包括上面我们所介绍的 v-bindv-html

指令 attribute 的期望值为一个 JavaScript 表达式 (除了少数几个例外,即之后要讨论到的 v-forv-onv-slot)。一个指令的任务是在其表达式的值变化时响应式地更新 DOM。以 v-if 为例:

<script>
export default{
    data(){
        return{
            msg:false
        }
    }
}
</script>
<template>
    <div v-if="msg">你能看见我吗</div>
    <div v-else>那你看看我</div>
</template>
v-ifv-show的区别

v-if也是惰性的:如果在初次渲染条件值为false,则不会做任何事。条件区只有当条件首次变为true时才被渲染。

相比之下,v-show简单许多,元素无论初始条件如何,始终会被渲染,只有CSSdisplay属性会被切换。

总的来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要频繁切换,则使用v-show较好;如果在运行时绑定条件很少改变,则v-if会更合适

7、列表渲染

我们可以使用v-for指令基于一个数组来渲染一个列表。v-for指令的值需要使用item in items形式来遍历。

<script>
export default{
    data(){
        return{
            names:["小丁","小海","小段"]
        }
    }
}
</script>
<template>
<p v-for="i in names">{{ i }}</p>
</template>

v-for支持使用可选的第二个参数标识当前项的位置索引

<p v-for="(i,index) in names">{{ i }}-{{ index }} p>

可以使用of作为分隔符来代替in,这样更接近JS的迭代器语法

<p v-for="(i,index) of names">{{ i }}-{{ index }} p>

v-for支持使用可选的第二个参数标识当前项的名称

<p v-for="(i,key,index) in names">{{ i }}-{{ key }}-{{ index }} p>
遍历对象的时候名称要不一样

遍历对象的时候名称要不一样,如果names:{name:"小丁",name:"小海",name:"小段"}只会输出一个小段

export default{
    data(){
        return{
            names:{name:"小丁",age:"小海",id:"小段"}
        }
    }
}

通过key管理状态

Vue默认按照“就地更新”的策略来更新通过v-for渲染的元素列表。当数据项的顺序改变时,Vue不会随之移动DOM元素的顺序,而是就地更新每一个元素,确保它们在原本指定的索引位置上渲染。

为了给Vue一个提示,以便他可以跟踪每一个节点的标识,从而重用和重新排序现有的元素,你需要为每一个元素对应的块提供一个唯一的key

<p v-for="(i,index) of names" :key="index">{{ i }}p>

key在这里是一个提供v-bind绑定的特殊attribute

推荐在任何可行的时候为v-for提供一个keyattribute

key绑定的值期望是一个基础类型的值,例如字符串或number类型

数组变化侦测

变更方法

Vue能够侦测响应式数组的变更方法,并在它们被调用时触发相关的更新。这些变更方法包括:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
替换一个数组

变更方法,就是会对调用它们的原数组进行变更。相对的,也有一些不可变方法,如filter()concat()slice(),这些都不会更改原数组,而总是返回一个新数组。



8、事件处理

我们可以使用v-on指令(简写为@)来监听DOM事件,并在事件触发时执行对应的JS。用法:v-on:click="methodName"@click="handler"

事件处理器的值可以是

  • 内联事件处理器:事件被触发时执行的内联JS语句(与onclick类似)
  • 方法事件处理器:一个指向组件上定义的方法的属性名或者路径

内联事件处理器

<template>
    <button v-on:click="count++">add</button>
    <p>{{ count }}</p>
</template>
<script>
export default{
    data(){
        return{
            count:0
        }
    }
}
</script>

方法事件处理器

<template>
    <button @click="add">add</button>
    <p>{{ count }}</p>
</template>
<script>
export default{
    data(){
        return{
            count:0
        }
    },
    methods:{
        add(){
            this.count+=1
        }
    }
}
</script>

事件修饰符

在处理事件时调用event.preventDefault()event.stopPropagation()是很常见的。尽管我们可以直接在方法内调用,但如果方法能更专注与数据逻辑而不用处理DOM事件的细节会更好

为解决这一问题,Vue为v-on提供了事件修饰符,常用有以下几个:

  • .stop
  • .prevent
  • .once
  • .enter
阻止默认事件
<template>
<a href="" @click="one">阻止默认事件</a>
</template>
<script>
export default{
    data(){
        return{
            
        } 
    },
    methods:{
        one(e){
            e.preventDefault();
            console.log("1");
        }
    }
   
}
<a href="" @click.prevent="one">阻止默认事件a>
阻止冒泡事件
<template>
<div @click="one">
    <p @click="two">阻止冒泡事件</p>
</div>
</template>
<script>
export default{
    data(){
        return{
            
        } 
    },
    methods:{
        one(e){
            console.log("1");
        },
        two(e){
            e.stopPropagation();
            console.log("2");
        }
    }
   
}
</script>
<div @click="one">
    <p @click.stop="two">阻止冒泡事件p>
div>

9、计算属性

<template>
<p>{{ person.content.length > 0 ? "yes" : "no"}}</p>
</template>
<script>
export default{
    data(){
        return{
            person:{
                name:"小丁",
                content:["1","2","3"]
            }
        }
    }
}
</script>

模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。因此我们推荐使用计算属性来描述响应式状态的复杂逻辑

<template>
<p>{{ getcontent }}</p>
</template>
<script>
export default{
    data(){
        return{
            person:{
                name:"小丁",
                content:["1","2","3"]
            }
        }
    },
    computed:{
        getcontent() {
            return this.person.content.length > 0 ? "yes" : "no"
        }
    },
    methods:{
        getcontent2() {
            return this.person.content.length > 0 ? "yes" : "no"
        }
    }
}
</script>

重点区别:

计算属性:计算属性值会基于其相应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算

方法:方法调用总是会在重渲染发生时再次执行函数

10、Class绑定

数据绑定的一个常见需求场景是操作的CSS class 列表,因为class是attribute,我们可以和其它attribute一样使用v-bind将它们和动态的字符串绑定。但是,在处理比较复杂的绑定时,通过拼接生成字符串是麻烦且易出错的。因此,Vue专门为classv-bind用法提供了特殊的功能增强。除了字符串外,表达式的值也可以是对象或数组。

<div :class="{ active: isActive }">div>

上面的语法表示 active 是否存在取决于数据属性 isActive 的真假值。

你可以在对象中写多个字段来操作多个 class。此外,:class 指令也可以和一般的 class attribute 共存。举例来说,下面这样的状态:

const isActive = ref(true)
const hasError = ref(false)

class会绑定对象、数组

11、Style绑定

绑定对象

:style 支持绑定 JavaScript 对象值,对应的是 HTML 元素的 style 属性:

const activeColor = ref('red')
const fontSize = ref(30)
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }">div>

尽管推荐使用 camelCase,但 :style 也支持 kebab-cased 形式的 CSS 属性 key (对应其 CSS 中的实际名称),例如:

<div :style="{ 'font-size': fontSize + 'px' }">div>

直接绑定一个样式对象通常是一个好主意,这样可以使模板更加简洁:

const styleObject = reactive({
  color: 'red',
  fontSize: '13px'
})
<div :style="styleObject">div>

同样的,如果样式对象需要更复杂的逻辑,也可以使用返回样式对象的计算属性。

绑定数组

我们还可以给 :style 绑定一个包含多个样式对象的数组。这些对象会被合并后渲染到同一元素上:

<div :style="[baseStyles, overridingStyles]">div>

12、侦听器

计算属性允许我们声明性地计算衍生值。然而在有些情况下,我们需要在状态变化时执行一些“副作用”:例如更改 DOM,或是根据异步操作的结果去修改另一处的状态。

在组合式 API 中,我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数:

<template>
<p>{{ msg }}</p>
<button @click="change"></button>
</template>
<script>
export default{
    data(){
        return{
            msg:"hello"
        }
    },
    methods:{
        change(){
            this.msg="world"
        }
    },
    watch:{
        msg(newValue,oldValue){
            //数据发生变化,自动执行的函数
            console.log(newValue,oldValue);
        }
    }
}
</script>

13、表单输入绑定

在前端处理表单时,我们常常需要将表单输入框的内容同步给 JavaScript 中相应的变量。手动连接值绑定和更改事件监听器可能会很麻烦:

<input
  :value="text"
  @input="event => text = event.target.value">

v-model 指令帮我们简化了这一步骤:

<input v-model="text">

另外,v-model 还可以用于各种不同类型的输入,