Vue2_Vue.js教程

news2025/4/8 6:12:21

目录

一、Vue.js安装

1、独立版本

2、CDN 方法

3、npm 方法

二、Vue Al编程助手

三、Vue.js目录结构

目录解析

四、Vue.js 起步

1.如何定义数据对象和方法并渲染进页面

五、Vue.js 模板语法

插值

文本_{{}}

Html_v-html 指令

属性_v-bind (数据传输工具)指令

表达式

指令

指令参数

1. b/m数据绑定指令

2. on事件绑定指令

3. if条件渲染指令

4. for列表渲染指令

5. text文本 & HTML 渲染指令

6. 修饰符

7. 其他指令

8. Vue 3 新增指令

8.1过滤器Vue 过滤器(Vue 2 专有,Vue 3 已移除)

六、Vue.js 条件语句

条件判断

v-if

v-else

v-else-if

v-show

七、Vue.js 循环语句

v-for迭代数组

v-for 迭代对象

v-for 迭代整数

八、Vue.js 计算属性

computed

computed vs methods

computed setter

九、Vue.js 监听属性

  watch

十、Vue.js 样式绑定

Vue.js class

class 属性绑定

对象语法

数组语法

三元表达式

Vue.js style(内联样式)

直接设置

对象语法

数组语法

十一、Vue.js 事件处理器

v-on

直接绑定方法()

内联 JavaScript 语句

事件修饰符.

按键修饰符

十二、Vue.js 表单(双向数据绑定)

输入框

复选框

单选按钮

select下拉列表

修饰符

.lazy(延迟更新)

.number(自动转为数字类型)

.trim(输入时去除首尾空格)

十三、Vue组件

全局组件

注册全局组件

局部组件

注册局部组件

Prop

🌟 生活类比

🌟 作用

动态 Prop

Prop 验证

十四、vue组件-自定义事件

data 必须是一个函数

自定义组件的 v-model

十五、Vue.js 自定义指令

钩子

钩子函数?

① 指令定义函数的钩子函数

钩子函数参数

② 钩子函数的参数

十六、Vue.js 路由

安装

1、直接下载 / CDN

2、NPM

简单实例

相关属性

to

replace

append

tag

active-class

exact-active-class

event

十七、Vue.js 过渡 & 动画

过渡

语法格式

十八、Vue.js 混入

十九、Vue.js Ajax(axios)

安装方法

浏览器支持情况

GET 方法

POST 方法

执行多个并发请求

axios API

请求方法的别名

并发

创建实例

请求配置项

响应结构

配置的默认值

配置的优先顺序

拦截器

取消

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

Node.js 环境

Promises

TypeScript支持

二十、Vue.js Ajax(vue-resource)

Get 请求

post 请求

语法 & API

二十一、Vue.js 响应接口

Vue.set

Vue.delete


Vue.js

一套构建用户界面的渐进式框架。

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

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

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

Vue 2.0 在 2023 年 12 月 31 日停止更新。

这里就相当于html


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

一、Vue.js安装

1、独立版本

Vue.js 的官网v2.vuejs.org/js/vue.min.js直接下载 vue.min.js保存本地并用 <script> 标签引入。

2、CDN 方法

 CDN,国内还没发现哪一家比较好,目前还是建议下载到本地。

  • 字节跳动 CDN(国内) :https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js

3、npm 方法

npm 安装速度慢,(要换源自己找教程)  这里临时指定阿里云及其命令 cnpm

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

cnpm install vue

vue2构建项目(现在还不用,本章是直接在1.html单页引入vue.js右键浏览器测试)

vue init webpack my-project


 Vite 默认支持 Vue 3,可以使用 Vite 来构建 Vue 2 项目。需要安装 @vitejs/plugin-vue2 插件支持 

//npm create vite@latest my-vue2-project --template vue

vue 3构建项目(只是顺便提一嘴这俩区别)

vue create my-project
//npm create vite@latest my-vue3-project --template vue



总结

vue init 使用的模板库已经被废弃,因此你无法通过它创建新项目。

推荐使用 Vue CLI 3.x 或更高版本,或者直接使用 Vite 来创建 Vue 项目

如果你仍然使用 Vue CLI 2.x,你可以继续使用 vue init webpack 命令,但这不是推荐的做法。

强烈建议升级到 Vue CLI 3.x 或 Vite,以确保你的项目能够使用最新的功能和更好的性能。

二、Vue Al编程助手

VSCode 的插件 Fitten Code

三、Vue.js目录结构

 npm 安装项目(脚手架)

目录解析

目录/文件说明
build    项目构建(webpack)相关代码
config    配置目录,端口号等。初学可以使用默认的。
node_modules    我们安装的第三方都在这里
src

     源码以及开发的静态资源等都在里面

  • assets: 资源文件(字体,图标,图片)

      components: 自定义公共组件,可以不用。


  • App.vue: App.vue 里面可能引入多个子组件
  • App.vue 中的 <div id="app">这个 app 是 Vue 组件的根节点,它会覆盖掉 index.html  app的div原始内容。

          mian.js将app.vue组件一个个渲染到index,#app 是 Vue(应用的“容器”) 管理SPA(单页面应用)容器


  • main.js: 做挂载   

        import { createApp } from 'vue' //导入vue应用创建方法
        import App from './App.vue',//导入组件 App.vue

        createApp(App).mount('#app')  // 创建 Vue 应用(并使用 App.vue 作为根组件),将app.vue组件挂载index.html 

  • mount('#app') 的作用就是用 App.vue 的内容替换挂载接管index.html<div id="app"> 的内容。

  • 所以,最终页面上看到的 #app 其实是 App.vue 里的内容,而不是 index.html 里的 ddd

       最终流程mian.js-----将aap.vue组件--------挂载到index

static       静态资源目录,如图片、字体等。
test       初始测试目录,可删除
.xxxx文件        这些是一些配置文件,包括语法配置,git配置等。
index.html

  • index.html做渲染做vue挂载的容器

  • <div id="app">ddd //App.vue会接管</div> 只是初始 HTML 结构,当 Vue 代码未执行时,它里面的内容(ddd)会显示在页面上。

  • 一旦 Vue 应用启动,接管这个 #app,并用 App.vue 里的内容替换它(ddd不显示)

它们之间关系:index.html 是“空白场地”

                          main.js “导演”:指导每个演员(组件)进入舞台

                         App.vue “后台演员后场室”:所有演员(组件)都先到这里集合,然后按剧本安排演出。

路由:

        router/index.js “剧本”:安排演出场地,规定演员--门牌号(哪个演员在哪里演出)

        <router-view/> “舞台切换器”:app.vue对应展示所有门牌号----演员

        <router-link> “演员门铃” :app.vue点击门铃跳转场地看不同的演员。

package.json项目配置文件(包记录文件)。package-lock.json // 版本锁定文件
README.md项目的说明文档,markdown 格式

四、Vue.js 起步

每个 Vue 应用都需要通过实例化 Vue 来实现。

通俗一点:实例化就是创建一个 Vue 应用, 挂载,生效。

简单来说,实例化 Vue 就是启动一个 Vue 应用,让它接管页面上的某个部分,这样 Vue 才能帮你管理数据、响应用户操作。

语法格式如下:

这是vue2

var vm = new Vue({
  // 选项
})

 Vue 创建,它向 Vue 响应式系统中加入了它data 对象所有属性。当date属性值发生改变,html 视图将也跟着改变。

1.如何定义数据对象和方法并渲染进页面

data 用于定义属性,实例中有三个属性分别为:site、url、alexa。

methods 用于定义的函数,可以通过 return 来返回函数值。

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

步骤,引入vue------定义数据对象方法并且挂载点------双花括号插值对引入到页面标签

1.html

