欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Vue3 教程 runoob 有大用 有大大用

 

1) Vue3 教程

Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架。

Vue 只关注视图层, 采用自底向上增量开发的设计。

Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

Vue 学习起来非常简单,本教程基于 Vue 3.0.5 版本测试。


阅读本教程前,您需要了解的知识:

  • HTML

  • CSS

  • JavaScript

本教程主要介绍了 Vue3.x 版本的使用。


第一个实例

Vue 3.0 实例

<div id="hello-vue" class="demo">  {{ message }} </div>

尝试一下 »

点击 "尝试一下" 按钮查看在线实例


参考资料:

官方网站:https://v3.vuejs.org/

中文文档: https://v3.cn.vuejs.org/guide/introduction.html

Webpack 入门教程:https://www.runoob.com/w3cnote/webpack-tutorial.html

来自  https://www.runoob.com/vue3/vue3-tutorial.html



2)

Vue3 安装

1、独立版本

我们可以在 Vue.js 的官网上直接下载最新版本, 并用 <script> 标签引入。

下载 Vue.js


2、使用 CDN 方法

以下推荐国外比较稳定的两个 CDN,国内还没发现哪一家比较好,目前还是建议下载到本地。

Staticfile CDN(国内)

<div id="app">  <p>{{ message }}</p> </div>

尝试一下 »

unpkg(推荐)

<div id="app">  <p>{{ message }}</p> </div>

尝试一下 »

cdnjs

<div id="app">  <p>{{ message }}</p> </div>

尝试一下 »



3、NPM 方法

由于 npm 安装速度慢,本教程使用了淘宝的镜像及其命令 cnpm,安装使用介绍参照:使用淘宝 NPM 镜像

npm 版本需要大于 3.0,如果低于此版本需要升级它:

# 查看版本
$ npm -v
2.3.0

#升级 npm
cnpm install npm -g


# 升级或安装 cnpm
npm install cnpm -g

在用 Vue.js 构建大型应用时推荐使用 cnpm 安装,cnpm 能很好地和 Webpack 或 Browserify 模块打包器配合使用:

# 最新稳定版
$ cnpm install vue@next

命令行工具

Vue.js 提供一个官方命令行工具,可用于快速搭建大型单页应用。

# 全局安装 vue-cli
$ cnpm install -g @vue/cli
# 安装完后查看版本
$ vue --version
@vue/cli 4.5.11

注意:vue-cli 3.x 和 vue-cli 2.x 使用了相同的 vue 命令,如果你之前已经安装了 vue-cli 2.x,它会被替换为 Vue-cli 3.x。

安装 @vue/cli-int:

$ cnpm i -g @vue/cli-init

创建项目

$ vue init webpack runoob-vue3-test
# 这里需要进行一些配置,默认回车即可
? Project name runoob-vue3-test
? Project description A Vue.js project
? Author runoob <test@runoob.com>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests Yes
? Pick a test runner jest
? Setup e2e tests with Nightwatch? Yes
? Should we run `npm install` for you after the project has been created? (recommended) npm

   vue-cli · Generated "runoob-vue3-test".


# Installing project dependencies ...
# ========================

...

进入项目,安装并运行:

$ cd runoob-vue3-test
$ cnpm run dev
  DONE  Compiled successfully in 2558ms          

 I  Your application is running here: http://localhost:8080

成功执行以上命令后访问 http://localhost:8080/,输出结果如下所示:

注意:Vue.js 不支持 IE8 及其以下 IE 版本。


Vite (推荐)

Vite 是一个 web 开发构建工具,由于其原生 ES 模块导入方式,可以实现闪电般的冷服务器启动。

通过在终端中运行以下命令,可以使用 Vite 快速构建 Vue 项目,语法格式如下:

npm init @vitejs/app <project-name>

创建项目 runoob-vue3-test2:

$  cnpm init @vitejs/app runoob-vue3-test2

运行项目:

$ cd runoob-vue3-test2
$ cnpm install
$ cnpm run dev
> runoob-vue3-test2@0.0.0 dev /Users/tianqixin/runoob-test/vue3/runoob-vue3-test2
> vite

[vite] Optimizable dependencies detected:
vue

  Dev server running at:
  > Local:    http://localhost:3000/

打开 http://localhost:3000/,显示如下:


来自  https://www.runoob.com/vue3/vue3-install.html


3)

Vue3 项目打包

打包 Vue 项目使用以下命令:

cnpm run build

执行以上命令,输出结果如下:

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

如果直接双击打开 index.html,在浏览器中页面可能是空白了,要正常显示则需要修改下 index.html 文件中 js、css 文件路径。

例如我们打开 dist/index.html 文件看到 css 和 js 文件路径是绝对路径:

<link href=/static/css/app.33da80d69744798940b135da93bc7b98.css rel=stylesheet>
<script type=text/javascript src=/static/js/app.717bb358ddc19e181140.js></script>
...

我们把 js、css 文件路径修改为相对路径:

<link href=static/css/app.33da80d69744798940b135da93bc7b98.css rel=stylesheet>
<script type=text/javascript src=static/js/app.717bb358ddc19e181140.js></script>
...

这样直接双击 dist/index.html 文件就可以在浏览器中看到效果了。


来自  https://www.runoob.com/vue3/vue3-build.html



4)

Vue3 目录结构

上一章节中我们使用了 npm 安装项目(Vue-cli 和 Vite),我们在 IDE(Vscode、Atom等) 中打开该目录,结构如下所示:

命令行工具 vue-cli(runoob-vue3-test):

Vite(runoob-vue3-test2)

目录解析

目录/文件说明
build项目构建(webpack)相关代码
config配置目录,包括端口号等。我们初学可以使用默认的。
node_modulesnpm 加载的项目依赖模块
src

这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:

  • assets: 放置一些图片,如logo等。

  • components: 目录里面放了一个组件文件,可以不用。

  • App.vue: 项目入口文件,我们也可以直接将组件写这里,而不使用 components 目录。

  • main.js: 项目的核心文件。

  • index.css: 样式文件。

static静态资源目录,如图片、字体等。
public公共资源目录。
test初始测试目录,可删除
.xxxx文件这些是一些配置文件,包括语法配置,git配置等。
index.html首页入口文件,你可以添加一些 meta 信息或统计代码啥的。
package.json项目配置文件。
README.md项目的说明文档,markdown 格式
dist使用 npm run build 命令打包后会生成该目录。
接下来,我们以 runoob-vue3-test2 为例,打开目录下的 src/APP.vue 文件,代码如下(解释在注释中):

src/APP.vue 文件代码

<!-- 展示模板 -->
<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg="Hello Vue 3.0 + Vite" />
</template>
<!-- Vue 代码 -->
<script>
/* 从 src/components/HelloWorld.vue 中引入 HelloWorld 组件 */
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

接下来我们可以尝试修改下初始化的项目,将 src/APP.vue 修改为以下代码:

src/APP.vue 文件代码

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg="欢迎来到菜鸟教程!" />
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>
打开页面 http://localhost:3000/,一般修改后会自动刷新,显示效果如下所示:


来自   https://www.runoob.com/vue3/vue3-directory-structure.html





5)


Vue3 起步

刚开始学习 Vue,我们不推荐使用 vue-cli 命令行工具来创建项目,更简单的方式是直接在页面引入 vue.global.js 文件来测试学习。

Vue3 中的应用是通过使用 createApp 函数来创建的,语法格式如下:

const app = Vue.createApp({ /* 选项 */ })

传递给 createApp 的选项用于配置根组件。在使用 mount() 挂载应用时,该组件被用作渲染的起点。

一个简单的实例:

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

createApp 的参数是根组件(HelloVueApp),在挂载应用时,该组件是渲染的起点。

一个应用需要被挂载到一个 DOM 元素中,以上代码使用 mount('#hello-vue') 将 Vue 应用 HelloVueApp 挂载到 <div id="hello-vue"></div> 中。

