Vue3学习笔记

一、开篇明义:

vue.js是一套构建用户界面渐进式框架(允许开发者根据项目需求逐步引入和使用其功能的框架

vue.js的优势:

  • 组件化:可复用的组件,减少代码量和维护量
  • 语法简洁
  • 虚拟DOM:使用虚拟 DOM 提高性能,通过对比新旧虚拟 DOM 来减少实际 DOM 操作,从而提高渲染效率
  • 双向数据绑定:提供双向数据绑定(v-model),使表单输入与数据模型同步,简化了数据流的管理
  • 轻量高效:Vue.js 相比其他框架(如 Angular 或 React)更轻量
  • 易集成
  • 生态丰富

学习基础:

  • HTML
  • CSS
  • JavaScript

安装:

把B站的安装视频找到

编译器:

使用VS Code 

使用Fitten code代码AI助手

创建一个vue3项目:

  1. 打开终端或命令提示符
  2. 创建项目
npm create vite@latest

工程目录:

my-vue-project/  # Vue 项目的根目录

├── public/      # 静态资源文件夹

│   └── index.html  # 项目的 HTML 模板文件

├── src/         # 源代码文件夹

│   ├── assets/  # 存放静态资源(如图片、字体等)

│   ├── components/  # Vue 组件

│   │   ├── Header.vue  # 页面头部组件

│   │   ├── Footer.vue  # 页面底部组件

│   │   ├── Welcome.vue  # 欢迎页面组件

│   │   └── FeatureCard.vue  # 功能卡片组件

│   ├── views/   # 页面组件

│   │   ├── Home.vue  # 首页

│   │   ├── FeaturePage1.vue  # 功能页面1

│   │   ├── FeaturePage2.vue  # 功能页面2

│   │   └── FeaturePage3.vue  # 功能页面3

│   ├── router/  # 路由配置

│   │   └── index.js  # 路由配置文件

│   ├── App.vue  # 根组件

│   ├── main.js  # 入口文件

│   ├── vue.config.js  # Vue CLI 的配置文件,用于修改默认配置

│   ├── package-lock.json  # 锁定安装的依赖版本,确保项目依赖的一致性

└── package.json  # 项目配置文件

详细说明:

  1. public/
    • index.html: 这是项目的 HTML 模板文件,Vue 会在这个模板中渲染应用。
  2. src/
    • assets/: 用来存放静态资源,比如图片、字体、样式等文件。
    • components/: 存放所有可复用的 Vue 组件,比如:
      • Header.vue: 页头部分。
      • Footer.vue: 页脚部分。
      • Welcome.vue: 欢迎页面组件。
      • FeatureCard.vue: 功能卡片组件。
    • views/: 存放不同页面的 Vue 组件,通常对应路由路径:
      • Home.vue: 首页,展示欢迎页面。
      • FeaturePage1.vue, FeaturePage2.vue, FeaturePage3.vue: 对应不同的功能页面。
    • router/: 存放路由配置文件:
      • index.js: Vue Router 配置文件,管理各页面组件和路由路径。
    • App.vue: 根组件,用于组织全局布局,包含头部、底部以及 <router-view /> 渲染页面内容。
    • main.js: 入口文件,初始化 Vue 实例并挂载应用。
  3. package.json
    • 项目的配置文件,包含依赖、脚本等配置信息。

如何理解这个结构:

  • components/ 和 views/ 的区别
    • components/ 存放的是可复用的组件(如 Header.vue, FeatureCard.vue),这些组件通常是某些页面的构建模块。
    • views/ 存放的是页面组件(如 Home.vue, FeaturePage1.vue),这些组件与路由路径对应,通常是应用的具体页面。
  • App.vue 作为根组件,组织了页面的全局布局,包含头部、底部等通用组件。而具体的页面内容(如 Welcome.vue、FeaturePage1.vue 等)会通过 Vue Router 动态加载。
  • router/index.js 配置了 Vue Router 路由,决定了不同路径展示哪些页面组件。

如何处理路由和页面展示

假设你访问 / 路径时展示 Home.vue,访问 /feature1 时展示 FeaturePage1.vue,路由配置大致如下:

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import FeaturePage1 from '../views/FeaturePage1.vue'
import FeaturePage2 from '../views/FeaturePage2.vue'
import FeaturePage3 from '../views/FeaturePage3.vue'
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home  // 首页,显示 Welcome 组件
  },
  {
    path: '/feature1',
    name: 'Feature1',
    component: FeaturePage1  // 功能页面1
  },
  {
    path: '/feature2',
    name: 'Feature2',
    component: FeaturePage2  // 功能页面2
  },
  {
    path: '/feature3',
    name: 'Feature3',
    component: FeaturePage3  // 功能页面3
  }
]
const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})
export default router