<html>
<head>
	<title>Vue数据绑定</title>
	<script src="https://cdn.staticfile.net/vue/2.4.2/vue.min.js"></script> //引入vue
</head>
<body>
      //第一:如何渲染进我们的页面?
     //3.用双花括号插值对渲染进我们的页面
    <div id="vue_det">
        <h1>{{site}}</h1>
        <h1>url : {{url}}</h1>
        <h1>Alexa : {{alexa}}</h1>
		<h1>{{ details() }}</h1>
    </div>

    //第二:如何定义我的数据和绑定?
    <script>
        var vm = new Vue({// 创建Vue实例
            el: '#vue_det',//将vue实例挂载到页面

           //定义我们的数据
            data: { 
                site: "Vue", 
                url: "aa.vue.com", 
                alexa: `第 ${1} 名`
            },
			//定义我们方法
            methods: {
                details() {
                    return `网站 ${this.site} 的排名:${this.alexa}`;
                }
            }
        });
</script>
</body>
</html>

渲染结果

五、Vue.js 模板语法

官网:

Vue.js 使用基于 HTML 模板语法,允许我们声明式地将 DOM 绑定至底层 Vue 实例的数据。

Vue.js 核心是允许我们采用简洁的模板语法来声明式的将数据渲染进 DOM 的系统

核心思想:“数据驱动视图”(页面的显示由数据决定,数据变-->页面自动更新)

我说:

  • 模板语法 {{ }} 就是“插值”把数据插入到 HTML 里,让数据和页面 实时绑定在一起。

插值

文本_{{}}

1.html

<head>
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js"></script>
</head>

<div id="app">
  <!--{{}}插值-->
  <p>{{ message }}</p>//文本插值输出文本:Hello Vue.js!
</div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'//数据值
  }
})
</script>

Html_v-html 指令

使用 v-html 指令用于输出 html 代码(有V开头的都是指令)

直白一点


//写死到html
<h1>标题1</h1>


//插值到htnl
<div v-html="message"></div>
1.html
//v-html 指令

<body>
<div id="app">
  <!--插值-->
    <div v-html="message"></div>//v-html 指令输出hmtl:标题1
</div>
	
<script>
new Vue({
  el: '#app',
  data: {
    message: '<h1>标题1</h1>'//数据值
  }
})
</script>

属性_v-bind (数据传输工具)指令

作用: 绑定 HTML 属性,如 idclasssrc 等。
简写方式: v-bind:属性名:属性名

v-model指令 主要用于表单双向绑定,它没有简写方式

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

v-bind:class 动态控制元素的 CSS 类, v-model 控制复选框状态。

v-bind:class,v-model  指令实现动态绑定数据与页面样式的效果

直白一点


//class1样式修饰
.class1{
  background: red;
  color: #fff;
}


//写死
<div class="class1">字体颜色</div>


//不写死(插值绑定到html页面)
<div :class="{'class1': use}">字体颜色:引用/不引用</div>


new Vue({
    el: '#app',
  data:{
      use: false // use初始化为 false //根据 use 的值动态决定是否给 div 添加 class1 类。
  }
});
1.html
//v-bind 指令

<head>
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js"></script>
</head>

//什么时候引用样式
//先把样式放好
<style> 
.class1{
  background: red;
  color: #fff;
}
</style>


<body>
<div id="app">
	<!--//复选框 v-model双向绑定-->
	<!--选中复选框,use 变为 true-->
  <label  for="r1">修改颜色表单控件</label ><input type="checkbox" v-model="use" id="r1">
	<hr>
	<!--use:初始化为 false-->
  <div v-bind:class="{'class1': use}">v-bind:class</div>
</div>
    
<script>
new Vue({//创建vue应用
    el: '#app',//挂载点
  data:{
      use: false // use初始化为 false,选框未选中,use 的值默认 false  //插值
  }
});
</script>
</body>

表达式

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

1.html
//JavaScript 表达式

<div id="app">
	{{5+5}}<br><!-- 输出 5 + 5 的结果 -->
	{{ ok ? 'YES' : 'NO' }}<br><!-- 使用三目表达式,根据条件输出 'YES' 或 'NO' -->
	{{ message.split('').reverse().join('') }}<!-- 反转 message 字符串 -->
	 <!-- 使用 v-for 来动态绑定 id 属性 -->
    <div v-for="id in ids" v-bind:id="'list-' + id">vue教程 {{ id }}</div>
</div>
	
<script>
new Vue({
  el: '#app',
  data: {
	ok: true,
    message: 'abc',
	 ids: [1, 2, 3, 4, 5] // 用数组存储教程编号
  }
})
</script>

指令

指令是带有 v- 开头的

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

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

指令参数

参数在指令后冒号:指明

<div id="app">
    //在这里 href 是参数,告知 v-bind 指令将该元素的 href 属性与表达式 url 的值绑定
    <pre><a v-bind:href="url">百度一下</a></pre>
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    url: 'http://www.baidu.com'
  }
})
</script>

直白一点

<div v-if="show">显示内容</div>
<div v-else>隐藏内容</div>
1.html

<div id="app">
    <p v-if="seen">现在你看到我了</p>
    <template v-if="ok">
      <h1>vue教程</h1>
      <p>这里是根据情况选择是否展示</p>
      <p>哈哈哈,打字辛苦啊!!!</p>
    </template>
</div>
    
<script>
new Vue({
  el: '#app',
	//我们的数据
  data: {
    seen: true, //改为0  都不显示
    ok: true //改为0   都不显示
  }
})
</script>

简写总结:Vue 主要提供 v-bind:v-on@ 这两个简写方式,其他指令都没有简写

指令简写
v-bind: 绑定 HTML 属性,如 idclasssrc 等。:
v-on:  监听 DOM 事件,如 clickinput@
1. b/m数据绑定指令

用户输入

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

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

指令作用简写
v-bind绑定 HTML 属性:
v-model双向数据绑定(表单)
<img :src="imgUrl">
<input v-model="username">



//双向数据绑定

<div id="app">
    <p>{{ message }}</p>
    <input v-model="message">
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: '请输入!'
  }
})
</script>

2. on事件绑定指令

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

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

指令作用简写
v-on监听事件@
<button @click="handleClick">点我</button>



//字符串反转
<div id="app">
    <p>{{ message }}</p>
    <button v-on:click="reverseMessage">反转字符串</button>
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: 'abcABC'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
</script>

3. if条件渲染指令
指令作用
v-if条件渲染(元素会被删除/添加)
v-else-if多条件分支
v-else默认情况
v-show控制 display(仅隐藏不删除)
<p v-if="score > 90">优秀</p>
<p v-else-if="score > 60">及格</p>
<p v-else>默认不及格</p>
<p v-show="isVisible">这个只是隐藏</p>
4. for列表渲染指令
指令作用
v-for遍历数组、对象、数字
<ul>
  <li v-for="(item, index) in list" :key="index">{{ item }}</li>
</ul>
5. text文本 & HTML 渲染指令
指令作用
v-text绑定文本(不会解析 HTML)
v-html绑定 HTML(解析 HTML,有安全风险)
<p v-text="message"></p>
<p v-html="htmlContent"></p>
6. 修饰符

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

修饰符作用
.prevent阻止默认事件
.stop阻止事件冒泡
.once事件只触发一次
.capture事件在捕获阶段触发
.self仅在自身元素触发事件
.passive事件不会阻止默认行为
<form @submit.prevent="submitForm">提交</form>
<button @click.stop="doSomething">阻止冒泡</button>
7. 其他指令
指令作用
v-cloak解决 {{}} 闪烁问题
v-once只渲染一次,不再更新
v-memo (Vue 3)仅在依赖变更时更新
v-pre跳过该节点的编译
<p v-cloak>{{ message }}</p>
<p v-once>{{ staticContent }}</p>
8. Vue 3 新增指令
指令作用
v-memo仅在依赖变化时重新渲染
v-is绑定动态组件
v-bind (多个)v-bind="{ class: 'red', id: 'app' }"
<component :is="currentComponent"></component>
8.1过滤器Vue 过滤器(Vue 2 专有,Vue 3 已移除)

过滤器 vs 计算属性 vs 方法

方式Vue 2Vue 3适用场景
过滤器✅ 支持❌ 移除仅适用于文本格式化
计算属性✅ 支持✅ 支持依赖响应式数据
方法✅ 支持✅ 支持适用于任何场景

Vue.js 允许你自定义过滤器,被用作一些常见的文本格式化。由"管道符"指示, 格式如下:

过滤器可以 串联,也可以 传参

<!-- 在插值表达式中使用 -->
{{ message | capitalize }}

<!-- 在 v-bind 指令中使用 -->
<div v-bind:id="rawId | formatId"></div>



过滤器可以串联:也就是多个过滤器可以 依次处理数据:

{{ message | filterA | filterB }}
filters: {
  filterA: function (value) {
    return value.charAt(0).toUpperCase() + value.slice(1);
  },
  filterB: function (value) {
    return value.split('').filterB().join('');
  }
}
:

{{ message | filterA('arg1', arg2) }}
这里,message 是第一个参数,字符串 'arg1' 将传给过滤器作为第二个参数, arg2 表达式的值将被求值然后传给过滤器作为第三个参数。

过滤器函数接受表达式的值作为第一个参数。

以下实例对输入的字符串第一个字母转为大写:

<div id="app">
  {{ message | capitalize }}
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: 'aaaaaaaaabbbbbbbbcccccccc'
  },
  filters: {
    capitalize: function (value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
})
</script>

Vue 3 移除了过滤器,推荐使用 计算属性方法 替代:

html

{ capitalize(message) }}
js

computed: {
  capitalize() {
    return this.message.charAt(0).toUpperCase() + this.message.slice(1);
  }
}

六、Vue.js 条件语句

条件判断

v-if

条件判断条件渲染指令使用 v-if 指令:

v-else

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

v-else-if

v-else-if 在 2.1.0 新增,顾名思义,用作 v-if 的 else-if 块。可以链式的多次使用

 v-if / v-else-if两个如果之后是v-else 、v-else-if 

v-show

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

七、Vue.js 循环语句

循环使用 v-for 指令。

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

v-for迭代数组

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

v-for 迭代对象

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

v-for你也可以提供第二个的参数为键名:前面演示有了无非就是以键值对的形式打印

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


//name : 邓
//age : 18

v-for第三个参数为索引:无非就是在前面打印个下标

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


0. name : 东
1. age : 18
2. log : 学的不仅是技术,更是梦想!



定义都是这样的

  data: {
    object: {
      name: '东',
      age: '18',
      log: '学的不仅是技术,更是梦想!'
    }
v-for 迭代整数

v-for 也可以循环整数   就是普通for循环

<div id="app">
  <ul>
    <li v-for="n in 10"> // Vue 允许 v-for 直接使用数字作为迭代范围
   //<li v-for="n in num">
     {{ n }}
    </li>
  </ul>
</div>


new Vue({
  el: '#app'  //这连数据都没有

 //可以定义一个
data: {
    num: 10  // 这里也可以改成一个数组 [1, 2, ..., 10] 更直观
  }

})

八、Vue.js 计算属性

计算属性关键词: computed。

计算属性:本质就是定义一个计算函数,它比普通方法(methods)更智能,会自动缓存计算结果,只有依赖的数据变化时才会重新执行

计算属性就是Vue 自动计算,基于已有的数据计算出新的数据。

现在 Vue 也支持简写,可以省略 function 关键字


定义函数:function{

}


//简写ES6
定义函数(){

}

反转字符串:模板复杂,也不容易看懂理解

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

computed

计算属性的实例

var vm = new Vue({ 
  el: '#app',       
  data: {           
    message: 'abc!'  
  },
  computed: {       // 使用计算属性(computed)
    // 计算属性的 getter(获取器)
    reversedMessage: function () { // 定义计算属性 reversedMessage(相当于一个函数)
      return this.message.split('').reverse().join(''); 
      // `this` 指向 Vue 实例 vm
      // ① this.message 取到 data 里的 message 值 'abc!'
      // ② .split('') 把字符串拆成数组 ['a', 'b', 'c', '!']
      // ③ .reverse() 反转数组 ['!', 'c', 'b', 'a']
      // ④ .join('') 组合成字符串 '!cba'
      // 最终返回 '!cba'
    }
  }
});
计算属性本质上是一个计算函数,但它:

像变量一样使用

依赖数据变化时才会重新计算

有缓存,提高性能


计算属性 reversedMessage

reversedMessage 依赖 message,Vue 发现 message 变了,就会重新计算 

computed vs methods

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

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

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


都可以简写

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

computed setter

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

是 Vue 计算属性的一个特性,它允许你不仅读取(getter),还可以修改(setter)计算属性的值。一般来说,计算属性默认是只有 getter(用于返回值),但你可以为它添加一个 setter,用来修改计算属性的值。当你对计算属性赋值时,setter 会被调用

通过 this 访问 data 里的属性

九、Vue.js 监听属性

  watch

Vue.js 监听属性 watch,通过 watch 来响应数据的变化。

watch是什么?通俗来说,watch 就是 Vue 里的“监听器”用来“监听”某个数据的变化,“数据一变,就执行某段代码”。

实例用 watch 实现计数器:

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

千米之间的换算

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

当我们在输入框输入数据时,watch 会实时监听数据变化并改变自身的值

十、Vue.js 样式绑定

classstyle 都是用来控制元素的外观和样式的属性

class 适合用于 批量控制样式 //上面摆有style

style 更适合 直接控制单个元素的样式,//上面没有style(直接在行内写)

style 的优先级高于 class

  • class:用于为 HTML 元素指定一个或多个类名(class),通过这些类名可以在外部的 CSS 文件中定义样式,从而使元素的样式具有一致性和可重用性。

  • style:直接在 HTML 元素上内联(inline)定义样式。它用于为元素添加具体的样式,而不需要外部的 CSS 文件。

Vue.js class

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

Vue.js v-bind 在处理 class 和 style 时, 专门增强了它。表达式的结果类型除了字符串之外,还可以是对象或数组。

说白了,就是控制元素样式有没有

class 属性绑定

对象语法

:class 设置一个对象,从而动态的切换 class:

在 JavaScript 和 Vue 中
对象(Object) 是一种 键值对(key-value) 结构的数据类型,通常用于存储和组织数据。

其实python java都是类似的。

人类{

 性别:
 年龄:
 职业:

}       //也是键值对啊

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

//其实就是用键值对对象存在这个样式
对象语法本质上是一个键值对(key-value),key(键) 是要绑定的 class 名称。value(值) 是一个布尔值(true 或 false)。

"对象"
"键值对"
<div :class="{ 'key类名a1': 绑定color(true) }"></div>

实例 2:a2类背景颜色覆盖了 a1 类的背景色

实例 3:我们也可以直接绑定数据里的一个对象,a2类背景颜色覆盖了 a1类的背景色:

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

计算属性 classObject 返回的是一个对象
这个对象中的键(a1, a2, a3)是 CSS 类名,值是布尔值(true 或 false)。这些布尔值决定了是否应用相应的 CSS 类。

总的来说:

a1: 始终是 true,所以类 a1 会一直应用。

a2: 只有当 ok 为 true 且 error.yes 为 false 时,a2 才会应用。

a3: 只有当 error.yes 为 true 且 error.type 等于 '666' 时,a3 才会应用。


直白一点:
通过计算属性返回一个对象(对象里面做了计算)(这个对象里面包含了样式)

举个例子:

我有个 div,我想根据某些条件(数据是否为真,或者是什么)来决定给 div 加哪些样式。

我可以创建一个计算属性,它会根据我指定的规则,动态地返回一个计算后的对象(这个对象包含最终执行的样式)。

这是一个非常强大且常见的 Vue 模式,意思是,你不需要手动写死管理一堆样式,而是通过计算属性自动根据状态返回需要的样式或类。

数组语法

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

这些指令也好 语法也好做操作的都是vue应用里面的

也就是说绑定的都是new vue里面的东西,通过这些东西指向谁。去应用

<div :class="数组[绑定数据a1Class(a1类), 绑定数据a2Class(a2类)]"></div>                           

三元表达式

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

三目运算符(?:

//其实就是绑定数据的时候顺便做个判断什么时候用这个数据(和数据里面的东西)

class="数组[,]"

<div v-bind:class="[绑定数据a1Class ,ok ? 绑定数据a2Class : '']"></div>

Vue.js style(内联样式)

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

直接设置

<div id="app">
    <div :style="{ 内联样式color: 绑定数据Col, 内联样式fontSize: 绑定数据Size + 'px' }">sb教程</div>
</div>



//渲染

<div style="color: green; font-size: 30px;">sb教程</div>

对象语法

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

<div id="app">
  <div v-bind:style="对象Object">人才教程</div>
</div>

数组语法

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

<div id="app">
  <div :style="数组[arr1, arr2]">人才教程</div>
</div>

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

十一、Vue.js 事件处理器

v-on

事件监听可以使用 v-on 指令:

<button @click="count += 1"></button>

 
  data: {
    counter: 0
  }

直接绑定方法()

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

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

事件对象(event)的变量名是可以自定义的

<!-- `gg` 是在下面定义的方法名 -->
<button @click="gg"></button>



  data: {
    name: '小笨蛋'
  },

  methods: {
    gg(e) { alert('Hello ' + this.name + '!')  2
              if (e) { alert(e.target.tagName)   3 }   }  }


app.greet() // -> 'Hello 小笨蛋'  1

内联 JavaScript 语句

除了直接绑定到一个方法,也可以用内联 JavaScript 语句//其实tnnd就是调动方法

//调用方法say()
<button @click="say('hi')">说一个值hi</button>


methods: {
    say: function (num) {//定义say(传参)
      alert(num) //弹窗
    }
  }

事件修饰符.

Vue.js 为 v-on 提供了事件修饰符(点 .)来处理 DOM 事件细节 . 指令后缀来调用修饰符。

事件和修饰符的意思:

  • 事件:是指用户在页面上进行操作(用户动了都算),用户点击、输入、拖动、滚动、键盘按键等行为,都属于事件

常见的用户操作事件:
点击事件 (click):用户点击一个元素(比如按钮、链接等)。

输入事件 (input):用户在输入框中输入文字。

键盘事件 (keydown, keyup):用户按下或松开键盘上的某个键。

鼠标事件 (mouseenter, mouseleave, mousemove):鼠标进入、离开、移动到元素区域。

表单事件 (submit, change):用户提交表单或修改表单中的输入内容。
  • 修饰符:这个词的意思是“附加的”或者“额外的功能”。它用来改变某个东西的行为。比如我们给一个按钮添加了修饰符,那么这个按钮的行为就会有所不同。

为什么叫 "事件修饰符"?

  • 事件修饰符指的就是在 Vue 中用来“修饰”事件的额外功能(比如阻止事件的默认行为,或停止事件的传播)。通过修饰符,我们可以让事件的行为更符合我们的需求,而不用手动编写额外的 JavaScript 代码。

举个简单例子:

假设你有一个按钮,点击它会提交表单后会默认刷新,但你不想让表单提交页面刷新。使用事件修饰符 .prevent 用来阻止这个默认行为。

//<form @submit="submitForm">
<form @submit.prevent="submitForm">
  <button type="submit">提交</button>
</form>
.stop - 阻止冒泡
.prevent - 阻止默认事件
.capture - 阻止捕获
.self - 只监听触发该元素的事件
.once - 只触发一次
.left - 左键事件
.right - 右键事件
.middle - 中间滚轮事件

<!-- 阻止单击事件冒泡 -->             //反!!!
//冒泡:我跟你讲话,传播太远门口都听到//大家监听的都是click,我点击一个click相当于触发所有个
//阻止我的点击触发到上层
<a v-on:click.stop="doThis"></a>

<div @click.capture="parentClick">  2.                    1.
  <button @click="childClick">点我</button> //点击 1.     点击  2.   这里用下面的捕获
</div>





<!-- 提交事件不再重载页面 -->
//直白:提交后不刷新页面
<form @submit.prevent="onSubmit"></form>


<!-- 修饰符可以串联  -->
//直白:同时处理多个行为。
<a @click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
//只有修饰符,没有方法//阻止表单提交时默认行为,但不执行任何额外的代码(不执行提交)。
//直白:就像你只是按下刹车,但不做其他操作。
<form @submit.prevent></form>

<!-- 添加事件侦听器时使用事件捕获模式 -->     //反!!!
//默认情况下,事件是“冒泡”执行的(从子元素往父元素传)。
//@click.capture 让事件变成“捕获”执行(从父元素往子元素传)
//直白:我随便在页面点击  看第一个执行谁?
<div @click.capture="doThis">...</div>

<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
//直白:监听的是div
<div @click.self="doThat">...</div>

<!-- click 事件只能点击一次,2.1.4版本新增 -->
//直白:点击后,失效
<a @click.once="doThis"></a>

按键修饰符

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

<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
//Enter 键的 keyCode 是 13
//直白:按下回车键才会提交
<input @keyup.13="submit">

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

<!-- 别名:用所标名 -->
<input @keyup.enter="submit">


//全部的按键别名
.enter
.tab
.delete (捕获 "删除" 和 "退格" 键)
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta

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

十二、Vue.js 表单(双向数据绑定)

这节介绍 Vue.js 表单上的应用。

你可以用 v-model 指令在表单控件元素上创建双向数据绑定。

Vue 根据控件类型自动选取合适方式更新数据

  • v-model 不同控件行为监听更新:

  • 文本框:监听 input 事件

    • 根据输入实时更新。

  • 单选框(radio: change 事件

    • 根据选中更新。

  • 复选框(checkbox:监听勾选状态。

    • 根据选中。true /勾选的值;没有勾选 false

  • 下拉框(<select>change 事件

文本框 (input) 是实时变化的,单选框、复选框、下拉框 都是在用户改变选项后才触发 change 更新数据。

举个简单的例子:

html

<!-- 文本框的双向绑定 -->
<input v-model="message">
<p>输入的内容是:{{ message }}</p>


当你在输入框里输入内容时,message 的值会自动更新,并且页面上的 {{ message }} 也会自动显示最新的内容。

输入框

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

复选框

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

复选框的双向数据绑定

单选按钮

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

是按钮!按钮!

select下拉列表

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

修饰符

.lazy(延迟更新)

.lazy 修饰符的作用是 延迟 v-model 绑定数据的更新时机,默认v-model 绑定的值会在 input 事件触发时(也就是用户每输入一个字符)立即更新到 msg 变量上。加上 .lazymsg 只有在 change 事件触发时才会更新。

 v-model 在 input 事件中同步改为在 change 事件中同步:

也就是本来我输入是时候实时输出,现在是我输入完的时候离开输入框输出。

<div id="app">
    <input v-model.lazy="msg"> //就这一条
    <p>输入的内容:{{ msg }}</p>
</div>

<script>
    new Vue({
        el: "#app",
        data: {
            msg: ""
        }
    });
</script>
<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >



行为对比
方式	          更新时机
v-model 默认	用户每次输入都会更新数据(input 事件)
v-model.lazy	只有当输入框失去焦点(change 事件)时才更新数据

适用场景
适用于 不需要实时更新 的情况,比如减少计算或 API 调用的频率。

适用于 需要在用户完成输入后再统一处理 的情况,如表单提交。

总结
加上 .lazy 后,v-model 会在 失去焦点(blur)或者按下 Enter 确认输入 时,才更新绑定的数据,而不是每次输入都更新

.number(自动转为数字类型)

.number 修饰符的作用是 自动将用户输入的string数据类型转换为 Number 数字类型,避免字符串类型的数据影响计算或逻辑判断。

默认行为(不加 .number

在 HTML 表单中,所有 input 输入的值都是 字符串类型,即使 type="number",用户输入的值仍然是 字符串

<div id="app">
    <input v-model.number="age" type="number"> //就这一句
    <p>输入的类型:{{ typeof age }}</p>
    <p>输入的值:{{ age }}</p>
</div>

<script>
    new Vue({
        el: "#app",
        data: {
            age: ""
        }
    });
</script>

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

.trim(输入时去除首尾空格)

.trim 主要用于 自动去除用户输入的首尾空格,避免数据存储时带有不必要的空格。

局限性:只能去除首尾空格,不会去掉 中间的空格

局限性:仅对 input 输入框有效,不影响 textarea多行文本输入框。如果需要对 textarea 也去空格,可以手动 trim()

方式是否推荐结果
<input v-model="msg">❌ 不推荐输入空格不会自动去除
<input v-model.trim="msg">✅ 推荐自动去除前后空格,防止数据污染
html
----------------------------------------------------------------------------
<div id="app">
    <input v-model.trim="msg"> //就这一句
    <p>输入的值:"{{ msg }}"</p>
    <p>字符长度:{{ msg.length }}</p>
</div>

<script>
    new Vue({
        el: "#app",
        data: {
            msg: ""
        }
    });
</script>

----------------------------------------------------------------------------
vue

<script>
export default {
  data() {
    return {
      msg: ""
    };
  }
};
</script>

十三、Vue组件

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

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

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

方式适用场景例子
全局组件适用于通用组件,如按钮、标题等Vue.component('my-button', {...})
局部组件适用于某些页面特定组件components: { MyButton }

如果你只是特定页面需要组件,建议用局部组件,否则可以用全局组件

注册组件=创建组件=告诉vue组件存在

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

Vue.component(tagName, options) //tagName 组件名,options 配置选项。

调用组件

<tagName></tagName>  //tagName组件名

Vue 全局组件不仅可以被全局使用,还可以在它内部再注册子组件

全局组件

语法:

//component注册

Vue.component(tagName, options)
Vue.component('组件名', {template: '组件的模板'});
  • Vue.component 用来注册全局组件。

  • '组件名' 是你给组件命名的标签名(使用时会作为 HTML 标签)。

  • options 包含组件的配置,如 templatedatamethods 等。

  • template是Vue 组件的 HTML 模板,决定组件在网页上渲染什么内容

注册全局组件

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

局部组件

语法:

//components注册

new Vue({
  el: '#app',
  components: { //是在实例选项中注册局部组件
    '组件名': {
      template: '组件的模板'
    }
  }
});
  • components 选项用于注册局部组件,只在当前 Vue 实例中有效。

  • '组件名' 是你给组件命名的标签名(仅在该 Vue 实例内有效)。

注册局部组件

Prop

在 Vue 组件中,prop(属性)是子组件用来接收父组件传递的数据的自定义属性

prop 作用父组件传数据

说白了:💡 父组件 通过 props 传递数据到 template子组件html模版显示

props: ['message'],//接收

🌟 生活类比

  • 父组件(家长) 负责准备数据交给子组件

  • 子组件(孩子) 只接受不能直接改动内容。

props  固定写法,即使只传一个 prop,也要写 props: ['message'](带 s)。
props 是数组,可以接收多个 prop参数。
Vue 规定 props 必须是数组,不能写成 prop

🌟 作用

  • prop 让父组件可以 向子组件传递数据

  • 子组件只能 读取 ,但不能修改它(Vue 2 中有 mutating prop 的警告)。

  • prop 可以是 字符串、数组、对象、布尔值等

动态 Prop

动态 Prop 指的是子组件的 prop 值是由父组件的数据动态控制的,而不是一个固定的字符串

简单来说,用v-bind 把父组件的数据传给子组件,并且当父组件的数据变了,子组件也会自动更新。不想上面一样固定死的。

在 Vue 里,v-bind 就像一根 “数据传输线”,把数据传输到显示屏。只要数据变化,显示屏也会自动更新!//显示屏(HTML 里(或者传给子组件))

输入:<input v-model="fatherMsg">//父组件接收html元素
输出:<child :message="fatherMsg">//子组件接收父组件元素</child>

v-bind 就是数据传输工具

使用 v-bind 指令将 todo 传到每一个重复的组件中:

注意: prop 单向:父组件属性变化,传导子组件,但是不会反过来。

Prop 验证

定制 prop 验证=对接收进来的数据验证。

  • 验证检查传递进来的数据是否符合要求,不符合要求时给出警告,但不会修改数据。

  • 过滤是对数据进行修改或筛选,将数据转化为所需的格式或内容。

Vue props 验证规则总结表

规则作用示例
必须传requiredprop 必须传,否则报错{ age: { type: Number, required: true } }
<child :age="18"></child>
<child></child>(缺少 age
类型匹配type传递值必须是指定类型{ name: String, age: Number }
<child name="小明" :age="18"></child>
<child name="小明" :age="'18'"></child>age 传了字符串)
默认值default未传值时使用默认值{ gender: { type: String, default: '未知' } }
<child></child>(默认 gender="未知"
自定义规则validator值必须符合自定义要求{ score: { type: Number, validator: v => v >= 0 && v <= 100 } }
<child :score="85"></child>
<child :score="150"></child>(超出 0~100
Vue.component('my-component', { 
  props: {
    // 基础类型检查
    propA: Number, // 只能是 Number 类型

    // 多个可能的类型
    propB: [String, Number], // 可以是 String 或 Number

    // 必填的字符串
    propC: {
      type: String, // 必须是 String 类型
      required: true // 这个 prop 必须传递,否则报错
    },

    // 带有默认值的数字
    propD: {
      type: Number, // 必须是 Number 类型
      default: 100  // 默认值 100(如果父组件未传递,则使用默认值)
    },

    // 带有默认值的对象
    propE: {
      type: Object, // 必须是 Object 类型
      default: () => ({ message: 'hello' }) // 默认值是 `{ message: 'hello' }`
    },

    // 自定义验证函数
    propF: {
      validator: value => ['success', 'warning', 'danger'].includes(value) 
      // 只能是 'success'、'warning' 或 'danger'
    }
  }
})

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

就是验证失败 浏览器控制台会报错提示。提示的时候可以用type获取数据类型。

type 支持的查询原生构造器包括:

  • String:字符串类型

  • Number:数字类型

  • Boolean:布尔值类型

  • Array:数组类型

  • Object:对象类型

  • Date:日期类型

  • Function:函数类型

  • Symbol:符号类型

你也可以使用自定义构造器,通过 instanceof 检测来验证传入的值是否符合要求。

举例:

假设你定义了以下 props 验证:

props: {
  age: {
    type: Number,
    required: true
  }
}

如果父组件传入的 age 不是 Number 类型(例如传入字符串 '18'),Vue 会在开发环境下的控制台输出类似以下的警告:

表示:age 的类型检查失败,要求age是 Number 类型,但传入的是 String 类型。

[Vue warn]: Invalid prop: type check failed for prop "age". Expected Number, got String.


[Vue warn]:警告信息

Invalid prop:传递给组件的 prop 无效。

type check failed for prop "age":类型检查失败, prop 是 age

Expected Number: 期望 Number 

got String:传入是 String 。

十四、vue组件-自定义事件

为什么需要自定义事件?

父组件用 props 传递数据给子组件,子组件要把数据传递回去,就需要使用自定义事件!。

如何使用自定义事件?

  1. 父组件 使用$on(eventName) 监听事件。

  2. 子组件 使用 $emit 触发自定义事件。

如果你想在某个组件的根元素上监听一个原生事件。可以使用 .native 修饰 v-on 。例如:

<my-component v-on:click.native="doTheThing"></my-component>

data 必须是一个函数

上面例子中,可以看到 zzz 组件中的 data 不是一个对象,而是一个函数

data: function () {
  return {
    count: 0
  }
}

好处每个实例可以维护一份被返回对象的独立的拷贝,如果 data 是一个对象则会影响到其他实例,如下所示:

自定义组件的 v-model

组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件。

<input v-model="parentData">

等价于:

<input 
    :value="parentData"
    @input="parentData = $event.target.value"
>

以下实例自定义组件 runoob-input,父组件的 num 的初始值是 100,更改子组件的值能实时更新父组件的 num:

<div id="app">
    <runoob-input v-model="num"></runoob-input>
    <p>输入的数字为:{{num}}</p>
</div>
<script>
Vue.component('runoob-input', {
    template: `
    <p>   <!-- 包含了名为 input 的事件 -->
      <input
       ref="input"
       :value="value" 
       @input="$emit('input', $event.target.value)"
      >
    </p>
    `,
    props: ['value'], // 名为 value 的 prop
})
   
new Vue({
    el: '#app',
    data: {
        num: 100,
    }
})
</script>

由于 v-model 默认传的是 value,不是 checked,所以对于复选框或者单选框的组件时,我们需要使用 model 选项,model 选项可以指定当前的事件类型和传入的 props。

<div id="app">
    <base-checkbox v-model="lovingVue"></base-checkbox> 
     <div v-show="lovingVue"> 
        如果选择框打勾我就会显示。 
    </div>
</div> 
<script>
// 注册
Vue.component('base-checkbox', {
 
  model: {
    prop: 'checked',
    event: 'change'  // onchange 事件
  },
  props: {
    checked: Boolean
  },
   
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})
// 创建根实例
new Vue({
  el: '#app',
  data: {
    lovingVue: true
  }
})
</script>

十五、Vue.js 自定义指令

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

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

<div id="app">
    <p>页面载入时,input 元素自动获取焦点:</p>
    <input v-focus>
</div>
 
<script>
// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
  // 当绑定元素插入到 DOM 中。
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})
// 创建根实例
new Vue({
  el: '#app'
})
</script>

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

<div id="app">
  <p>页面载入时,input 元素自动获取焦点:</p>
  <input v-focus>
</div>
 
<script>
// 创建根实例
new Vue({
  el: '#app',
  directives: {
    // 注册一个局部的自定义指令 v-focus
    focus: {
      // 指令的定义
      inserted: function (el) {
        // 聚焦元素
        el.focus()
      }
    }
  }
})
</script>

钩子

钩子函数?

钩子函数(Hook Function),就是一种“被动调用”的函数。
不是你手动调用它,而是在特定时机,框架自动帮你调用。

① 指令定义函数的钩子函数

钩子函数名说明
bind只调用一次,指令第一次绑定到元素时调用。可以在这里做初始化。
inserted被绑定元素插入父节点时调用(不要求在 document 中)。
update所在模板更新时调用,无论绑定值是否变化。可以通过对比新旧值优化性能。
componentUpdated元素所在模板完成一次更新周期时调用。
unbind只调用一次,指令与元素解绑时调用。

钩子函数参数

② 钩子函数的参数

参数名说明
el指令绑定的元素,可以直接操作 DOM。
binding一个对象,包含关于指令的详细信息。具体属性如下:
name指令名(不含 v- 前缀)。
value指令绑定的值,例如:v-my-directive="1 + 1",值为 2
oldValue之前的绑定值,仅在 updatecomponentUpdated 钩子中可用。
expression字符串形式的绑定表达式,例如:"1 + 1"
arg传给指令的参数,例如:v-my-directive:foo,参数为 "foo"
modifiers包含修饰符的对象,例如:v-my-directive.foo.bar,值为 { foo: true, bar: true }
vnodeVue 编译生成的虚拟节点。
oldVnode上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

十六、Vue.js 路由

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

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

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

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

安装

1、直接下载 / CDN

https://unpkg.com/vue-router/dist/vue-router.js

2、NPM

推荐使用淘宝镜像:

cnpm install vue-router

简单实例

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

<router-link> 是一个组件,用于设置一个导航链接切换。 to 属性目标(页面)地址。

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

HTML 


<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
 
<div id="app">
  <h1>购物商城!</h1>
  <p>
    <!-- 使用 router-link 组件来导航. -->
    <!-- 通过传入 `to` 属性指定目标页面地址链接. -->
    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    <router-link to="/foo">手机</router-link>
    <router-link to="/bar">电脑</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>
JavaScript 

// 0. 如果使用模块化机制编程,导入 Vue 和 VueRouter,要调用 Vue.use(VueRouter)
 
// 1. 定义(路由)组件。
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
 
// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]
 
// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
  routes // (缩写)相当于 routes: routes
})
 
// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
  router
}).$mount('#app')
 
// 现在,应用已经启动了!

<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 内容会发生改变。

注意:

exact-active-class 和 active-class 的区别

router-link 默认情况下的路由是模糊匹配,例如当前路径是 /article/1 那么也会激活 <router-link to="/article">,所以当设置 exact-active-class 以后,这个 router-link 只有在当前路由被全包含匹配时才会被激活 exact-active-class 中的 class,例如:

<router-link to="/article" active-class="router-active"></router-link>

当用户访问 /article/1 时会被激活为:

<a href="#/article" class="router-active" rel="nofollow"></a>

而当使用:

<router-link to="/article" exact-active-class="router-active"></router-link>

当用户访问 /article/1 时,不会激活这个 link 的 class:

const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function(location) {
    return originalPush.call(this, location).catch(err => err)
};
<a href="#/article" rel="nofollow"></a>

在 vue 中多次切换相同一个路由会存在问题。

vue-router.js:2071 Uncaught (in promise) NavigationDuplicated: Avoid redundant navigation to current location: "/xxxx"

解决方案:

1、每次切换路由之前手动判断:

if(this.$route.name!='xxxx'){
    this.$router.push({name:'xxxx'});
}

2、在创建路由规则对象之后加入如下配置:

十七、Vue.js 过渡 & 动画

本章节我们主要讨论 Vue.js 的过渡效果与动画效果。

过渡

Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。

Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件。

语法格式

<transition name = "nameoftransition">
   <div></div>
</transition>

十八、Vue.js 混入

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

来看一个简单的实例:

十九、Vue.js Ajax(axios)

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

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

安装方法

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

浏览器支持情况

GET 方法

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

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

使用 response.data 读取 JSON 数据:

<div id="app">
  <h1>网站列表</h1>
  <div
    v-for="site in info"
  >
    {{ site.name }}
  </div>
</div>
<script type = "text/javascript">
new Vue({
  el: '#app',
  data () {
    return {
      info: null
    }
  },
  mounted () {
    axios
      .get('https://www.runoob.com/try/ajax/json_demo.json')
      .then(response => (this.info = response.data.sites))
      .catch(function (error) { // 请求失败处理
        console.log(error);
      });
  }
})
</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 方法

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:'https://static.jyshare.com/images/runoob-logo.png',
  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#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, https://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('https://www.runoob.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");

二十、Vue.js Ajax(vue-resource)

Vue 要实现异步加载需要使用到 vue-resource 库。

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

<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>

Get 请求

以下是一个简单的 Get 请求实例,请求地址是一个简单的 txt 文本:

window.onload = function(){
    var vm = new Vue({
        el:'#box',
        data:{
            msg:'Hello World!',
        },
        methods:{
            get:function(){
                //发送get请求
                this.$http.get('/try/ajax/ajax_info.txt').then(function(res){
                    document.write(res.body);    
                },function(){
                    console.log('请求失败处理');
                });
            }
        }
    });
}

如果需要传递数据,可以使用 this.$http.get('get.php',{params : jsonData}) 格式,第二个参数 jsonData 就是传到后端的数据

this.$http.get('get.php',{params : {a:1,b:2}}).then(function(res){
    document.write(res.body);    
},function(res){
    console.log(res.status);
});

post 请求

post 发送数据到后端,需要第三个参数 {emulateJSON:true}。

emulateJSON 的作用: 如果Web服务器无法处理编码为 application/json 的请求,你可以启用 emulateJSON 选项。

window.onload = function(){
    var vm = new Vue({
        el:'#box',
        data:{
            msg:'Hello World!',
        },
        methods:{
            post:function(){
                //发送 post 请求
                this.$http.post('/try/ajax/demo_test_post.php',{name:"菜鸟教程",url:"http://www.runoob.com"},{emulateJSON:true}).then(function(res){
                    document.write(res.body);    
                },function(res){
                    console.log(res.status);
                });
            }
        }
    });
}

demo_test_post.php 代码如下:

<?php
$name = isset($_POST['name']) ? htmlspecialchars($_POST['name']) : '';
$city = isset($_POST['url']) ? htmlspecialchars($_POST['url']) : '';
echo '网站名: ' . $name;
echo "\n";
echo 'URL 地址: ' .$city;
?>

语法 & API

你可以使用全局对象方式 Vue.http 或者在一个 Vue 实例的内部使用 this.$http来发起 HTTP 请求。

// 基于全局Vue对象使用http
Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback);
Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);

// 在一个Vue实例内使用$http
this.$http.get('/someUrl', [options]).then(successCallback, errorCallback);
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);

vue-resource 提供了 7 种请求 API(REST 风格):

get(url, [options])
head(url, [options])
delete(url, [options])
jsonp(url, [options])
post(url, [body], [options])
put(url, [body], [options])
patch(url, [body], [options])

除了 jsonp 以外,另外 6 种的 API 名称是标准的 HTTP 方法。

options 参数说明:

参数类型描述
urlstring请求的目标URL
bodyObjectFormDatastring作为请求体发送的数据
headersObject作为请求头部发送的头部对象
paramsObject作为URL参数的参数对象
methodstringHTTP方法 (例如GET,POST,...)
timeoutnumber请求超时(单位:毫秒) (0表示永不超时)
beforefunction(request)在请求发送之前修改请求的回调函数
progressfunction(event)用于处理上传进度的回调函数 ProgressEvent
credentialsboolean是否需要出示用于跨站点请求的凭据
emulateHTTPboolean是否需要通过设置X-HTTP-Method-Override头部并且以传统POST方式发送PUT,PATCH和DELETE请求。
emulateJSONboolean设置请求体的类型为application/x-www-form-urlencoded

通过如下属性和方法处理一个请求获取到的响应对象:

属性类型描述
urlstring响应的 URL 源
bodyObjectBlobstring响应体数据
headersHeader请求头部对象
okboolean当 HTTP 响应码为 200 到 299 之间的数值时该值为 true
statusnumberHTTP 响应码
statusTextstringHTTP 响应状态
方法类型描述
text()约定值以字符串方式返回响应体
json()约定值以格式化后的 json 对象方式返回响应体
blob()约定值以二进制 Blob 对象方式返回响应体

二十一、Vue.js 响应接口

Vue 可以添加数据动态响应接口。

例如以下实例,我们通过使用 $watch 属性来实现数据的监听,$watch 必须添加在 Vue 实例之外才能实现正确的响应。

实例中通过点击按钮计数器会加 1。setTimeout 设置 10 秒后计算器的值加上 20 。

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

Vue 不允许在已经创建的实例上动态添加新的根级响应式属性。

Vue 不能检测到对象属性的添加或删除,最好的方式就是在初始化实例前声明根级响应式属性,哪怕只是一个空值。

如果我们需要在运行过程中实现属性的添加或删除,则可以使用全局 Vue,Vue.set 和 Vue.delete 方法。

Vue.set

Vue.set 方法用于设置对象的属性,它可以解决 Vue 无法检测添加属性的限制,语法格式如下:

Vue.set( target, key, value )

参数说明:

  • target: 可以是对象或数组
  • key : 可以是字符串或数字
  • value: 可以是任何类型
<div id = "app">
   <p style = "font-size:25px;">计数器: {{ products.id }}</p>
   <button @click = "products.id++" style = "font-size:25px;">点我</button>
</div>
<script type = "text/javascript">
var myproduct = {"id":1, name:"book", "price":"20.00"};
var vm = new Vue({
   el: '#app',
   data: {
      products: myproduct
   }
});
vm.products.qty = "1";
console.log(vm);
vm.$watch('products.id', function(nval, oval) {
   alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
});
</script>

在以上实例中,使用以下代码在开始时创建了一个变量 myproduct:

var myproduct = {"id":1, name:"book", "price":"20.00"};

该变量在赋值给了 Vue 实例的 data 对象:

var vm = new Vue({ el: '#app', data: { products: myproduct } });

如果我们想给 myproduct 数组添加一个或多个属性,我们可以在 Vue 实例创建后使用以下代码:

vm.products.qty = "1";

查看控制台输出:

如上图看到的,在产品中添加了数量属性 qty,但是 get/set 方法只可用于 id,name 和 price 属性,却不能在 qty 属性中使用。

我们不能通过添加 Vue 对象来实现响应。 Vue 主要在开始时创建所有属性。 如果我们要实现这个功能,可以通过 Vue.set 来实现:

<div id = "app">
<p style = "font-size:25px;">计数器: {{ products.id }}</p>
<button @click = "products.id++" style = "font-size:25px;">点我</button>
</div>
<script type = "text/javascript">
var myproduct = {"id":1, name:"book", "price":"20.00"};
var vm = new Vue({
   el: '#app',
   data: {
      products: myproduct
   }
});
Vue.set(myproduct, 'qty', 1);
console.log(vm);
vm.$watch('products.id', function(nval, oval) {
   alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
});
</script>

从控制台输出的结果可以看出 get/set 方法可用于qty 属性。

Vue.delete

Vue.delete 用于删除动态添加的属性 语法格式:

Vue.delete( target, key )

参数说明:

  • target: 可以是对象或数组
  • key : 可以是字符串或数字
<div id = "app">
   <p style = "font-size:25px;">计数器: {{ products.id }}</p>
   <button @click = "products.id++" style = "font-size:25px;">点我</button>
</div>
<script type = "text/javascript">
var myproduct = {"id":1, name:"book", "price":"20.00"};
var vm = new Vue({
   el: '#app',
   data: {
      products: myproduct
   }
});
Vue.delete(myproduct, 'price');
console.log(vm);
vm.$watch('products.id', function(nval, oval) {
   alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
});
</script>

以上实例中我们使用 Vue.delete 来删除 price 属性。以下是控制台输出结果:

从上图输出结果中,我们可以看到 price 属性已删除,只剩下了 id 和 name 属性,price 属性的 get/set 方法也已删除。

html学两天,css学两个星期,js去看两个星期,然后看一个星期vue。直接去写项目通过项目项目成长

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2329565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【工业场景】用YOLOv12实现饮料类别识别

饮料类别识别任务的意义在于帮助人们更快速地识别和区分不同类型的饮料&#xff0c;从而提高消费者的购物体验和满意度。对于商家而言&#xff0c;饮料类别识别可以帮助他们更好地管理库存、优化货架布局和预测销售趋势&#xff0c;从而提高运营效率和利润。此外&#xff0c;饮…

从小米汽车事故反思 LabVIEW 开发

近期&#xff0c;小米汽车的一起严重事故引发了社会各界的广泛关注。这起事故不仅让我们对智能汽车的安全性产生了深深的思考&#xff0c;也为 LabVIEW 开发领域带来了诸多值得汲取的知识与领悟。 在智能汽车领域&#xff0c;尤其是涉及到智能驾驶辅助系统时&#xff0c;安全是…

Vue3+Vite+TypeScript+Element Plus开发-04.静态菜单设计

系列文档目录 Vue3ViteTypeScript安装 Element Plus安装与配置 主页设计与router配置 静态菜单设计 Pinia引入 文章目录 目录 系列文档目录 文章目录 前言 一、Aside设计 二、动态增加菜单 三.布局引用在Main中显示 参考文献&#xff1a; 前言 在本系列文档中&…

大数据技术发展与应用趋势分析

大数据技术发展与应用趋势分析 文章目录 大数据技术发展与应用趋势分析1. 大数据概述2 大数据技术架构2.1 数据采集层2.2 数据存储层2.3 数据处理层2.4 数据分析层 3 大数据发展趋势3.1 AI驱动的分析与自动化3.2 隐私保护分析技术3.3 混合云架构的普及3.4 数据网格架构3.5 量子…

与Linux操作系统相关的引导和服务

目录 一.Linux操作系统引导过程 1.1引导过程总览 1.2系统初始化进程 1.2.1init进程 1.2.2sysmted 1.3systemd单元类型 二.排除启动类故障 2.1MBR扇区故障 2.1.1故障原因 2.1.2故障现象 2.1.3解决办法 2.1.4模拟修复MBR扇区故障 1)添加新的硬盘 2&#xff09;进行…

STM32单片机入门学习——第16节: [6-4] PWM驱动LED呼吸灯PWM驱动舵机PWM驱动直流电机

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.04.05 STM32开发板学习——第16节: [6-4] PWM驱动LED呼吸灯&PWM驱动舵机&PWM驱…

基础框架系列分享:一个通用的Excel报表生成管理框架

由于我们系统经常要生成大量的Excel报表&#xff08;Word&#xff0c;PDF报表也有&#xff0c;另行分享&#xff09;&#xff0c;最初始他们的方案是&#xff0c;设计一个表&#xff0c;和Excel完全对应&#xff0c;然后读表&#xff0c;把数据填进去&#xff0c;这显然是非常不…

Ansible(4)—— Playbook

目录 一、Ansible Playbook : 1、Play &#xff1a; 2、Playbook&#xff1a; 二、Ansible Playbook 格式&#xff1a; 1、空格&#xff1a; 2、破折号&#xff08; - &#xff09;&#xff1a; 3、Play 格式&#xff1a; 三、查找用于任务的模块&#xff1a; 1、模块…

自学-C语言-基础-数组、函数、指针、结构体和共同体、文件

这里写自定义目录标题 代码环境&#xff1a;&#xff1f;问题思考&#xff1a;一、数组二、函数三、指针四、结构体和共同体五、文件问题答案&#xff1a; 代码环境&#xff1a; Dev C &#xff1f;问题思考&#xff1a; 把上门的字母与下面相同的字母相连&#xff0c;线不能…

蓝桥云客--团队赛

2.团队赛【算法赛】 - 蓝桥云课 问题描述 蓝桥杯最近推出了一项团队赛模式&#xff0c;要求三人组队参赛&#xff0c;并规定其中一人必须担任队长。队长的资格很简单&#xff1a;其程序设计能力值必须严格大于其他两名队友程序设计能力值的总和。 小蓝、小桥和小杯正在考虑报名…

C-S模式之实现一对一聊天

天天开心&#xff01;&#xff01;&#xff01; 文章目录 一、如何实现一对一聊天&#xff1f;1. 服务器设计2. 客户端设计3. 服务端代码实现4. 客户端代码实现5. 实现说明6.实验结果 二、改进常见的服务器高并发方案1. 多线程/多进程模型2. I/O多路复用3. 异步I/O&#xff08;…

[Deep-ML]Transpose of a Matrix(矩阵的转置)

Transpose of a Matrix&#xff08;矩阵的转置&#xff09; 题目链接&#xff1a; Transpose of a Matrix&#xff08;矩阵的转置&#xff09;https://www.deep-ml.com/problems/2 题目描述&#xff1a; 难度&#xff1a; easy&#xff08;简单&#xff09;。 分类&#…

智慧节能双突破 强力巨彩谷亚VK系列刷新LED屏使用体验

当前全球节能减排趋势明显&#xff0c;LED节能屏作为显示技术的佼佼者&#xff0c;正逐渐成为市场的新宠。强力巨彩谷亚万境VK系列节能智慧屏凭借三重技术保障、四大智能设计以及大师臻彩画质&#xff0c;在实现节能效果的同时&#xff0c;更在智慧显示领域树立新的标杆。   …

html 给文本两端加虚线自适应

效果图&#xff1a; <div class"separator">文本 </div>.separator {width: 40%;border-style: dashed;display: flex;align-items: center;color: #e2e2e2;font-size: 14px;line-height: 20px;border-color: #e2e2e2;border-width: 0; }.separator::bef…

leetcode4.寻找两个正序数组中的中位数

思路源于 LeetCode004-两个有序数组的中位数-最优算法代码讲解 基本思路是将两个数组看成一个数组&#xff0c;然后划分为两个部分&#xff0c;若为奇数左边部分个数多1&#xff0c;若为偶数左边部分等于右边部分个数。i表示数组1划分位置&#xff08;i为4是索引4也表示i的左半…

0101安装matplotlib_numpy_pandas-报错-python

文章目录 1 前言2 报错报错1&#xff1a;ModuleNotFoundError: No module named distutils报错2&#xff1a;ERROR:root:code for hash blake2b was not found.报错3&#xff1a;**ModuleNotFoundError: No module named _tkinter**报错4&#xff1a;UserWarning: Glyph 39044 …

OSCP - Proving Grounds- SoSimple

主要知识点 wordpress 插件RCE漏洞sudo -l shell劫持 具体步骤 依旧是nmap 起手&#xff0c;只发现了22和80端口&#xff0c;但80端口只能看到一张图 Nmap scan report for 192.168.214.78 Host is up (0.46s latency). Not shown: 65533 closed tcp ports (reset) PORT …

C语言求3到100之间的素数

一、代码展示 二、运行结果 三、感悟思考 注意: 这个题思路他是一个试除法的一个思路 先进入一个for循环 遍历3到100之间的数字 第二个for循环则是 判断他不是素数 那么就直接退出 这里用break 是素数就打印出来 在第一个for循环内 第二个for循环外

【2025】物联网发展趋势介绍

目录 物联网四层架构感知识别层网络构建层管理服务层——**边缘存储**边缘计算关键技术&#xff1a;综合应用层——信息应用 物联网四层架构 综合应用层&#xff1a;信息应用 利用获取的信息和知识&#xff0c;支持各类应用系统的运转 管理服务层&#xff1a;信息处理 对数据进…

如何查看 MySQL 的磁盘空间使用情况:从表级到数据库级的分析

在日常数据库管理中&#xff0c;了解每张表和每个数据库占用了多少磁盘空间是非常关键的。这不仅有助于我们监控数据增长&#xff0c;还能为性能优化提供依据。 Google Gemini中国版调用Google Gemini API&#xff0c;中国大陆优化&#xff0c;完全免费&#xff01;https://ge…