接下来我们从 Hello Vue!! 的代码开始学起。

Vue 3.0 实例

<div id="hello-vue" class="demo">  {{ message }} </div> <script> const HelloVueApp = {  data() {    return {      message: 'Hello Vue!!'    }  } } Vue.createApp(HelloVueApp).mount('#hello-vue') </script>

尝试一下 »

点击 "尝试一下" 按钮查看在线实例

以上实例中,我们先在 HTML 页面中引入 Vue 的 JS 文件:


<script src="https://unpkg.com/vue@next"></script>

HTML 页面中有一个 div 元素:

<div id="hello-vue" class="demo">
  {{ message }}
</div>

mount('#hello-vue') 将 Vue 应用 HelloVueApp 挂载到 <div id="hello-vue"></div> 中。

{{ }} 用于输出对象属性和函数返回值。

{{ message }} 对应应用中 message 的值。

data 选项

data 选项是一个函数。Vue 在创建新组件实例的过程中调用此函数。它应该返回一个对象,然后 Vue 会通过响应性系统将其包裹起来,并以 $data 的形式存储在组件实例中。

实例

const app = Vue.createApp({
  data() {
    return { count: 4 }
  }
})

const vm = app.mount('#app')

document.write(vm.$data.count) // => 4
document.write("<br>")
document.write(vm.count)       // => 4
document.write("<br>")
// 修改 vm.count 的值也会更新 $data.count
vm.count = 5
document.write(vm.$data.count) // => 5
document.write("<br>")
// 反之亦然
vm.$data.count = 6
document.write(vm.count) // => 6

尝试一下 »

以上实例属性仅在实例首次创建时被添加,所以你需要确保它们都在 data 函数返回的对象中。

方法

我们可以在组件中添加方法,使用 methods 选项,该选项包含了所需方法的对象。

以下实例我们添加了 methods 选项,选项中包含了 increment() 方法:

实例

const app = Vue.createApp({
  data() {
    return { count: 4 }
  },
  methods: {
    increment() {
      // `this` 指向该组件实例
      this.count++
    }
  }
})

const vm = app.mount('#app')

document.write(vm.count) // => 4
document.write("<br>")
vm.increment()

document.write(vm.count) // => 5

尝试一下 »


来自  https://www.runoob.com/vue3/vue3-intro.html



6)


Vue3 模板语法

Vue 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。

Vue 的核心是一个允许你采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统。

结合响应系统,在应用状态改变时, Vue 能够智能地计算出重新渲染组件的最小代价并应用到 DOM 操作上。


插值

文本

数据绑定最常见的形式就是使用 {{...}}(双大括号)的文本插值:

文本插值

<div id="app">  <p>{{ message }}</p> </div>

尝试一下 »

{{...}} 标签的内容将会被替代为对应组件实例中 message 属性的值,如果 message 属性的值发生了改变,{{...}} 标签内容也会更新。

如果不想改变标签的内容,可以通过使用 v-once 指令执行一次性地插值,当数据改变时,插值处的内容不会更新。

<span v-once>这个将不会改变: {{ message }}</span>

Html

使用 v-html 指令用于输出 html 代码:

v-html 指令

<div id="example1" class="demo">    <p>使用双大括号的文本插值: {{ rawHtml }}</p>    <p>使用 v-html 指令: <span v-html="rawHtml"></span></p> </div> <script> const RenderHtmlApp = {  data() {    return {      rawHtml: '<span style="color: red">这里会显示红色!</span>'    }  } } Vue.createApp(RenderHtmlApp).mount('#example1') </script>

尝试一下 »

属性

HTML 属性中的值应使用 v-bind 指令。

<div v-bind:id="dynamicId"></div>
对于布尔属性,常规值为 true 或 false,如果属性值为 null 或 undefined,则该属性不会显示出来。
<button v-bind:disabled="isButtonDisabled">按钮</button>

以上代码中如果 isButtonDisabled 的值是 null 或 undefined,则 disabled 属性甚至不会被包含在渲染出来的 <button> 元素中。

以下实例判断 use 的值,如果为 true 使用 class1 类的样式,否则不使用该类:

v-bind 指令

<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>

尝试一下 »

表达式

Vue.js 都提供了完全的 JavaScript 表达式支持。

JavaScript 表达式

<div id="app">    {{5+5}}<br>    {{ ok ? 'YES' : 'NO' }}<br>    {{ message.split('').reverse().join('') }}    <div v-bind:id="'list-' + id">菜鸟教程</div> </div>     <script> const app = {  data() {    return {      ok: true,      message: 'RUNOOB!!',      id: 1    }  } } Vue.createApp(app).mount('#app') </script> </script>

尝试一下 »

表达式会在当前活动实例的数据作用域下作为 JavaScript 被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效:

<!--  这是语句,不是表达式:-->
{{ var a = 1 }}

<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

指令

指令是带有 v- 前缀的特殊属性。

指令用于在表达式的值改变时,将某些行为应用到 DOM 上。如下例子:

实例