总结:

  • 目录结构将你的组件和页面组织清晰,components/ 存放可复用的组件,views/ 存放各个页面组件。
  • 路由配置和页面组件的关系通过 router/index.js 来管理。
  • 通过 App.vue 的全局布局和 Vue Router 进行路由切换,你可以轻松管理不同页面的显示和布局。

vue3项目启动和打包部署

启动开发服务器,打开浏览器访问 http://localhost:8080,查看应用

npm run serve

使用打包命令

npm run build

执行完成后,会在 Vue 项目下会生成一个 dist 目录,该目录一般包含 index.html 文件及 static 目录,static 目录包含了静态文件 js、css 以及图片目录 images(如果有图片的话)。

二、HTML基础

三、CSS基础

四、JavaScript

五、vue3

1.vue组件的基本结构

一个 .vue 文件包含三个部分:<template><script> 和 <style>

模板(<template>

  • 使用 HTML 和 Vue 模板语法定义组件的 UI。

  • 支持插值({{ }})、指令(如 v-ifv-for)和事件绑定(如 @click)。

脚本(<script>

  • 定义组件的逻辑,包括数据、方法、生命周期钩子等。

  • 使用 export default 导出组件选项。

样式(<style>

  • 定义组件的样式。

  • 使用 scoped 属性可以将样式限制在当前组件内。

2.起点

createApp 的参数是根组件(HelloVueApp),在挂载应用时,该组件是渲染的起点。一个应用需要被挂载到一个 DOM 元素中,以上代码使用 mount('#hello-vue') 将 Vue 应用 HelloVueApp 挂载到 <div id="hello-vue"></div> 中。

Vue.createApp(HelloVueApp).mount('#hello-vue')

3.基础语法

创建vue实例:在html文件创建vue实例并将其挂在到一个DOM元素

<div id="hello-vue" class="demo">
    {{message}}   //Vue.js的模板语法,将Vue实例中的message数据绑定到页面上,随之更新
</div>

<script>
const HelloVueApp={ //一个普通的 JavaScript 对象
    data(){ //返回一个包含 message 属性的对象,这个属性的初始值是 'Hello Vue!!'
        return{
            message: 'Hello,vue!'
        }
    }
}
Vue.createApp(HelloVueApp).mount('#hello-vue')//Vue.createApp() 方法用于创建一个 Vue 应用实例
//.mount('#hello-vue') 方法将 Vue 应用实例挂载到页面中具有 id="hello-vue" 的 DOM 元素上
</script>

4.模板语法

1)插值

<div>{{ message }}</div>

2)指令

指令是带有前缀 v- 的特殊属性,用于在模板中表达逻辑

//动态绑定一个或多个特性,或一个组件 prop
//HTML属性中的值使用v-bind
<a v-bind:href="url">Link</a>

//条件渲染v-if v-else-if v-else v-show
<p v-if="visible">内容可见</p>
<p v-else>内容不可见</p>

//列表渲染v-for
<ul>
    <li v-for="item in items" :key="item.id">{{item.next}}</li>
</ul>

//双向数据绑定v-model
<input v-model="message" placeholder="edit me">
<p>Message is: {{message}}</p>

//事件监听器v-on
<button v-on:click="doSomething">Click me</button>
或者
<button @click="doSomething">Click me</button>
i)条件语句

主要的条件语句有 v-ifv-else-ifv-else 和 v-show,以下是它们的用法及区别:

  • v-if:元素在条件为 false 时不会被渲染到 DOM 中,适用于条件变化不频繁的情况。
  • v-show:元素总是渲染到 DOM 中,适用于条件变化频繁的情况,切换显示隐藏性能更好。
  • v-else-if 和 v-else:用于处理多个条件分支,配合 v-if 使用
ii)循环语句

 使用 v-for 渲染列表时,必须为每个项提供一个唯一的 key 属性,以便 Vue 能够识别每个项的唯一性,从而进行高效的 DOM 更新

可以嵌套使用多个 v-for 来渲染多维数组或对象结构

任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要使用 props

  • 遍历数组:v-for="(item, index) in items"
  • 遍历对象:v-for="(value, key, index) in object"

3)事件处理

使用 v-on 指令来监听 DOM 事件,并在触发时执行一些 JavaScript 代码

4)计算属性

计算属性是基于其依赖进行缓存的属性。计算属性只有在其相关依赖发生变化时才会重新计算。

<template>
  <div>
    <p>商品名称:{{ productName }}</p>
    <p>商品价格:{{ formattedPrice }}</p>
    <button @click="increasePrice">增加价格</button>
  </div>
</template>

<script>
import { reactive, computed } from 'vue';

export default {
  setup() {
    // 响应式数据
    const state = reactive({
      name: '手机',
      price: 2000
    });

    // 计算属性
    const productName = computed(() => {
      return `优惠 ${state.name}`;
    });

    const formattedPrice = computed(() => {
      return `¥${state.price.toFixed(2)}`;
    });

    // 方法
    const increasePrice = () => {
      state.price += 100;
    };

    return {
      productName,
      formattedPrice,
      increasePrice
    };
  }
};
</script>

computed 函数:

  • 在 setup 函数中使用 computed 函数来定义计算属性。
  • 通过箭头函数返回计算的值,该函数会自动跟踪其依赖的响应式数据(state 对象中的 name 和 price)。
  • computed 属性默认只有 getter,不过在需要时你也可以提供一个 setter 

使用计算属性:

  • productName 计算属性衍生自 state.name,每当 state.name 发生变化时,productName 会自动更新。
  • formattedPrice 计算属性衍生自 state.price,每当 state.price 发生变化时,formattedPrice 会自动更新。

响应式数据:

  • 使用 reactive 函数创建 state 对象,使其成为响应式数据,可以监听其属性的变化。

方法:

  • increasePrice 方法用于增加 state.price 的值,每点击一次按钮,state.price 值增加 100,并且 formattedPrice 计算属性会相应更新。
computed vs methods

我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性

5)组件

<div id="app">
  <my-component></my-component>
</div>

<script>
  const app = createApp({});

  app.component('my-component', {
    template: '<div>A custom component!</div>'
  });

  app.mount('#app');
</script>

6) Props

prop 是子组件用来接受父组件传递过来的数据的一个自定义属性。

父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 "prop";

用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件

<div id="app">
  <site-name title="Google"></site-name>
  <site-name title="Runoob"></site-name>
  <site-name title="Taobao"></site-name>
</div>
 
<script>
const app = Vue.createApp({})
 
app.component('site-name', {
  props: ['title'],
  template: `<h4>{{ title }}</h4>`
})
 
app.mount('#app')
</script>

7)事件

子组件通过 $emit 触发事件,父组件可以监听这些事件。

一个关于v-for v-bind props和emit的例子

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 关注v-for props和emit</title>
<script src="https://cdn.staticfile.net/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="todo-list-example">
  <form v-on:submit.prevent="addNewTodo">
    <label for="new-todo">添加 todo</label>
    <input
      v-model="newTodoText"
      id="new-todo"
      placeholder="例如:明天早上跑步"
    />
    <button>添加</button>
  </form>
  <ul>
    <todo-item
      v-for="(todo, index) in todos"
      :key="todo.id"
      :title="todo.title"
      @remove="todos.splice(index, 1)"
    ></todo-item>
  </ul>
</div>
 
<script>
const app = Vue.createApp({
  data() {
    return {
      newTodoText: '',
      todos: [
        {
          id: 1,
          title: '看电影'
        },
        {
          id: 2,
          title: '吃饭'
        },
        {
          id: 3,
          title: '上 RUNOOB 学习'
        }
      ],
      nextTodoId: 4
    }
  },
  methods: {
    addNewTodo() {
      this.todos.push({
        id: this.nextTodoId++,
        title: this.newTodoText
      })
      this.newTodoText = ''
    }
  }
})

app.component('todo-item', {
  template: `
    <li>
      {{ title }}
      <button @click="$emit('remove')">删除</button>
    </li>
  `,
  props: ['title'],
  emits: ['remove']
})

app.mount('#todo-list-example')
</script>
</body>
</html>

5声明式渲染

声明式渲染(Declarative Rendering)是指通过数据驱动视图的更新,而不是直接操作 DOM

数据绑定:通过绑定数据,Vue 可以自动更新 DOM 元素的内容,避免了传统的手动 DOM 操作

---------插值---------
<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, Vue 3!'
    };
  }
};
</script>



--------属性绑定---------
<div id="app">
  <label for="r1">修改颜色</label><input type="checkbox" v-model="use" id="r1">
  <br><br>
  <div v-bind:class="{'class1': use}">
    v-bind:class 指令
  </div>
</div>
    
<script>
const app = {
  data() {
    return {
      use: false
    }
  }
}
 
Vue.createApp(app).mount('#app')
</script>


---------条件渲染------------------
<template>
  <div>
    <p v-if="isVisible">这段文本是可见的</p>
    <button @click="toggleVisibility">切换可见性</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isVisible: true
    };
  },
  methods: {
    toggleVisibility() {
      this.isVisible = !this.isVisible;
    }
  }
};
</script>




---------列表渲染---------
<template>
  <div>
    <ul>
      <li v-for="item in items" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, name: 'Vue 3' },
        { id: 2, name: 'JavaScript' },
        { id: 3, name: 'HTML' }
      ]
    };
  }
};
</script>


--------双向数据绑定--------
---双向:表单元素(如 <input>)和组件数据---
在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定
<template>
  <div>
    <input v-model="message" placeholder="输入一些文本" />
    <p>你输入了:{{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    };
  }
};
</script>


-----------事件处理------------
<template>
  <div>
    <button v-on:click="increment">点击我</button>
    <p>点击次数:{{ count }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count += 1;
    }
  }
};
</script>


---------计算属性----------
<template>
  <div>
    <p>原始金额:{{ amount }}</p>
    <p>税后金额:{{ computedAmount }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      amount: 100
    };
  },
  computed: {
    computedAmount() {
      return this.amount * 1.1; // 假设税率为10%
    }
  }
};
</script>

6 监听属性

watch 的作用是用于监测响应式属性的变化,并在属性发生改变时执行特定的操作,它是 Vue 中的一种响应式机制,允许你在数据发生变化时做出相应的响应,执行自定义的逻辑

监听多个响应式属性

import { reactive, watch } from 'vue';

export default {
  setup() {
    const state = reactive({
      count: 0,
      name: 'Vue3'
    });

    watch(
      [() => state.count, () => state.name], // 监听多个属性
      ([newCount, newName], [oldCount, oldName]) => {
        console.log(`count changed from ${oldCount} to ${newCount}`);
        console.log(`name changed from ${oldName} to ${newName}`);
      }
    );

    return {
      state
    };
  }
};

深度监听

监听的是一个对象或数组,并希望对其内部的嵌套属性进行监听

import { reactive, watch } from 'vue';

export default {
  setup() {
    const state = reactive({
      user: {
        name: 'Alice',
        age: 25
      }
    });

    watch(
      () => state.user, // 监听整个对象
      (newVal, oldVal) => {
        console.log('User object changed:', newVal, oldVal);
      },
      { deep: true } // 启用深度监听
    );

    return {
      state
    };
  }
};

watchEffect API,它比 watch 更加简洁,可以自动地跟踪响应式数据的变化,而不需要指定具体的数据源。

默认情况下,watch 回调会在 DOM 更新后执行。如果你需要在更新之前执行回调,可以使用 flush: 'pre'

7样式绑定

要结合HTML看

8.事件处理

使用 v-on 指令来监听 DOM 事件,从而执行 JavaScript 代码。

事件修饰符

Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节。Vue.js 通过由点 . 表示的指令后缀来调用修饰符。

  • .stop - 阻止冒泡
  • .prevent - 阻止默认事件
  • .capture - 阻止捕获
  • .self - 只监听触发该元素的事件
  • .once - 只触发一次
  • .left - 左键事件
  • .right - 右键事件
  • .middle - 中间滚轮事件
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联  -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>

<!-- click 事件只能点击一次,2.1.4版本新增 -->
<a v-on:click.once="doThis"></a>

按键修饰符

监听键盘事件时添加按键修饰符

全部的按键别名:

  • .enter
  • .tab
  • .delete (捕获 "删除" 和 "退格" 键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

系统修饰键:

  • .ctrl
  • .alt
  • .shift
  • .meta
  • exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。

9.表单

用 v-model 指令在表单 <input><textarea> 及 <select> 等元素上创建双向数据绑定

v-model 会根据控件类型自动选取正确的方法来更新元素

v-model 会忽略所有表单元素的 value、checked、selected 属性的初始值,使用的是 data 选项中声明初始值。

v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:

  • text 和 textarea 元素使用 value 属性和 input 事件;
  • checkbox 和 radio 使用 checked 属性和 change 事件;
  • select 字段将 value 作为属性并将 change 作为事件。

修饰符

  • .lazy:默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步
  • .number:自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值)
  • .trim:自动过滤用户输入的首尾空格
<input v-model.lazy="msg">
<input v-model.number="age" type="number">
<input v-model.trim="msg">

10.自定义指令

允许自定义指令

钩子

指令定义函数提供了几个钩子函数(可选):

  • created : 在绑定元素的属性或事件监听器被应用之前调用。

  • beforeMount : 指令第一次绑定到元素并且在挂载父组件之前调用。。

  • mounted : 在绑定元素的父组件被挂载后调用。。

  • beforeUpdate: 在更新包含组件的 VNode 之前调用。。

  • updated: 在包含组件的 VNode 及其子组件的 VNode 更新后调用。

  • beforeUnmount: 当指令与在绑定元素父组件卸载之前时,只调用一次。

  • unmounted: 当指令与元素解除绑定且父组件已卸载时,只调用一次。

import { createApp } from 'vue'
const app = createApp({})
 
// 注册
app.directive('my-directive', {
  // 指令是具有一组生命周期的钩子:
  // 在绑定元素的 attribute 或事件监听器被应用之前调用
  created() {},
  // 在绑定元素的父组件挂载之前调用
  beforeMount() {},
  // 绑定元素的父组件被挂载时调用
  mounted() {},
  // 在包含组件的 VNode 更新之前调用
  beforeUpdate() {},
  // 在包含组件的 VNode 及其子组件的 VNode 更新之后调用
  updated() {},
  // 在绑定元素的父组件卸载之前调用
  beforeUnmount() {},
  // 卸载绑定元素的父组件时调用
  unmounted() {}
})
 
// 注册 (功能指令)
app.directive('my-directive', () => {
  // 这将被作为 `mounted` 和 `updated` 调用
})
 
// getter, 如果已注册,则返回指令定义
const myDirective = app.directive('my-directive')

实例生命周期:

钩子函数的参数有:

el:el 指令绑定到的元素。这可用于直接操作 DOM。

binding:binding 是一个对象,包含以下属性:

  • instance:使用指令的组件实例。
  • value:传递给指令的值。例如,在 v-my-directive="1 + 1" 中,该值为 2
  • oldValue:先前的值,仅在 beforeUpdate 和 updated 中可用。值是否已更改都可用。
  • arg:参数传递给指令 (如果有)。例如在 v-my-directive:foo 中,arg 为 "foo"
  • modifiers:包含修饰符 (如果有) 的对象。例如在 v-my-directive.foo.bar 中,修饰符对象为 {foo: true,bar: true}
  • dir:一个对象,在注册指令时作为参数传递。

vnode:作为 el 参数收到的真实 DOM 元素的蓝图。

prevNode:上一个虚拟节点,仅在 beforeUpdate 和 updated 钩子中可用。

11.路由

Vue 路由允许我们通过不同的 URL 访问不同的内容;通过 Vue 可以实现多视图的单页 Web 应用

Vue.js 路由需要载入 vue-router 库

推荐NPM安装

npm install -g cnpm --registry=https://registry.npmmirror.com
cnpm install vue-router@4

Vue.js + vue-router 可以很简单的实现单页应用。

<router-link> 是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容。 to 属性为目标地址, 即要显示的内容。没有使用常规的 a 标签。在不重新加载页面的情况下更改 URL,处理 URL 的生成以及编码。

<script src="https://unpkg.com/vue@3"></script>
<script src="https://unpkg.com/vue-router@4"></script>
 
<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!--使用 router-link 组件进行导航 -->
    <!--通过传递 `to` 来指定链接 -->
    <!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
    <router-link to="/">Go to Home</router-link>
    <router-link to="/about">Go to About</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>

<router-view>将显示与 url 对应的组件。你可以把它放在任何地方,以适应你的布局

 <router-link> 的属性:

  • to:表示目标路由的链接。 当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。

  • replace:设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),导航后不会留下 history 记录。

  • append:设置 append 属性后,则在当前 (相对) 路径前添加其路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b

  • tag:有时候想要 <router-link> 渲染成某种标签,例如 <li>。 于是我们使用 tag prop 类指定何种标签,同样它还是会监听点击,触发导航。

  • active-class:设置 链接激活时使用的 CSS 类名

  • exact-active-class:配置当链接被精确匹配的时候应该激活的 class

  • event:声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组。

12.混入

混入 (mixins)定义了一部分可复用的方法或者计算属性。混入对象可以包含任意组件选项。

当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合。

13.Vue3 Ajax(axios)

推荐使用 axios 来完成 ajax 请求。

NPM安装

$ npm install axios

使用方法

//GET 通过 params 设置参数:
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

//POST
axios.post('/user', {
    firstName: 'Fred',        // 参数 firstName
    lastName: 'Flintstone'    // 参数 lastName
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

请求方法的别名

为方便使用,官方为所有支持的请求方法提供了别名,可以直接使用别名来发起请求:

axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

并发

处理并发请求的助手函数:

axios.all(iterable)
axios.spread(callback)

自定义请求配置

{
  // `url` 是用于请求的服务器 URL
  url: "/user",

  // `method` 是创建请求时使用的方法
  method: "get", // 默认是 get

  // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  baseURL: "https://some-domain.com/api/",

  // `transformRequest` 允许在向服务器发送前,修改请求数据
  // 只能用在 "PUT", "POST" 和 "PATCH" 这几个请求方法
  // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
  transformRequest: [function (data) {
    // 对 data 进行任意转换处理

    return data;
  }],

  // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
  transformResponse: [function (data) {
    // 对 data 进行任意转换处理

    return data;
  }],

  // `headers` 是即将被发送的自定义请求头
  headers: {"X-Requested-With": "XMLHttpRequest"},

  // `params` 是即将与请求一起发送的 URL 参数
  // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
  params: {
    ID: 12345
  },

  // `paramsSerializer` 是一个负责 `params` 序列化的函数
  // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
  paramsSerializer: function(params) {
    return Qs.stringify(params, {arrayFormat: "brackets"})
  },

  // `data` 是作为请求主体被发送的数据
  // 只适用于这些请求方法 "PUT", "POST", 和 "PATCH"
  // 在没有设置 `transformRequest` 时,必须是以下类型之一:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 浏览器专属:FormData, File, Blob
  // - Node 专属: Stream
  data: {
    firstName: "Fred"
  },

  // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
  // 如果请求花费了超过 `timeout` 的时间,请求将被中断
  timeout: 1000,

  // `withCredentials` 表示跨域请求时是否需要使用凭证
  withCredentials: false, // 默认的

  // `adapter` 允许自定义处理请求,以使测试更轻松
  // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
  adapter: function (config) {
    /* ... */
  },

  // `auth` 表示应该使用 HTTP 基础验证,并提供凭据
  // 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头
  auth: {
    username: "janedoe",
    password: "s00pers3cret"
  },

  // `responseType` 表示服务器响应的数据类型,可以是 "arraybuffer", "blob", "document", "json", "text", "stream"
  responseType: "json", // 默认的

  // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
  xsrfCookieName: "XSRF-TOKEN", // default

  // `xsrfHeaderName` 是承载 xsrf token 的值的 HTTP 头的名称
  xsrfHeaderName: "X-XSRF-TOKEN", // 默认的

  // `onUploadProgress` 允许为上传处理进度事件
  onUploadProgress: function (progressEvent) {
    // 对原生进度事件的处理
  },

  // `onDownloadProgress` 允许为下载处理进度事件
  onDownloadProgress: function (progressEvent) {
    // 对原生进度事件的处理
  },

  // `maxContentLength` 定义允许的响应内容的最大尺寸
  maxContentLength: 2000,

  // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject  promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
  validateStatus: function (status) {
    return status &gt;= 200 &amp;&amp; status &lt; 300; // 默认的
  },

  // `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
  // 如果设置为0,将不会 follow 任何重定向
  maxRedirects: 5, // 默认的

  // `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
  // `keepAlive` 默认没有启用
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // "proxy" 定义代理服务器的主机名称和端口
  // `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据
  // 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。
  proxy: {
    host: "127.0.0.1",
    port: 9000,
    auth: : {
      username: "mikeymike",
      password: "rapunz3l"
    }
  },

  // `cancelToken` 指定用于取消请求的 cancel token
  // (查看后面的 Cancellation 这节了解更多)
  cancelToken: new CancelToken(function (cancel) {
  })
}

响应结构

{
  // `data` 由服务器提供的响应
  data: {},

  // `status`  HTTP 状态码
  status: 200,

  // `statusText` 来自服务器响应的 HTTP 状态信息
  statusText: "OK",

  // `headers` 服务器响应的头
  headers: {},

  // `config` 是为请求提供的配置信息
  config: {}
}

使用 then 时,会接收下面这样的响应:

axios.get("/user/12345")
  .then(function(response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
  });

配置的优先顺序

这个顺序是:在 lib/defaults.js 找到的库的默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后者将优先于前者。

// 使用由库提供的配置的默认值来创建实例
// 此时超时配置的默认值是 `0`
var instance = axios.create();

// 覆写库的超时默认值
// 现在,在超时前,所有请求都会等待 2.5 秒
instance.defaults.timeout = 2500;

// 为已知需要花费很长时间的请求覆写超时设置
instance.get('/longRequest', {
  timeout: 5000
});

拦截器

在请求或响应被 then 或 catch 处理前拦截它们。

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

//移除拦截器
var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

setup 组件

setup() 函数在组件创建 created() 之前执行。

setup() 函数接收两个参数 props 和 context。

第一个参数 props,它是响应式的,当传入新的 prop 时,它将被更新。

第二个参数 context 是一个普通的 JavaScript 对象,它是一个上下文对象,暴露了其它可能在 setup 中有用的值。

六、API 手册

序号API 和 描述实例
1setup()
组件的组合式 API 中的入口函数,组件实例化时调用,用于定义响应式数据和方法。
export default { setup() { const count = ref(0); return { count }; } }
2ref()
创建一个响应式引用,用于包装基本类型或对象。
const count = ref(0)
3computed()
创建一个基于其他响应式数据计算出的值。
const doubledCount = computed(() => count.value * 2)
4reactive()
创建一个响应式对象,适用于对象或数组。
const state = reactive({ count: 0 })
5readonly()
创建只读的响应式数据,禁止修改。
const state = readonly({ count: 0 })
6watchEffect()
创建响应式副作用,自动追踪与其相关的响应式依赖。
watchEffect(() => { console.log(count.value) })
7watchPostEffect()
在 DOM 更新后触发的副作用。
watchPostEffect(() => { console.log('Post effect') })
8watchSyncEffect()
在响应式依赖变化时同步执行副作用。
watchSyncEffect(() => { console.log('Synchronized effect') })
9watch()
用于观察响应式数据的变化,可以指定特定的响应式数据或计算属性。
watch(count, (newCount) => { console.log(newCount) })
10onWatcherCleanup()
清理监听器,在观察的数据不再需要时调用。
watch(count, () => {}, onWatcherCleanup(() => { console.log('cleaned up') }))
11isRef()
检查一个值是否是 ref 类型。
isRef(count)
12unref()
解包一个 ref 的值。
unref(count)
13toRef()
创建一个从对象中提取的响应式引用。
const countRef = toRef(state, 'count')
14toValue()
解包 ref 或 reactive 类型的值。
toValue(count)
15toRefs()
将响应式对象的每个属性转换为独立的 ref
const { count } = toRefs(state)
16isProxy()
检查一个对象是否是 Vue 的代理对象。
isProxy(state)
17isReactive()
检查一个对象是否是响应式对象。
isReactive(state)
18isReadonly()
检查一个对象是否是只读的响应式对象。
isReadonly(state)
19shallowRef()
创建一个浅层的 ref,仅使对象的第一层属性响应式。
const state = shallowRef({ count: 0 })
20triggerRef()
强制触发 ref 的更新。
triggerRef(count)
21customRef()
创建一个自定义的响应式引用,允许开发者自定义 getter 和 setter。
const count = customRef((track, trigger) => { let value = 0; return { get: () => value, set: (val) => { value = val; trigger() } } })
22shallowReactive()
创建一个浅层响应式对象,只有对象的第一层属性是响应式的。
const state = shallowReactive({ count: 0 })
23shallowReadonly()
创建一个浅层只读的响应式对象,只有对象的第一层属性是只读的。
const state = shallowReadonly({ count: 0 })
24toRaw()
获取一个代理对象的原始对象。
const rawState = toRaw(state)
25markRaw()
将对象标记为不可代理的对象,Vue 将跳过该对象的响应式处理。
const obj = markRaw({ count: 0 })
26effectScope()
创建一个新的 effect scope,用于管理副作用。
const scope = effectScope()
27getCurrentScope()
获取当前的 effect scope。
const scope = getCurrentScope()
28onScopeDispose()
在 effect scope 被销毁时执行清理函数。
onScopeDispose(() => { console.log('Scope disposed') })
29onMounted()
组件挂载完成时调用的生命周期钩子。
onMounted(() => { console.log('Component mounted') })
30onUpdated()
组件更新时调用的生命周期钩子。
onUpdated(() => { console.log('Component updated') })
31onUnmounted()
组件卸载时调用的生命周期钩子。
onUnmounted(() => { console.log('Component unmounted') })
32onBeforeMount()
组件挂载前调用的生命周期钩子。
onBeforeMount(() => { console.log('Before mount') })
33onBeforeUpdate()
组件更新前调用的生命周期钩子。
onBeforeUpdate(() => { console.log('Before update') })
34onBeforeUnmount()
组件卸载前调用的生命周期钩子。
onBeforeUnmount(() => { console.log('Before unmount') })
35onErrorCaptured()
捕获组件树中未处理的错误。
onErrorCaptured((err, instance, info) => { console.error(err) })
36onRenderTracked()
组件渲染过程中,响应式数据被追踪时触发的钩子。
onRenderTracked((event) => { console.log(event) })
37onRenderTriggered()
组件渲染过程中,响应式数据发生变化时触发的钩子。
onRenderTriggered((event) => { console.log(event) })
38onActivated()
在组件被激活时调用的生命周期钩子(用于 keep-alive 组件)。
onActivated(() => { console.log('Component activated') })
39onDeactivated()
在组件被停用时调用的生命周期钩子(用于 keep-alive 组件)。
onDeactivated(() => { console.log('Component deactivated') })
40onServerPrefetch()
组件在服务器端渲染时预取数据的钩子。
onServerPrefetch(async () => { await fetchData() })
41provide()
向下传递依赖给后代组件。
provide('key', value)
42inject()
从父级组件或祖先组件注入依赖。
const value = inject('key')
43hasInjectionContext()
检查当前是否有注入上下文。
hasInjectionContext()
44useAttrs()
获取组件的所有属性,包括传递给组件的 HTML 特性。
const attrs = useAttrs()
45useSlots()
获取组件的插槽内容。
const slots = useSlots()
46useModel()
获取当前组件的 v-model 绑定的值。
const modelValue = useModel()
47useTemplateRef()
获取模板中元素的引用。
const templateRef = useTemplateRef('elementId')
48useId()
获取一个唯一的标识符。
const uniqueId = useId()

七.内置属性

在 Vue.js 中,is、key 和 ref 是三个常用的内置属性

is 属性

在 Vue.js 中,is 属性通常用于动态组件的实现,特别是当你希望在运行时动态地切换不同的组件时非常有用。

  • 类型: String 或 Object
  • 作用is 属性用于动态地指定当前 <component> 组件应该渲染哪一个子组件。通常结合 <component> 元素和动态组件的特性一起使用,允许你在运行时基于数据来切换不同的组件。

key 属性

  • 类型: String 或 Number

  • 作用: 在 Vue.js 的列表渲染中,每个 v-for 循环中的元素需要有一个唯一的 key 属性。key 的作用是帮助 Vue 识别每个节点的唯一性,从而高效地更新虚拟 DOM。当 Vue 重新渲染列表时,会根据 key 来决定是否重新使用现有 DOM 元素或者重新创建。

ref 属性

  • 类型: String 或 Object

  • 作用ref 是用来给元素或子组件注册引用信息的。在实际开发中,你可以使用 ref 来访问具体的 DOM 元素或子组件实例,从而进行一些操作,如调用方法、访问属性等。

八、内置组件

1. component

<component> 是一个抽象的组件,用于动态地渲染不同的组件或元素。通过绑定 is 属性可以实现动态组件的切换和渲染。

<component :is="currentComponent"></component>

2. transition 和 transition-group

<transition> 和 <transition-group> 提供了在 Vue.js 中实现过渡和动画效果的功能。

通过定义过渡的 CSS 类名,可以控制元素在进入或离开 DOM 时的动画效果。

3. keep-alive

<keep-alive> 是一个抽象组件,用于保持组件状态或避免多次渲染。

当组件被 <keep-alive> 包裹时,其状态将会被缓存,而不是每次切换时重新渲染。

<keep-alive>
  <component :is="currentComponent"></component>
</keep-alive>

4. slot

<slot> 是 Vue.js 中用于插入内容的插槽组件。它允许父组件将子组件的内容传递到特定的插槽位置,使得组件更加灵活和可复用。

5. teleport

<teleport> 允许你将 DOM 元素渲染到应用的任何地方,而不受当前 DOM 结构的限制。这在需要在应用中动态移动元素时非常有用,例如在模态框中渲染弹出内容。

6. Suspense

<Suspense> 是 Vue.js 3.x 中新增的组件,用于处理异步组件的加载和状态。它可以在异步组件加载完成之前显示占位内容,并处理加载状态和错误。

九.组件实例

组件选项对象可以包含如下属性:

  • data: 数据对象,用于存储组件的响应式数据。
  • props: 属性数组或对象,用于接收父组件传递的数据。
  • computed: 计算属性对象,根据响应式依赖进行动态计算。
  • methods: 方法对象,包含组件内部的函数和操作。
  • watch: 监听器对象,用于监听数据变化并做出响应。
  • template: 字符串,定义组件的模板结构。
  • render: 函数,用于渲染组件的虚拟 DOM。
  • setup: 函数,用于设置组件的初始状态、数据、计算属性和监听器等(Vue 3 中)。

生命周期钩子

Vue 组件实例具有一些生命周期钩子函数,允许开发者在组件生命周期的不同阶段执行自定义逻辑。常见的生命周期钩子包括 createdmountedupdated 和 destroyed 等。

$data

$data 属性包含组件实例的所有数据属性。它是响应式的,即当数据发生变化时,相关的视图会自动更新。

$props

$props 属性包含当前组件接收的所有父组件传递的属性(props)。它是只读的。

$refs

$refs 包含了组件内所有拥有 ref 特性的 DOM 元素或子组件实例。可以通过 $refs 来访问这些元素或组件实例。

$el

$el 属性表示当前组件实例的根 DOM 元素。在组件被挂载后才能访问到该属性。

$attrs

$attrs 包含了父组件传递给当前组件但未在子组件声明的所有属性。这些属性可以用于向子组件传递额外的非 prop 特性。

$listeners

$listeners 包含了父组件传递给当前组件的所有监听器(事件处理函数),可以直接绑定到组件的根元素或其他元素上。

$mount()

$mount() 方法手动将 Vue 组件挂载到 DOM 元素上。在 Vue 3 中,通常通过 createApp().mount() 自动挂载,少数情况下需要手动挂载。

$destroy()

$destroy() 方法销毁当前组件实例,解绑其所有的事件监听器并释放其占用的资源。在一些特定的场景,如动态创建和销毁组件时很有用。

$emit()

$emit() 方法用于触发当前组件实例上的自定义事件,并传递数据给父组件。通常与 v-on 指令结合使用。

$nextTick()

$nextTick() 方法在下次 DOM 更新循环结束之后执行指定的回调函数。用于在 DOM 更新之后执行一些操作

$watch()

$watch() 方法用于监听组件实例上的数据变化,并在数据变化时执行指定的回调函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值