<div id="app">    <p v-if="seen">现在你看到我了</p> </div>     <script> const app = {  data() {    return {      seen: true  /* 改为false,信息就无法显示 */    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

这里, v-if 指令将根据表达式 seen 的值( true 或 false )来决定是否插入 p 元素。

另外还有其它很多指令,每个都有特殊的功能。例如,v-for 指令可以绑定数组的数据来渲染一个项目列表:

实例

<div id="app">
  <ol>
    <li v-for="site in sites">
      {{ site.text }}
    </li>
  </ol>
</div>
<script>
const app = {
  data() {
    return {
      sites: [
        { text: 'Google' },
        { text: 'Runoob' },
        { text: 'Taobao' }
      ]
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

尝试一下 »

参数

参数在指令后以冒号指明。例如, v-bind 指令被用来响应地更新 HTML 属性:

实例

<div id="app">    <p><a v-bind:href="url">菜鸟教程</a></p> </div>     <script> const app = {  data() {    return {      url: 'https://www.runoob.com'    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

在这里 href 是参数,告知 v-bind 指令将该元素的 href 属性与表达式 url 的值绑定。

另一个例子是 v-on 指令,它用于监听 DOM 事件:

<!-- 完整语法 -->
<a v-on:click="doSomething"> ... </a>

<!-- 缩写 -->
<a @click="doSomething"> ... </a>

<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>

在这里参数是监听的事件名。

修饰符

修饰符是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()

<form v-on:submit.prevent="onSubmit"></form>

用户输入

在 input 输入框中我们可以使用 v-model 指令来实现双向数据绑定:

双向数据绑定

<div id="app">    <p>{{ message }}</p>    <input v-model="message"> </div> <script> const app = {  data() {    return {      message: 'Runoob!'    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

v-model 指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。

按钮的事件我们可以使用 v-on 监听事件,并对用户的输入进行响应。

以下实例在用户点击按钮后对字符串进行反转操作:

字符串反转

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="app">    <p>{{ message }}</p>    <button v-on:click="reverseMessage">反转字符串</button> </div>     <script> const app = {  data() {    return {      message: 'Runoob!'    }  },  methods: {    reverseMessage() {      this.message = this.message        .split('')        .reverse()        .join('')    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

缩写

v-bind 缩写

Vue.js 为两个最为常用的指令提供了特别的缩写:

<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>

v-on 缩写

<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>



来自  https://www.runoob.com/vue3/vue3-template-syntax.html


7)

Vue3 条件语句

条件判断

v-if

条件判断使用 v-if 指令,指令的表达式返回 true 时才会显示:

v-if 指令

在元素中使用 v-if 指令:

<div id="app">    <p v-if="seen">现在你看到我了</p> </div>     <script> const app = {  data() {    return {      seen: true /* 改为false,信息就无法显示 */    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

这里, v-if 指令将根据表达式 seen 的值( true 或 false )来决定是否插入 p 元素。

因为 v-if 是一个指令,所以必须将它添加到一个元素上。如果是多个元素,可以包裹在 <template> 元素上,并在上面使用 v-if。最终的渲染结果将不包含 <template> 元素。

v-if 指令

在 <template> 元素上使用 v-if 指令:

<div id="app">    <template v-if="seen">        <h1>网站</h1>        <p>Google</p>        <p>Runoob</p>        <p>Taobao</p>    </template> </div>     <script> const app = {  data() {    return {      seen: true /* 改为false,信息就无法显示 */    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »


v-else

可以用 v-else 指令给 v-if 添加一个 "else" 块:

v-else 指令

随机生成一个数字,判断是否大于 0.5,然后输出对应信息:

<div id="app">    <div v-if="Math.random() > 0.5">      随机数大于 0.5    </div>    <div v-else>      随机数小于等于 0.5    </div> </div>     <script> Vue.createApp(app).mount('#app') </script>

尝试一下 »

v-else-if

v-else-if 即 v-if 的 else-if 块,可以链式的使用多次:

v-else 指令

判断 type 变量的值:

<div id="app">    <div v-if="type === 'A'">         A    </div>    <div v-else-if="type === 'B'">      B    </div>    <div v-else-if="type === 'C'">      C    </div>    <div v-else>      Not A/B/C    </div> </div>     <script> const app = {  data() {    return {      type: "C"    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

v-else 、v-else-if 必须跟在 v-if 或者 v-else-if之后。

v-show

我们也可以使用 v-show 指令来根据条件展示元素:

v-show 指令

<h1 v-show="ok">Hello!</h1>

尝试一下 »


来自   https://www.runoob.com/vue3/vue3-v-if.html



8)

Vue.js 循环语句

循环使用 v-for 指令。

v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组并且 site 是数组元素迭代的别名。

v-for 可以绑定数据到数组来渲染一个列表:

v-for 实例

<div id="app">
  <ol>
    <li v-for="site in sites">
      {{ site.text }}
    </li>
  </ol>
</div>
<script>
const app = {
  data() {
    return {
      sites: [
        { text: 'Google' },
        { text: 'Runoob' },
        { text: 'Taobao' }
      ]
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

尝试一下 »

v-for 还支持一个可选的第二个参数,参数值为当前项的索引:

v-for 实例

index 为列表项的索引值:

<div id="app">
  <ol>
    <li v-for="(site, index) in sites">
      {{ index }} -{{ site.text }}
    </li>
  </ol>
</div>
<script>
const app = {
  data() {
    return {
      sites: [
        { text: 'Google' },
        { text: 'Runoob' },
        { text: 'Taobao' }
      ]
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

尝试一下 »

模板 <template> 中使用 v-for:

v-for

<ul>  <template v-for="site in sites">    <li>{{ site.name }}</li>    <li>--------------</li>  </template> </ul>

尝试一下 »

v-for 迭代对象

v-for 可以通过一个对象的属性来迭代数据:

v-for

<div id="app">  <ul>    <li v-for="value in object">    {{ value }}    </li>  </ul> </div> <script> const app = {  data() {    return {      object: {        name: '菜鸟教程',        url: 'http://www.runoob.com',        slogan: '学的不仅是技术,更是梦想!'      }    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

你也可以提供第二个的参数为键名:

v-for

<div id="app">  <ul>    <li v-for="(value, key) in object">    {{ key }} : {{ value }}    </li>  </ul> </div>

尝试一下 »

第三个参数为索引:

v-for

<div id="app">  <ul>    <li v-for="(value, key, index) in object">     {{ index }}. {{ key }} : {{ value }}    </li>  </ul> </div>

尝试一下 »

v-for 迭代整数

v-for 也可以循环整数

v-for

<div id="app">  <ul>    <li v-for="n in 10">     {{ n }}    </li>  </ul> </div>

尝试一下 »

显示过滤/排序后的结果

我们可以对数组的元素进行处理后再显示出来,一般可以通过创建一个计算属性,来返回过滤或排序后的数组。

v-for 实例

输出数组中的偶数:

<div id="app">  <ul>    <li v-for="n in evenNumbers">{{ n }}</li>  </ul> </div>

尝试一下 »

v-for/v-if 联合使用

以上实例联合使用 v-for/v-if 给 select 设置默认值:

v-for/v-if 实例

v-for 循环出列表,v-if 设置选中值:

<div id="app">   <select @change="changeVal($event)" v-model="selOption">      <template v-for="(site,index) in sites" :site="site" :index="index" :key="site.id">         <!-- 索引为 1 的设为默认值,索引值从0 开始-->         <option v-if = "index == 1" :value="site.name" selected>{{site.name}}</option>         <option v-else :value="site.name">{{site.name}}</option>      </template>   </select>   <div>您选中了:{{selOption}}</div> </div> <script> const app = {    data() {        return {            selOption: "Runoob",            sites: [                  {id:1,name:"Google"},                  {id:2,name:"Runoob"},                  {id:3,name:"Taobao"},            ]         }            },    methods:{        changeVal:function(event){            this.selOption = event.target.value;            alert("你选中了"+this.selOption);        }    } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

在组件上使用 v-for

如果你还没了解组件的内容,可以先跳过这部分。

在自定义组件上,你可以像在任何普通元素上一样使用 v-for:

<my-component v-for="item in items" :key="item.id"></my-component>

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

<my-component
  v-for="(item, index) in items"
  :item="item"
  :index="index"
  :key="item.id"
></my-component>

不自动将 item 注入到组件里的原因是,这会使得组件与 v-for 的运作紧密耦合。明确组件数据的来源能够使组件在其他场合重复使用。

下面是一个简单的 todo 列表的完整例子:

实例

<div id="todo-list-example">  <form v-on:submit.prevent="addNewTodo">    <label for="new-todo">Add a todo</label>    <input      v-model="newTodoText"      id="new-todo"          placeholder="E.g. Feed the cat"    />    <button>Add</button>  </form>  <ul>

Vue.js 循环语句

循环使用 v-for 指令。

v-for 指令需要以 site in sites 形式的特殊语法, sites 是源数据数组并且 site 是数组元素迭代的别名。

v-for 可以绑定数据到数组来渲染一个列表:

v-for 实例

<div id="app">
  <ol>
    <li v-for="site in sites">
      {{ site.text }}
    </li>
  </ol>
</div>
<script>
const app = {
  data() {
    return {
      sites: [
        { text: 'Google' },
        { text: 'Runoob' },
        { text: 'Taobao' }
      ]
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

尝试一下 »

v-for 还支持一个可选的第二个参数,参数值为当前项的索引:

v-for 实例

index 为列表项的索引值:

<div id="app">
  <ol>
    <li v-for="(site, index) in sites">
      {{ index }} -{{ site.text }}
    </li>
  </ol>
</div>
<script>
const app = {
  data() {
    return {
      sites: [
        { text: 'Google' },
        { text: 'Runoob' },
        { text: 'Taobao' }
      ]
    }
  }
}

Vue.createApp(app).mount('#app')
</script>

尝试一下 »

模板 <template> 中使用 v-for:

v-for

<ul>  <template v-for="site in sites">    <li>{{ site.name }}</li>    <li>--------------</li>  </template> </ul>

尝试一下 »

v-for 迭代对象

v-for 可以通过一个对象的属性来迭代数据:

v-for

<div id="app">  <ul>    <li v-for="value in object">    {{ value }}    </li>  </ul> </div> <script> const app = {  data() {    return {      object: {        name: '菜鸟教程',        url: 'http://www.runoob.com',        slogan: '学的不仅是技术,更是梦想!'      }    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

你也可以提供第二个的参数为键名:

v-for

<div id="app">  <ul>    <li v-for="(value, key) in object">    {{ key }} : {{ value }}    </li>  </ul> </div>

尝试一下 »

第三个参数为索引:

v-for

<div id="app">  <ul>    <li v-for="(value, key, index) in object">     {{ index }}. {{ key }} : {{ value }}    </li>  </ul> </div>

尝试一下 »

v-for 迭代整数

v-for 也可以循环整数

v-for

<div id="app">  <ul>    <li v-for="n in 10">     {{ n }}    </li>  </ul> </div>

尝试一下 »

显示过滤/排序后的结果

我们可以对数组的元素进行处理后再显示出来,一般可以通过创建一个计算属性,来返回过滤或排序后的数组。

v-for 实例

输出数组中的偶数:

<div id="app">  <ul>    <li v-for="n in evenNumbers">{{ n }}</li>  </ul> </div>

尝试一下 »

v-for/v-if 联合使用

以上实例联合使用 v-for/v-if 给 select 设置默认值:

v-for/v-if 实例

v-for 循环出列表,v-if 设置选中值:

<div id="app">   <select @change="changeVal($event)" v-model="selOption">      <template v-for="(site,index) in sites" :site="site" :index="index" :key="site.id">         <!-- 索引为 1 的设为默认值,索引值从0 开始-->         <option v-if = "index == 1" :value="site.name" selected>{{site.name}}</option>         <option v-else :value="site.name">{{site.name}}</option>      </template>   </select>   <div>您选中了:{{selOption}}</div> </div> <script> const app = {    data() {        return {            selOption: "Runoob",            sites: [                  {id:1,name:"Google"},                  {id:2,name:"Runoob"},                  {id:3,name:"Taobao"},            ]         }            },    methods:{        changeVal:function(event){            this.selOption = event.target.value;            alert("你选中了"+this.selOption);        }    } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

在组件上使用 v-for

如果你还没了解组件的内容,可以先跳过这部分。

在自定义组件上,你可以像在任何普通元素上一样使用 v-for:

<my-component v-for="item in items" :key="item.id"></my-component>

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

<my-component
  v-for="(item, index) in items"
  :item="item"
  :index="index"
  :key="item.id"
></my-component>

不自动将 item 注入到组件里的原因是,这会使得组件与 v-for 的运作紧密耦合。明确组件数据的来源能够使组件在其他场合重复使用。

下面是一个简单的 todo 列表的完整例子:

实例

<div id="todo-list-example">  <form v-on:submit.prevent="addNewTodo">    <label for="new-todo">Add a todo</label>    <input      v-model="newTodoText"      id="new-todo"  <!--这里好像不能用key,好像 key 是关键字,且 key 用在对象当中 -->      placeholder="E.g. Feed the cat"    />    <button>Add</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>

尝试一下 »
   <todo-item      v-for="(todo, index) in todos"      :key="todo.id"      :title="todo.title"      @remove="todos.splice(index, 1)"    ></todo-item>  </ul> </div>

尝试一下 »


来自  https://www.runoob.com/vue3/vue3-v-for.html




9)

Vue3 组件

组件(Component)是 Vue.js 最强大的功能之一。

组件可以扩展 HTML 元素,封装可重用的代码。

组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:

每个 Vue 应用都是通过用 createApp 函数创建的,传递给 createApp 的选项用于配置根组件。当我们挂载应用时,该组件被用作渲染的起点。

一个应用需要被挂载到一个 DOM 元素中。

以下实例我们将 Vue 应用挂载到 <div id="app"></div>,应该传入 #app:

const RootComponent = { /* 选项 */ }
const app = Vue.createApp(RootComponent)
const vm = app.mount('#app')

注册一个全局组件语法格式如下:

const app = Vue.createApp({...})

app.component('my-component-name', {
  /* ... */
})

my-component-name 为组件名,/* ... */ 部分为配置选项。注册后,我们可以使用以下方式来调用组件:

<my-component-name></my-component-name>

一个简单的 Vue 组件的实例:

全局组件实例

注册一个简单的全局组件 runoob,并使用它:

<div id="app">    <runoob></runoob> </div> <script> // 创建一个Vue 应用 const app = Vue.createApp({}) // 定义一个名为 runoob的新全局组件 app.component('runoob', {    template: '<h1>自定义组件!</h1>' }) app.mount('#app') </script>

尝试一下 »

接下来我们再注册一个 button-counter 组件,在每次点击后,计数器会加 1:

实例

// 创建一个Vue 应用
const app = Vue.createApp({})

// 定义一个名为 button-counter 的新全局组件
app.component('button-counter', {
  data() {
    return {
      count: 0
    }
  },
  template: `
    <button @click="count++">
      点了 {{ count }} 次!
    </button>`
})
app.mount('#app')
</script>

尝试一下 »

注意:template 中 ` 是反引号,不是单单引号 '

组件的复用

你可以将组件进行任意次数的复用:

实例

<div id="components-demo">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>

尝试一下 »

全局组件

以上的实例中我们的组件都只是通过 component 全局注册的。

全局注册的组件可以在随后创建的 app 实例模板中使用,也包括根实例组件树中的所有子组件的模板中。。

全局组件实例

注册一个简单的全局组件 runoob,并使用它:

<div id="app">    <runoob></runoob> </div> <script> // 创建一个Vue 应用 const app = Vue.createApp({}) // 定义一个名为 runoob 的新全局组件 app.component('runoob', {    template: '<h1>自定义组件!</h1>' }) app.mount('#app') </script>

尝试一下 »

局部组件

全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。

在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:

const ComponentA = {
  /* ... */
}
const ComponentB = {
  /* ... */
}
const ComponentC = {
  /* ... */
}

然后在 components 选项中定义你想要使用的组件:

const app = Vue.createApp({
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字(component-a、component-b),其属性值就是这个组件的选项对象(ComponentA、ComponentB)。

我们也可以在实例选项中注册局部组件,这样组件只能在这个实例中使用:

局部组件实例

注册一个简单的局部组件 runoobA,并使用它:

<div id="app">    <runoob-a></runoob-a> </div> <script> var runoobA = {  template: '<h1>自定义组件!</h1>' } const app = Vue.createApp({  components: {    'runoob-a': runoobA  } }) app.mount('#app') </script>

尝试一下 »

Prop

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

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

Prop 实例

<div id="app">  <site-name title="Google"></site-namet>  <site-name title="Runoob"></site-namet>  <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>

尝试一下 »

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。

动态 Prop

类似于用 v-bind 绑定 HTML 特性到一个表达式,也可以用 v-bind 动态绑定 props 的值到父组件的数据中。每当父组件的数据变化时,该变化也会传导给子组件:

Prop 实例

<div id="app">  <site-info    v-for="site in sites"    :id="site.id"    :title="site.title"  ></site-info> </div> <script> const Site = {  data() {    return {      sites: [        { id: 1, title: 'Google' },        { id: 2, title: 'Runoob' },        { id: 3, title: 'Taobao' }      ]    }  } } const app = Vue.createApp(Site) app.component('site-info', {  props: ['id','title'],  template: `<h4>{{ id }} - {{ title }}</h4>` }) app.mount('#app') </script>

尝试一下 »

Prop 验证

组件可以为 props 指定验证要求。

为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:

Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})

当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

type 可以是下面原生构造器:

  • String

  • Number

  • Boolean

  • Array

  • Object

  • Date

  • Function

  • Symbol

type 也可以是一个自定义构造器,使用 instanceof 检测。


来自   https://www.runoob.com/vue3/vue3-components.html




10)


Vue3 计算属性

计算属性关键词: computed

计算属性在处理一些复杂逻辑时是很有用的。

可以看下以下反转字符串的例子:

实例 1

<div id="app">  {{ message.split('').reverse().join('') }} </div>

尝试一下 »

实例 1 中模板变的很复杂起来,也不容易看懂理解。

接下来我们看看使用了计算属性的实例:

实例 2

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="app">  <p>原始字符串: {{ message }}</p>  <p>计算后反转字符串: {{ reversedMessage }}</p> </div>     <script> const app = {  data() {    return {      message: 'RUNOOB!!'    }  },  computed: {    // 计算属性的 getter    reversedMessage: function () {      // `this` 指向 vm 实例      return this.message.split('').reverse().join('')    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

实例 2 中声明了一个计算属性 reversedMessage 。

提供的函数将用作属性 vm.reversedMessage 的 getter 。

vm.reversedMessage 依赖于 vm.message,在 vm.message 发生改变时,vm.reversedMessage 也会更新。


computed vs methods

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

实例 3

methods: {  reversedMessage2: function () {    return this.message.split('').reverse().join('')  } }

尝试一下 »

可以说使用 computed 性能会更好,但是如果你不希望缓存,你可以使用 methods 属性。


computed setter

computed 属性默认只有 getter ,不过在需要时你也可以提供一个 setter :

实例 4

var vm = new Vue({  el: '#app',  data: {    name: 'Google',    url: 'http://www.google.com'  },  computed: {    site: {      // getter      get: function () {        return this.name + ' ' + this.url      },      // setter      set: function (newValue) {        var names = newValue.split(' ')        this.name = names[0]        this.url = names[names.length - 1]      }    }  } }) // 调用 setter, vm.name 和 vm.url 也会被对应更新 vm.site = '菜鸟教程 http://www.runoob.com'; document.write('name: ' + vm.name); document.write('<br>'); document.write('url: ' + vm.url);

尝试一下 »

从实例运行结果看在运行 vm.site = '菜鸟教程 http://www.runoob.com'; 时,setter 会被调用, vm.name 和 vm.url 也会被对应更新。



来自   https://www.runoob.com/vue3/vu3-computed.html





11)

Vue3 监听属性

本章节,我们将为大家介绍 Vue3 监听属性 watch,我们可以通过 watch 来响应数据的变化。

以下实例通过使用 watch 实现计数器:

实例

<div id = "app">    <p style = "font-size:25px;">计数器: {{ counter }}</p>    <button @click = "counter++" style = "font-size:25px;">点我</button> </div>     <script> const app = {  data() {    return {      counter: 1    }  } } vm = Vue.createApp(app).mount('#app') vm.$watch('counter', function(nval, oval) {    alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!'); }); </script>

尝试一下 »

以下实例进行千米之间的换算:

实例

<head> <meta charset="utf-8"> <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id = "app">    千米 : <input type = "text" v-model = "kilometers">    米 : <input type = "text" v-model = "meters"> </div> <p id="info"></p>     <script> const app = {  data() {    return {      kilometers : 0,      meters:0    }  },  watch : {      kilometers:function(val) {          this.kilometers = val;          this.meters = this.kilometers * 1000      },      meters : function (val) {          this.kilometers = val/ 1000;          this.meters = val;      }  } } vm = Vue.createApp(app).mount('#app') vm.$watch('kilometers', function (newValue, oldValue) {    // 这个回调将在 vm.kilometers 改变后调用    document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue; }) </script>

尝试一下 »

点击 "尝试一下" 按钮查看在线实例

以上代码中我们创建了两个输入框,data 属性中, kilometers 和 meters 初始值都为 0。watch 对象创建了 data 对象的两个监控方法: kilometers 和 meters。

当我们再输入框输入数据时,watch 会实时监听数据变化并改变自身的值。可以看下如下视频演示:

异步加载中使用 watch

异步数据的加载 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。

以下实例我们使用 axios 库,后面会具体介绍。

实例

<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script>
  const watchExampleVM = Vue.createApp({
    data() {
      return {
        question: '',
        answer: '每个问题结尾需要输入 ? 号。'
      }
    },
    watch: {
      // 每当问题改变时,此功能将运行,以 ? 号结尾
      question(newQuestion, oldQuestion) {
        if (newQuestion.indexOf('?') > -1) {
          this.getAnswer()
        }
      }
    },
    methods: {
      getAnswer() {
        this.answer = '加载中...'
        axios
          .get('https://yesno.wtf/api')
          .then(response => {
            this.answer = response.data.answer
          })
          .catch(error => {
            this.answer = '错误! 无法访问 API。 ' + error
          })
      }
    }
  }).mount('#watch-example')
</script>

尝试一下 »


来自  https://www.runoob.com/vue3/vue3-watch.html



12)

Vue3 样式绑定

Vue.js class

class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。

v-bind 在处理 class 和 style 时, 表达式除了可以使用字符串之外,还可以是对象或数组。

v-bind:class 可以简写为 :class


class 属性绑定

我们可以为 v-bind:class 设置一个对象,从而动态的切换 class:

实例 1

实例中将 isActive 设置为 true 显示了一个绿色的 div 块,如果设置为 false 则不显示:

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

尝试一下 »

以上实例 div class 渲染结果为:

<div class="active"></div>

我们也可以在对象中传入更多属性用来动态切换多个 class 。

此外,:class 指令也可以与普通的 class 属性共存。

实例 2

text-danger 类背景颜色覆盖了 active 类的背景色:

<div class="static" :class="{ 'active' : isActive, 'text-danger' : hasError }"> </div>

尝试一下 »

以上实例 div class 渲染结果为:

<div class="static text-danger"></div>

当 isActive 或者 hasError 变化时,class 属性值也将相应地更新。例如,如果 active 的值为 true,class 列表将变为 "static active text-danger"。

我们也可以直接绑定数据里的一个对象:

实例 3

text-danger 类背景颜色覆盖了 active 类的背景色:

<div id="app">    <div class="static" :class="classObject"></div> </div>

尝试一下 »

实例 3 与 实例 2 的渲染结果是一样的。

此外,我们也可以在这里绑定一个返回对象的计算属性。这是一个常用且强大的模式:

实例 4

data() {  return {    isActive: true,    error: null  } }, computed: {  classObject() {    return {      active: this.isActive && !this.error,      'text-danger': this.error && this.error.type === 'fatal'    }  } }

尝试一下 »

数组语法

我们可以把一个数组传给 v-bind:class ,实例如下:

实例 5

<div class="static" :class="[activeClass, errorClass]"></div>

尝试一下 »

以上实例 div class 渲染结果为:

<div class="static active text-danger"></div>

我们还可以使用三元表达式来切换列表中的 class :

实例 6

errorClass 是始终存在的,isActive 为 true 时添加 activeClass 类:

<div id="app">    <div class="static" :class="[isActive ? activeClass : '', errorClass]"></div> </div>

尝试一下 »

以上实例 div class 渲染结果为:

<div class="static text-danger"></div>

Vue.js style(内联样式)

我们可以在 v-bind:style 直接设置样式,可以简写为 :style

实例 7

<div id="app">    <div :style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程</div> </div>

尝试一下 »

以上实例 div style 渲染结果为:

<div style="color: red; font-size: 30px;">菜鸟教程</div>

也可以直接绑定到一个样式对象,让模板更清晰:

实例 8

<div id="app">  <div :style="styleObject">菜鸟教程</div> </div>

尝试一下 »

v-bind:style 可以使用数组将多个样式对象应用到一个元素上:

实例 9

<div id="app">  <div :style="[baseStyles, overridingStyles]">菜鸟教程</div> </div>

尝试一下 »

注意:当 v-bind:style 使用需要特定前缀的 CSS 属性时,如 transform ,Vue.js 会自动侦测并添加相应的前缀。

多重值

可以为 style 绑定中的 property 提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

这样写只会渲染数组中最后一个被浏览器支持的值。在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex。


组件上使用 class 属性

当你在带有单个根元素的自定义组件上使用 class 属性时,这些 class 将被添加到该元素中。此元素上的现有 class 将不会被覆盖。

实例 10

<div id="app">    <runoob class="classC classD"></runoob> </div> <script> // 创建一个Vue 应用 const app = Vue.createApp({}) // 定义一个名为 runoob的新全局组件 app.component('runoob', {    template: '<h1 class="classA classB">I like runoob!</h1>' }) app.mount('#app') </script>

尝试一下 »

以上实例 div class 渲染结果为:

<h1 class="classA classB classC classD">I like runoob!</h1>

对于带数据绑定 class 也同样适用:

<my-component :class="{ active: isActive }"></my-component>

当 isActive 为 true 时,HTML 将被渲染成为:

<p class="active">Hi</p>

如果你的组件有多个根元素,你需要定义哪些部分将接收这个类。可以使用 $attrs 组件属性执行此操作:

实例 11

<div id="app">    <runoob class="classA"></runoob> </div> <script> const app = Vue.createApp({}) app.component('runoob', {  template: `    <p :class="$attrs.class">I like runoob!</p>    <span>这是一个子组件</span>  ` }) app.mount('#app') </script>

尝试一下 »

注意:template 中 ` 是反引号,不是单引号 '

以上实例 div class 渲染结果为:

<div id="app" data-v-app=""><p class="classA">I like runoob!</p><span>这是一个子组件</span></div>


来自  https://www.runoob.com/vue3/vue3-class-bind.html



13)

Vue3 事件处理

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

v-on 指令可以缩写为 @ 符号。

语法格式:

v-on:click="methodName"

@click="methodName"

v-on

<div id="app">  <button @click="counter += 1">增加 1</button>  <p>这个按钮被点击了 {{ counter }} 次。</p> </div> <script> const app = {  data() {    return {      counter: 0    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

通常情况下,我们需要使用一个方法来调用 JavaScript 方法。

v-on 可以接收一个定义的方法来调用。

v-on

<div id="app">  <!-- `greet` 是在下面定义的方法名 -->  <button @click="greet">点我</button> </div> <script> const app = {  data() {    return {      name: 'Runoob'    }  },  methods: {    greet(event) {      // `methods` 内部的 `this` 指向当前活动实例      alert('Hello ' + this.name + '!')      // `event` 是原生 DOM event      if (event) {        alert(event.target.tagName)      }    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

除了直接绑定到一个方法,也可以用内联 JavaScript 语句:

v-on

<div id="app">  <button @click="say('hi')">Say hi</button>  <button @click="say('what')">Say what</button> </div> <script> const app = {  data() {    },  methods: {    say(message) {      alert(message)    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

事件处理程序中可以有多个方法,这些方法由逗号运算符分隔:

v-on

<div id="app">  <!-- 这两个 one() 和 two() 将执行按钮点击事件 -->  <button @click="one($event), two($event)">  点我  </button> </div> <script> const app = {  data() {  },  methods: {    one(event) {      alert("第一个事件处理器逻辑...")    },    two(event) {      alert("第二个事件处理器逻辑...")    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

事件修饰符

Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。

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>

按键修饰符

Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">

记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:

<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">

全部的按键别名:

  • .enter

  • .tab

  • .delete (捕获 "删除" 和 "退格" 键)

  • .esc

  • .space

  • .up

  • .down

  • .left

  • .right

系统修饰键:

  • .ctrl

  • .alt

  • .shift

  • .meta

鼠标按钮修饰符:

  • .left

  • .right

  • .middle

实例

<p><!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>

.exact 修饰符

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

实例

<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>


来自   https://www.runoob.com/vue3/vue3-events.html




14)


Vue3 表单

这节我们为大家介绍 Vue 表单上的应用。

我们可以用 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 作为事件。

输入框

实例中演示了 input 和 textarea 元素中使用 v-model 实现双向数据绑定:

<div id="app">  <p>input 元素:</p>  <input v-model="message" placeholder="编辑我……">  <p>input 表单消息是: {{ message }}</p>      <p>textarea 元素:</p>  <textarea v-model="message2" placeholder="多行文本输入……"></textarea>  <p>textarea 表单消息是:</p>  <p style="white-space: pre">{{ message2 }}</p>   </div> <script> const app = {  data() {    return {      message: '',      message2: '菜鸟教程\r\nhttps://www.runoob.com'    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »
在文本区域 textarea 插值是不起作用,需要使用 v-model 来代替:
<!-- 错误 -->
<textarea>{{ text }}</textarea>

<!-- 正确 -->
<textarea v-model="text"></textarea>

复选框

复选框如果是一个为逻辑值,如果是多个则绑定到同一个数组:

复选框

以下实例中演示了复选框的双向数据绑定:

<div id="app">  <p>单个复选框:</p>  <input type="checkbox" id="checkbox" v-model="checked">  <label for="checkbox">{{ checked }}</label>      <p>多个复选框:</p>  <input type="checkbox" id="runoob" value="Runoob" v-model="checkedNames">  <label for="runoob">Runoob</label>  <input type="checkbox" id="google" value="Google" v-model="checkedNames">  <label for="google">Google</label>  <input type="checkbox" id="taobao" value="Taobao" v-model="checkedNames">  <label for="taobao">taobao</label>  <br>  <span>选择的值为: {{ checkedNames }}</span> </div> <script> const app = {  data() {    return {      checked : false,      checkedNames: []    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

实例中勾选复选框效果如下所示:


单选按钮

以下实例中演示了单选按钮的双向数据绑定:

单选按钮

<div id="app">  <input type="radio" id="runoob" value="Runoob" v-model="picked">  <label for="runoob">Runoob</label>  <br>  <input type="radio" id="google" value="Google" v-model="picked">  <label for="google">Google</label>  <br>  <span>选中值为: {{ picked }}</span> </div> <script> const app = {  data() {    return {      picked : 'Runoob'    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

选中后,效果如下图所示:

select 列表

以下实例中演示了下拉列表的双向数据绑定:

select

<div id="app">  <select v-model="selected" name="fruit">    <option value="">选择一个网站</option>    <option value="www.runoob.com">Runoob</option>    <option value="www.google.com">Google</option>  </select>  <div id="output">      选择的网站是: {{selected}}  </div> </div> <script> new Vue({  el: '#app',  data: {    selected: ''  } }) </script>

尝试一下 »

选取 Runoob,输出效果如下所示:

多选时会绑定到一个数组:

select

<div id="app">  <select v-model="selected" name="fruit" multiple>    <option value="www.runoob.com">Runoob</option>    <option value="www.google.com">Google</option>    <option value="www.taobao.com">Taobao</option>  </select>  <div id="output">      选择的网站是: {{selected}}  </div> </div> <script> const app = {  data() {    return {      selected: ''    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

选中 Runoob 和 Google:

使用 v-for 循环输出选项:

select

<div id="app" class="demo">  <select v-model="selected">    <option v-for="option in options" :value="option.value">      {{ option.text }}    </option>  </select>  <span>选择的是: {{ selected }}</span> </div> <script> const app = {  data() {    return {      selected: 'www.runoob.com',      options: [        { text: 'Runoob', value: 'www.runoob.com' },        { text: 'Google', value: 'www.google.com' },        { text: 'Taobao', value: 'www.taobao.com' }      ]    }  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

选中 Runoob:

值绑定

对于单选按钮,复选框及选择框的选项,v-model 绑定的值通常是静态字符串 (对于复选框也可以是布尔值):

<!-- 当选中时,`picked` 为字符串 "a" -->
<input type="radio" v-model="picked" value="a" />

<!-- `toggle` 为 true 或 false -->
<input type="checkbox" v-model="toggle" />

<!-- 当选中第一个选项时,`selected` 为字符串 "abc" -->
<select v-model="selected">
  <option value="abc">ABC</option>
</select>

但是有时我们可能想把值绑定到当前活动实例的一个动态属性上,这时可以用 v-bind 实现,此外,使用 v-bind 可以将输入值绑定到非字符串。

复选框 (Checkbox):

<input type="checkbox" v-model="toggle" true-value="yes" false-value="no" />
...
// 选中时
vm.toggle === 'yes'
// 取消选中 
vm.toggle === 'no'

单选框 (Radio):

<input type="radio" v-model="pick" v-bind:value="a" />
// 当选中时
vm.pick === vm.a

选择框选项 (Select):

<select v-model="selected">
  <!-- 内联对象字面量 -->
  <option :value="{ number: 123 }">123</option>
</select>
// 当被选中时
typeof vm.selected // => 'object'
vm.selected.number // => 123

修饰符

.lazy

在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步:

<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >

.number

如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值:

<input v-model.number="age" type="number">

这通常很有用,因为在 type="number" 时 HTML 中输入的值也总是会返回字符串类型。

.trim

如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入:

<input v-model.trim="msg">


来自  https://www.runoob.com/vue3/vue3-forms.html


15)

Vue3 自定义指令

除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令。

下面我们注册一个全局指令 v-focus, 该指令的功能是在页面加载时,元素获得焦点:

实例

<div id="app">    <p>页面载入时,input 元素自动获取焦点:</p>    <input v-focus> </div> <script> const app = Vue.createApp({}) // 注册一个全局自定义指令 `v-focus` app.directive('focus', {  // 当被绑定的元素挂载到 DOM 中时……  mounted(el) {    // 聚焦元素    el.focus()  } }) app.mount('#app') </script>

尝试一下 »

我们也可以在实例使用 directives 选项来注册局部指令,这样指令只能在这个实例中使用:

实例

<div id="app">    <p>页面载入时,input 元素自动获取焦点:</p>    <input v-focus> </div> <script> const app = {   data() {      return {      }   },   directives: {      focus: {         // 指令的定义         mounted(el) {            el.focus()         }      }   } } Vue.createApp(app).mount('#app')

尝试一下 »

钩子

钩子函数

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

  • 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:一个对象,在注册指令时作为参数传递。例如,在以下指令中:

app.directive('focus', {
  mounted(el) {
    el.focus()
  }
})

dir 将会是以下对象:

{
  mounted(el) {
    el.focus()
  }
}

vnode

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

prevNode

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

以下实例演示了这些参数的使用:

实例

<div id="app">   <div v-runoob="{ name: '菜鸟教程', url: 'www.runoob.com' }"></div> </div> <script> const app = Vue.createApp({}) app.directive('runoob', (el, binding, vnode) => { console.log(binding.value.name) // => "菜鸟教程" console.log(binding.value.url) // => "www.runoob.com" var s = JSON.stringify el.innerHTML = s(binding.value) }) app.mount('#app') </script>

尝试一下 »

有时候我们不需要其他钩子函数,我们可以简写函数,如下格式:

Vue.directive('runoob', function (el, binding) {
  // 设置指令的背景颜色
  el.style.backgroundColor = binding.value.color
})

指令函数可接受所有合法的 JavaScript 表达式,以下实例传入了 JavaScript 对象:

实例

<div id="app">    <div v-runoob="{ color: 'green', text: '菜鸟教程!' }"></div> </div> <script> Vue.directive('runoob', function (el, binding) {    // 简写方式设置文本及背景颜色    el.innerHTML = binding.value.text    el.style.backgroundColor = binding.value.color }) new Vue({  el: '#app' }) </script>

尝试一下 »


来自   https://www.runoob.com/vue3/vue3-custom-directive.html


16)

Vue3 路由

本章节我们将为大家介绍 Vue 路由。

Vue 路由允许我们通过不同的 URL 访问不同的内容。

通过 Vue 可以实现多视图的单页 Web 应用(single page web application,SPA)。

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

中文文档地址:vue-router 文档


安装

1、直接下载 / CDN

https://unpkg.com/vue-router@4

NPM

推荐使用淘宝镜像:

npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install vue-router@4

简单实例

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

<router-link> 是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容。 to 属性为目标地址, 即要显示的内容。

以下实例中我们将 vue-router 加进来,然后配置组件和路由映射,再告诉 vue-router 在哪里渲染它们。代码如下所示:

HTML 代码

<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-link

请注意,我们没有使用常规的 a 标签,而是使用一个自定义组件 router-link 来创建链接。这使得 Vue Router 可以在不重新加载页面的情况下更改 URL,处理 URL 的生成以及编码。我们将在后面看到如何从这些功能中获益。

router-view

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

JavaScript 代码

// 1. 定义路由组件. // 也可以从其他文件导入 const Home = { template: '<div>Home</div>' } const About = { template: '<div>About</div>' } // 2. 定义一些路由 // 每个路由都需要映射到一个组件。 // 我们后面再讨论嵌套路由。 const routes = [  { path: '/', component: Home },  { path: '/about', component: About }, ] // 3. 创建路由实例并传递 `routes` 配置 // 你可以在这里输入更多的配置,但我们在这里 // 暂时保持简单 const router = VueRouter.createRouter({  // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。  history: VueRouter.createWebHashHistory(),  routes, // `routes: routes` 的缩写 }) // 5. 创建并挂载根实例 const app = Vue.createApp({}) //确保 _use_ 路由实例使 //整个应用支持路由。 app.use(router) app.mount('#app') // 现在,应用已经启动了!

尝试一下 »

点击过的导航链接都会加上样式 class ="router-link-exact-active router-link-active"


<router-link> 相关属性

接下来我们可以了解下更多关于 <router-link> 的属性。

to

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

<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染结果 -->
<a href="home">Home</a>

<!-- 使用 v-bind 的 JS 表达式 -->
<router-link v-bind:to="'home'">Home</router-link>

<!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
<router-link :to="'home'">Home</router-link>

<!-- 同上 -->
<router-link :to="{ path: 'home' }">Home</router-link>

<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>

replace

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

<router-link :to="{ path: '/abc'}" replace></router-link>

append

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

<router-link :to="{ path: 'relative/path'}" append></router-link>

tag

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

<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染结果 -->
<li>foo</li>

active-class

设置 链接激活时使用的 CSS 类名。可以通过以下代码来替代。

<style>
   ._active{
      background-color : red;
   }
</style>
<p>
   <router-link v-bind:to = "{ path: '/route1'}" active-class = "_active">Router Link 1</router-link>
   <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
</p>

注意这里 class 使用 active-class="_active"

exact-active-class

配置当链接被精确匹配的时候应该激活的 class。可以通过以下代码来替代。

<p>
   <router-link v-bind:to = "{ path: '/route1'}" exact-active-class = "_active">Router Link 1</router-link>
   <router-link v-bind:to = "{ path: '/route2'}" tag = "span">Router Link 2</router-link>
</p>

event

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

<router-link v-bind:to = "{ path: '/route1'}" event = "mouseover">Router Link 1</router-link>

以上代码设置了 event 为 mouseover ,及在鼠标移动到 Router Link 1 上时导航的 HTML 内容会发生改变。


来自   https://www.runoob.com/vue3/vue3-routing.html


17)

Vue3 混入

混入 (mixins)定义了一部分可复用的方法或者计算属性。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。

来看一个简单的实例:

实例

// 定义混入对象 const myMixin = {  created() {    this.hello()  },  methods: {    hello() {      console.log('欢迎来到混入实例-RUNOOB!')    }  } } // 定义一个应用,使用混入 const app = Vue.createApp({  mixins: [myMixin] }) app.mount('#app') // => "欢迎来到混入实例-RUNOOB!"

尝试一下 »

选项合并

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

比如,数据对象在内部会进行浅合并 (一层属性深度),在和组件的数据发生冲突时以组件数据优先。

以下实例中,Vue 实例与混入对象包含了相同的方法。从输出结果可以看出两个选项合并了。

实例

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id = "app"></div> <script type = "text/javascript"> const myMixin = {  data() {    return {      message: 'hello',      foo: 'runoob'    }  } } const app = Vue.createApp({  mixins: [myMixin],  data() {    return {      message: 'goodbye',      bar: 'def'    }  },  created() {    document.write(JSON.stringify(this.$data))  } })

输出结果为:

{"message":"goodbye","foo":"runoob","bar":"def"}

尝试一下 »

同名钩子函数将合并为一个数组,因此都将被调用。另外,mixin 对象的钩子将在组件自身钩子之前调用。

const myMixin = {
  created() {
    console.log('mixin 对象的钩子被调用')
  }
}

const app = Vue.createApp({
  mixins: [myMixin],
  created() {
    console.log('组件钩子被调用')
  }
})

// => "mixin 对象的钩子被调用"
// => "组件钩子被调用"

值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。

实例

const myMixin = {  methods: {    foo() {      console.log('foo')    },    conflicting() {      console.log('from mixin')    }  } } const app = Vue.createApp({  mixins: [myMixin],  methods: {    bar() {      console.log('bar')    },    conflicting() {      console.log('from self')    }  } }) const vm = app.mount('#app') vm.foo() // => "foo" vm.bar() // => "bar" vm.conflicting() // => "from self"

以上实例,我们调用了以下三个方法:

vm.foo();
vm.bar();
vm.conflicting();

从输出结果 methods 选项中如果碰到相同的函数名则 Vue 实例有更高的优先级会执行输出。


全局混入

也可以全局注册混入对象。注意使用! 一旦使用全局混入对象,将会影响到 所有 之后创建的 Vue 实例。使用恰当时,可以为自定义对象注入处理逻辑。

实例

const app = Vue.createApp({  myOption: 'hello!' }) // 为自定义的选项 'myOption' 注入一个处理器。 app.mixin({  created() {    const myOption = this.$options.myOption    if (myOption) {      document.write(myOption)    }  } }) app.mount('#app') // => "hello!"

尝试一下 »

谨慎使用全局混入对象,因为会影响到每个单独创建的 Vue 实例 (包括第三方模板)。


来自   https://www.runoob.com/vue3/vue3-mixins.html


18)

Vue3 Ajax(axios)

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

Axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中。

Github开源地址: https://github.com/axios/axios

安装方法

使用 cdn:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>

使用 npm:

$ npm install axios

使用 bower:

$ bower install axios

使用 yarn:

$ yarn add axios

使用方法:

Vue.axios.get(api).then((response) => {
  console.log(response.data)
})

this.axios.get(api).then((response) => {
  console.log(response.data)
})

this.$http.get(api).then((response) => {
  console.log(response.data)
})

浏览器支持情况


GET 方法

我们可以简单的读取 JSON 数据:

GET 实例

const app = {  data() {    return {      info: 'Ajax 测试!!'    }  },  mounted () {    axios      .get('https://www.runoob.com/try/ajax/json_demo.json')      .then(response => (this.info = response))      .catch(function (error) { // 请求失败处理        console.log(error);    });  } } Vue.createApp(app).mount('#app')

尝试一下 »

使用 response.data 读取 JSON 数据:

GET 实例

<div id="app">  <h1>网站列表</h1>  <div    v-for="site in info"  >    {{ site.name }}  </div> </div> <script type = "text/javascript"> const app = {  data() {    return {      info: 'Ajax 测试!!'    }  },  mounted () {    axios      .get('https://www.runoob.com/try/ajax/json_demo.json')      .then(response => (this.info = response))      .catch(function (error) { // 请求失败处理        console.log(error);    });  } } Vue.createApp(app).mount('#app') </script>

尝试一下 »

GET 方法传递参数格式如下:

传递参数说明

// 直接在 URL 上添加参数 ID=12345 axios.get('/user?ID=12345')  .then(function (response) {    console.log(response);  })  .catch(function (error) {    console.log(error);  }); // 也可以通过 params 设置参数: axios.get('/user', {    params: {      ID: 12345    }  })  .then(function (response) {    console.log(response);  })  .catch(function (error) {    console.log(error);  });

POST 方法

POST 实例

new Vue({  el: '#app',  data () {    return {      info: null    }  },  mounted () {    axios      .post('https://www.runoob.com/try/ajax/demo_axios_post.php')      .then(response => (this.info = 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);  });

执行多个并发请求

实例

function getUserAccount() {  return axios.get('/user/12345'); } function getUserPermissions() {  return axios.get('/user/12345/permissions'); } axios.all([getUserAccount(), getUserPermissions()])  .then(axios.spread(function (acct, perms) {    // 两个请求现在都执行完成  }));

axios API

可以通过向 axios 传递相关配置来创建请求。

实例

axios(config) // 发送 POST 请求 axios({  method: 'post',  url: '/user/12345',  data: {    firstName: 'Fred',    lastName: 'Flintstone'  } }); //  GET 请求远程图片 axios({  method:'get',  url:'http://bit.ly/2mTM3nY',  responseType:'stream' })  .then(function(response) {  response.data.pipe(fs.createWriteStream('ada_lovelace.jpg')) }); axios(url[, config]) // 发送 GET 请求(默认的方法) axios('/user/12345');

请求方法的别名

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

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]])

注意:在使用别名方法时, url、method、data 这些属性都不必在配置中指定。

并发

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

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

创建实例

可以使用自定义配置新建一个 axios 实例:

axios.create([config])
const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

实例方法

以下是可用的实例方法。指定的配置将与实例的配置合并:

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]])

请求配置项

下面是创建请求时可用的配置选项,注意只有 url 是必需的。如果没有指定 method,请求将默认使用 get 方法。

{
  // `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) {
  })
}

响应结构

axios请求的响应包含以下信息:

{
  // `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);
  });

在使用 catch 时,或传递 rejection callback 作为 then 的第二个参数时,响应可以通过 error 对象可被使用。

配置的默认值

你可以指定将被用在各个请求的配置默认值。

全局的 axios 默认值:

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

自定义实例默认值:

// 创建实例时设置配置的默认值
var instance = axios.create({
  baseURL: 'https://api.example.com'
});

// 在实例已创建后修改默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

配置的优先顺序

配置会以一个优先顺序进行合并。这个顺序是:在 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);

可以为自定义 axios 实例添加拦截器。

var instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

错误处理:

axios.get('/user/12345')
  .catch(function (error) {
    if (error.response) {
      // 请求已发出,但服务器响应的状态码不在 2xx 范围内
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

可以使用 validateStatus 配置选项定义一个自定义 HTTP 状态码的错误范围。

axios.get('/user/12345', {
  validateStatus: function (status) {
    return status < 500; // 状态码在大于或等于500时才会 reject
  }
})

取消

使用 cancel token 取消请求。

Axios 的 cancel token API 基于cancelable promises proposal

可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:

var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function(thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');

还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

var CancelToken = axios.CancelToken;
var cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});

// 取消请求
cancel();

注意:可以使用同一个 cancel token 取消多个请求。

请求时使用 application/x-www-form-urlencoded

axios 会默认序列化 JavaScript 对象为 JSON。 如果想使用 application/x-www-form-urlencoded 格式,你可以使用下面的配置。

浏览器

在浏览器环境,你可以使用 URLSearchParams API:

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);

URLSearchParams 不是所有的浏览器均支持。

除此之外,你可以使用 qs 库来编码数据:

const qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));

// Or in another way (ES6),

import qs from 'qs';
const data = { 'bar': 123 };
const options = {
  method: 'POST',
  headers: { 'content-type': 'application/x-www-form-urlencoded' },
  data: qs.stringify(data),
  url,
};
axios(options);

Node.js 环境

在 node.js里, 可以使用 querystring 模块:

const querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));

当然,同浏览器一样,你还可以使用 qs 库。

Promises

axios 依赖原生的 ES6 Promise 实现而被支持

如果你的环境不支持 ES6 Promise,你可以使用 polyfill

TypeScript支持

axios 包含 TypeScript 的定义。

import axios from "axios";
axios.get("/user?ID=12345");

来自  https://www.runoob.com/vue3/vue3-ajax-axios.html




https://www.runoob.com/vue3/vue3-components.html



普通分类: