什么是vue?
- Vue (读音 /vjuː/,类似于 view) 是一个前端框架, 易于构建用户界面
- Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合
- 支持和其它类库结合使用
- 开发复杂的单页应用非常方便
- Vue 是 Vue.js 的简称
MVVM
- M∶即 Model,模型,包括数据和一些基本操作
- V∶即View,视图,页面渲染结果
- 在 MVVM之前,开发人员从后端获取需要的数据模型,然后要通过DOM操作Model 渲染到View 中。而后当用户操作视图,我们还需要通过DOM获取View中的数据,然后同步到Model 中。
- 而 MVVM中的VM 要做的事情就是把DOM 操作完全封装起来,开发人员不用再关心Model 和View 之间是如何互相影响的
只要我们 Model 发生了改变,View上自然就会表现出来当用户修改了View,Model 中的数据也会跟着改变。- 结果:把开发人员从繁琐的 DOM操作中解放出来,把关注点放在如何操作Model上, 大大提高开发效率
VUE中的debug
可以直接在浏览器上面输入指令运行调试, 对应我们后面调试 Vue 项目很有用
快速入门
<!--
1. div不是必须的, 可以是span
2. 使用div的原因是, div便于布局
3. id 可以不是 "app"
-->
<div id="app">
<!--
1. {{}} 是插值表达式
2. message就是从module的data 数据池来设置的
3. 当我们执行到这段代码时, 回到data{} 数据池匹配数据, 如果匹配上就进行替换, 没有匹配上就输出空
-->
<h1> 欢迎你 {{message}} -- {{name}}</h1>
</div>
<!--引入vue-->
<script src="vue/vue.js"></script>
<script type="text/javascript">
// 创建vue对象
let vm = new Vue({
// Vue 实例的 el 属性在差值表达式之前被定义,会导致差值表达式无法被识别。
el:"#app",
data: {
//data{} 表示数据池(model 的有了数据), 有很多数据 ,以k-v 形式设置(根据业务需要来设置)
message: "Hello_vue!",
name: "leikooo"
}
});
</script>
细节
- 注意代码顺序,要求 div 在前,script 在后,否则无法绑定数据
- 从案例可以体会声明式渲染:Vue.js 采用简洁的模板语法来声明式地将数据渲染进DOM 的系统, 做到数据和显示分离
- Vue 没有繁琐的 DOM 操作,如果使用 jQuery,我们需要先找到div 节点,获取到DOM对象,然后进行节点操作, 显然 Vue 更加简洁
数据单项渲染 (v-bind)
差值表达式和单项渲染的区别和联系
- 联系 都能从data中取出数据
- 区别
- 使用插值表达式引用 data 数据池数据是在标签体内
- 在标签/元素 的属性上去引用 data 数据池数据时, 使用单向数据渲染
具体案例 :
<div id="app">
<h1> {{content}}</h1>
<img v-bind:src="img_src" v-bind:width="img_width">
<!-- 简写形式-->
<img :src="img_src" :width="img_width">
</div>
<script src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
content: "CodingImprove",
img_src: "编程真是一辈都学不完.png",
img_width: "400px"
}
});
</script>
数据双向绑定 (v-model)
数据双向绑定是 Vue.js 框架中的一项核心特性,它可以将模型 (Model) 层中的数据和视图 (View) 层中的数据进行双向绑定。也就是说,当模型层的数据发生变化时,视图层中的数据会自动更新;反之,当视图层中的数据发生变化时,模型层中的数据也会自动更新。
写法上的小细节!!
<input type="text" v-model="score">
<input type="text" v-model:value="score"> 者两种写法的区别是什么
这两种写法都是用于在 Vue.js 中双向绑定数据的输入框,但它们在实现上略有不同。
第一种写法使用了 v-model 指令及其简化的语法,可以同时将数据的值绑定到表单中,并且在用户输入时自动更新数据。在这种情况下,score 是一个计算属性,并且在组件内被定义和处理。这种写法适用于大多数情况。
第二种写法使用了 v-model:value 指令,其中 value 可以替换成任何其他表单属性,例如 v-model:checked 或 v-model:disabled 等等。这种写法也可以用来绑定数据并且在用户输入时自动更新,但是相对来说它的语法稍微繁琐一些。它适用于需要绑定具有特殊属性的表单元素的情况
案例
<div id="app">
<h1>{{message}}</h1>
<!-- v-model是数据双向渲染
(1)data 数据池绑定的数据变化,会影响 view 【底层的机制是 Data Bindings】
(2)view 关联的的元素值变化, 会影响到 data 数据池的数据【底层机制是DomListeners】
-->
<input type="text" v-model:value="hobby.val"> <br><br>
<!-- 这个v-bind是单向渲染-->
<input type="text" v-bind:value="hobby.val"> <br>
<p>输入的爱好是 {{hobby.val}}</p>
</div>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
message: "输入你的爱好!",
hobby: {
val: "购物"
}
}
});
</script>
事件处理
- 使用 v-on 进行事件处理,比如: v-on:click 表示处理鼠标点击事件
- 事件调用的方法定义在vue 对象声明的 methods 节点中
- v-on:事件名 可以绑定指定事件
- 方法中使用data中的数据 可以直接使用, 格式 this.属性名
<div id="app">
<!-- 1. v-on:click 表示我们要给button绑定一份click的时间-->
<!-- 2. sayHi() 表示绑定的方法, 在方法池中定义的-->
<input v-on:click="sayHi()" type="submit" value="点击输出">
<input v-on:click="sayOk()" type="submit" value="点击输出">
<input type="submit" value="点击输出">
<input type="submit" value="点击输出">
</div>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app", // 这个是element的缩写
data: {
// module中的数据
message: "Vue事件处理",
name: "韩顺平教育"
},
methods: {
// 1. 这个method是一个属性, 对应写很多方法
// 2. 在{} 中, 可以理解里面是一个方法池
sayHi() {
console.log("hi, 银角大王")
},
sayOk() {
console.log("sayOk, 金角大王")
}
}
})
</script>
细节
- 如果方法不需要传递参数可以不写括号
<input v-on:click="sayOk" type="submit">
- 可以简写 v-on: ==> @
<input @click="sayOk" type="submit">
- 查看可以绑定的事件
作业
<div id="app">
<h1>{{message}}</h1>
<input @click="add(1)" type="submit" value="点击增加+1">
<!-- <input @click="add(2)" type="submit" value="点击增加+2"> <br>-->
<!-- 这里可以拿到 num 这个数据,是因为 Vue 已经将 data 中的属性挂载到了 Vue 实例上-->
<input @click="num += 2" type="submit" value="点击增加+2"> <br>
<!-- <input type="text" v-model:value="num"> -->
<p>你的按钮被点击了{{num}}次</p>
</div>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
message: "演示vue事件绑定操作",
num: 0
},
methods: {
addOne() {
// this可以指定data中的数据
this.num++;
},
addTwo() {
this.num += 2;
},
add(i) {
this.num += i;
}
}
});
</script>
作业二
<div id="app">
<h1>{{message}}</h1>
书名: <input type="text" v-model:value="bookName"> <input type="submit" value="点击显示输入框的内容" @click="popUps()">
</div>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
message: "演示vue事件绑定操作",
bookName: "笑傲江湖~"
},
methods: {
popUps() {
// data和methods在同一个vue对象之中, 因此可以找到vue对象嘚瑟相关data属性
alert(this.bookName);
}
}
});
</script>
修饰符
- 修饰符 (Modifiers) 是以(.)指明的后缀,指出某个指令以特殊方式绑定。
- 例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用event.preventDefault()即阻止事件原本的默认行为
事件修饰分类
- .stop 阻止事件继续传播
- .prevent 阻止标签默认行为
- .capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理
- .self 只当在 event.target 是当前元素自身时触发处理函数
- .once 事件将只会触发一次
- .passive 告诉浏览器你不想阻止事件的默认行为
【需要的时候去看文档】
老韩解惑, 为什么在开发中, 有时需要 , 让某个指令以特殊方式绑定, 比如表单提交
- 我们不希望将这个表单进行整体提交, 而是是 Ajax 的方式进行提交
- 因为表单整体提交会导致重载页面, 而 Ajax 方式可以有选择性提交数据,并且局部刷新
实操案例
小细节: data中的某一个对象可以不写相关的属性, 可以由数据双向渲染生成
<div id="app">
<form action="https://www.baidu.com" v-on:submit.prevent="onMySubmit">
妖怪名 : <input type="text" v-model:value="monster.name"> <br><br>
<input type="submit" value="注册">
</form>
</div>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
monster: {
// 这里面可以不写数据, 可以动态生成
// 数据双向渲染的时候可以动态的生成
}
},
methods: {
onMySubmit() {
// console.log("我自己的提交方式...")
// 在js中 "" null undefined 都是false
if (this.monster.name) {
// 输入了名字
console.log("提交表单的数据 name = " + this.monster.name);
// 可以发送到服务器~
} else {
console.log("请输入数据~~");
}
}
}
});
</script>
条件渲染
v-if
v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。
<h1 v-if="awesome">Vue is awesome!</h1>
也可以用 v-else 添加一个“else 块”:
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
v-show
另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:
<h1 v-show="ok">Hello!</h1>
v-if vs v-show
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
作业
<div id="app">
<!-- blur 失去焦点-->
输入成绩1-100: <input type="text" v-model:value="score" v-on:blur="verify"> <br><br> <br>
你当前的成绩是 {{score}} <br> <br>
<h1 v-if="score >= 90">优秀</h1>
<h1 v-else-if="score >= 70">良好</h1>
<h1 v-else-if="score >= 60">及格</h1>
<h1 v-else>不及格</h1>
</div>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue ({
el: "#app",
data: {
score: 90
},
methods: {
verify() {
if (this.score > 100) {
this.score = 100;
} else if (this.score < 0) {
this.score = 0;
}
}
}
})
列表渲染
了解一下
在Vue.js中,为v-for指令的每个元素添加一个唯一的key是非常重要的。这有助于Vue.js跟踪每个列表项的状态,并且可以提高性能。如果您不提供key属性,Vue.js会发出警告。 在您的代码中,使用:key="item.message"是为v-for循环生成的每个列表项提供唯一标识符的一种方法。这里使用item.message是因为它通常是列表中唯一的值。但是,如果您知道您的数据中有一个唯一的ID或其他标识符,则最好使用该标识符来作为:key属性的值。 综上所述,为了避免Vue.js发出警告并提高性能,建议始终在使用v-for指令时为每个列表项提供一个:key属性。
<ul id="app">
<li v-for="item in items" :key="item.message">
{{item.message}}
</li>
</ul>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
items: [
{message: 'Foo'},
{message: 'Bar'}
]
}
})
</script>
遍历对象
<ul id="app">
<li v-for="item in object" :key="item.id">
{{item}}
</li>
</ul>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue ({
el: "#app",
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})
</script>
遍历数组
<ul id="app">
<li v-for="(item, index) in items" :key="index">
{{parentMessage}} -- {{item.message}} -- {{index}}
</li>
</ul>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
parentMessage: 'Parent',
items: [
{message: 'Foo'},
{message: 'Bar'}
]
}
})
</script>
作业
显示成绩及格的学生
<table id="app" border="1px" width="400px" align="center">
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
<th>score</th>
</tr>
<tr v-for="student in students">
<td v-if="student.score > 60">{{student.id}}</td>
<td v-if="student.score > 60">{{student.name}}</td>
<td v-if="student.score > 60">{{student.age}}</td>
<td v-if="student.score > 60">{{student.score}}</td>
</tr>
</table>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
students: [
{id: 1, name: "Alice", age: 21, score: 40},
{id: 2, name: "Bob", age: 22, score: 30},
{id: 3, name: "Charlie", age: 23, score: 60},
{id: 4, name: "David", age: 24, score: 40},
{id: 5, name: "Emily", age: 25, score: 75},
{id: 6, name: "Frank", age: 26, score: 75},
{id: 7, name: "Grace", age: 27, score: 85},
{id: 8, name: "Henry", age: 28, score: 65},
{id: 9, name: "Isabella", age: 29, score: 95},
{id: 10, name: "Jack", age: 30, score: 70}
]
}
})
</script>
组件化编程
- 在大型应用开发的时候,页面可以划分成很多部分,往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。
- 但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发 (如图)
解读
- 组件(Component) 是 Vue.js 最强大的功能之一(可以提高复用性[1.界面2.业务处理])
- 组件也是一个Vue实例,也包括∶ data、methods、生命周期函数等
- 组件渲染需要 html模板,所以增加了template 属性,值就是HTML 模板
- 对于全局组件,任何vue 实例都可以直接在 HTML 中通过组件名称来使用组件
- data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据
实现方式一 -- 普通方式
缺点
- 界面都一样, 我们都重写了一次, 复用性低
- 各个按钮的逻辑都相同, 业务类似, 但是我们都重新写了一个方法, 复用性低
<div id="app">
<button v-on:click="click"> 点击次数【非组件化编程】{{count}}</button><br> <br>
<button v-on:click="click2"> 点击次数【非组件化编程】{{count2}} </button>
</div>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
count: 10,
count2: 10,
count3: 10
},
methods: {
click() {
this.count++;
},
click2() {
this.count2++;
}
}
})
</script>
实现方式 -- 全局组件
- 定义一个全局组件, 名称为 counter 【名字可以自己取】
- {} 表示就是我们的组件相关的内容
- template 指定该组件的界面, 因为会引用到数据池的数据,所以需要是模板字符串
- 这里老师说明: 要把组件视为一个 Vue 实例,也有自己的数据池和methods
- 这里老师说明: 对于组件,我们的数据池的数据,是使用函数/方法返回【目的是为了保证每个组件的数据是独立】, 不能使用原来的方式
- 这时我们达到目前,界面通过 template 实现共享,业务处理也复用
- 全局组件是属于所有 vue 实例,因此,可以在所有的 vue 实例使用
// 类似于java的static的感觉
Vue.component("counter", {
template: `
<button v-on:click="click"> 点击次数【全局组件化编程】{{ count }}</button>`,
// 这里很不一样, 记住
data() {
return {
count: 10
}
},
methods: {
click() {
this.count++;
}
}
})
实现案例
<div id="app">
<counter></counter> <br/>
<counter></counter>
</div>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
Vue.component("counter", {
template: `
<button v-on:click="click"> 点击次数【全局组件化编程】{{ count }}</button>`,
// 这里很不一样, 记住
data() {
return {
count: 10
}
},
methods: {
click() {
this.count++;
}
}
})
let vm = new Vue({
el: "#app"
})
</script>
实现方式 -- 局部组件
全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加. 所有需要局部组件
<div id="app">
<!-- 使用局部组件, 该组件是从挂载到app的vue中获取-->
<my_counter> </my_counter>
<my_counter> </my_counter>
</div>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
// 这里可以直接exports 导出提供给其他项目使用
const myCounter = {
template: `<button v-on:click="click"> 点击次数【局部组件编程】{{ count }}</button>`,
// 这里很不一样, 记住
data() {
return {
count: 10
}
},
methods: {
click() {
this.count++;
}
}
};
let vm = new Vue({
el: "#app",
components: {
// 引入到某一个组件, 此时myCounter是一个组件, 使用范围是当前的vue
"my_counter": myCounter
}
})
</script>
细节
- 组件定义需要放置在 new Vue() 前,否则组件注册会
失败 - 组件也是一个 Vue 实例,因此它的定义是也存在∶ data、methods、生命周期函数等
- data 是一个函数,不再是一个对象, 这样每次引用组件都是独立的对象/数据
- 组件渲染需要 html 模板,所以增加了 template 属性,值就是 HTML 模板
生命周期和监听函数(钩子函数)
- Vue 实例有一个完整的生命周期,也就是说从开始创建、初始化数据、编译模板、挂载DOM、渲染-更新-渲染、卸载等一系列过程,我们称为 Vue 实例的生命周期
- 钩子函数(监听函数): Vue 实例在完整的生命周期过程中(比如设置数据监听、编译模板、将实例挂载到 DOM 、在数据变化时更新 DOM 等), 也会运行叫做生命周期钩子的函数
- 钩子函数的 作用就是
在某个阶段, 给程序员一个做某些处理的机会
- new Vue() new 了一个 Vue 的实例对象,此时就会进入组件的创建过程。
- Init Events & Lifecycle 初始化组件的事件和生命周期函数
- beforeCreate 组件创建之后遇到的第一个生命周期函数,这个阶段 data 和methods 以及dom结构都未被初始化,也就是获取不到 data 的值,
不能调用 methods 中的函数 - Init injections & reactivity 这个阶段中, 正在初始化 data 和 methods 中的方法
- created -
这个阶段组件的 data 和 methods 中的方法已初始化结束,可以访问,但是dom结构未初始化,页面未渲染- 老师说明:在这个阶段, 经常会发起 Ajax 请求
- 编译模板结构(在内存)
- beforeMount (在挂载之前) -- 当模板在内存中编译完成,此时内存中的模板结构还未渲染至页面上,看不到真实的数据
- Create vm.$el and replace ‘el’ with it 这一步,再在把内存中渲染好的模板结构替换至真实的 dom 结构也就是页面上
- mounted 此时,
页面渲染好,用户看到的是真实的页面数据, 生命周期创建阶段完毕,进入到了运行中的阶段 - 生命周期运行中
- beforeUpdate 当执行此函数,数据池的数据新的,但是页面是旧的
- Virtual DOM re-render and patch 根据最新的 data 数据,重新渲染内存中的模板结构,并把渲染好的模板结构,替换至页面上
- updated 页面已经完成了更新,此时,data 数据和页面的数据都是新的
- beforeDestroy 当执行此函数时,组件即将被销毁,但是还没有真正开始销毁,此时组件的data、methods数据或方法 还可被调用
- Teardown…… 注销组件和事件监听
- destroyed 组件已经完成了销毁
<div id="app">
<span id="num">{{num}}</span>
<button @click="num++">赞!!</button>
<h2>{{name}}, 有{{num}}次点赞</h2>
</div>
<script type="text/javascript" src="vue/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
name: "leikooo",
num: 0
},
methods: {
show() {
return this.name;
},
add() {
this.num++;
}
},
beforeCreate() {
// 生命周期函数
console.log("===beforeCreate()===")
console.log("数据模型中的数据是否加载/使用? " , this.name + " " , this.num)
// console.log("函数是否可以使用 ?", this.show())console.log("用户页面的dom是否可以使用 ?", document.getElementById("num"))
console.log("用户页面的dom是否被渲染 ?", document.getElementById("num").innerText) // {{num}} 没有成功
},
created() {
// 创建实例成功
console.log("===created()===")
console.log("数据模型中的数据是否加载/使用? " , this.name + " " , this.num)
console.log("函数是否可以使用 ?", this.show())
console.log("用户页面的dom是否可以使用 ?", document.getElementById("num"))
console.log("用户页面的dom是否被渲染 ?", document.getElementById("num").innerText) // {{num}} 没有成功
// 可以发送ajax请求
// 下面一个阶段就是vue内存模板的创建了
},
beforeMount() {
// vue实例挂载前
console.log("===beforeMount()===")
console.log("数据模型中的数据是否加载/使用? " , this.name + " " , this.num)
console.log("函数是否可以使用 ?", this.show())console.log("用户页面的dom是否可以使用 ?", document.getElementById("num"))
console.log("用户页面的dom是否被渲染 ?", document.getElementById("num").innerText) // {{num}} 没有成功
},
mounted() {
// 内存里面的数据, 替换到dom
console.log("===mounted()===")
console.log("数据模型中的数据是否加载/使用? " , this.name + " " , this.num)
console.log("函数是否可以使用 ?", this.show())console.log("用户页面的dom是否可以使用 ?", document.getElementById("num"))
console.log("用户页面的dom是否被渲染 ?", document.getElementById("num").innerText)
},
// 进入运行监听状态
beforeUpdate() {
// 数据池更新前
console.log("===beforeUpdate()===")
console.log("数据模型中的数据是否加载/使用? " , this.name + " " , this.num)
console.log("函数是否可以使用 ?", this.show())console.log("用户页面的dom是否可以使用 ?", document.getElementById("num"))
console.log("用户页面的dom是否被更新 ?", document.getElementById("num").innerText)
},
updated() {
console.log("===updated()===")
console.log("数据模型中的数据是否加载/使用? " , this.name + " " , this.num)
console.log("函数是否可以使用 ?", this.show())console.log("用户页面的dom是否可以使用 ?", document.getElementById("num"))
console.log("用户页面的dom是否更新?", document.getElementById("num").innerText)
}
})
</script>
总结
- Vue 实例生命周期是非常重要,Vue 编程模型都是建立在此基础上
- 小伙伴们一时记不住也不用急, 随着使用,会越来越深入的理解, 水到渠成
vue脚手架
传统开发的问题
- 开发效率低
- 不够规范
- 维护和升级, 可读性比较差
如何安装vueCli 直接看官方文档
没怎么看内部结构, 以后有需要在看
分析执行流程
Axios
前端模拟的json数据
{
"success": true,
"message": "成功",
"data": {
"items": [
{
"name": "牛魔王",
"age": 800
},
{
"name": "红孩儿",
"age": 500
},
{
"name": "蜈蚣精",
"age": 200
}
]
}
}
官方文档 非常官方
<table id="app" border="1px" width="200px">
<tr>
<th>名字</th>
<th>年龄</th>
</tr>
<tr v-for="monster in monsters">
<td>{{monster.name}}</td>
<td>{{monster.age}}</td>
</tr>
</table>
<script type="text/javascript" src="dependence/vue.js"></script>
<script type="text/javascript" src="dependence/axios.min.js"></script>
<script type="text/javascript">
let vm = new Vue({
el: "#app",
data: {
monsters: []
},
methods: {
list() {
axios
.get("http://localhost:63342/axios/data/response.json")
.then((response) => {
console.log(response)
console.log(JSON.stringify(response))
/** 老韩解读
* 1. 使用 axios 发送 ajax 请求
* 2. 语 法 格 式 axios. 请 求 方 式( 请求路径).then( 箭头函数).catch(箭头函数)
* 3. 请求成功,执行 then 的函数, response 就是返回的数据, 名字有程序员确定
* 4. 请求失败, 执行 catch 的函数
* 5. this.monsterList = response.data.data.items 把返回的data.items 赋给 monsterList
* 6. 这里的 http://127.0.0.1:63342/axios/response.data.json路径需要根据实际的端口和资源名来修改
*/
console.log("response", response.data.data.items)
this.monsters = response.data.data.items;
// console.log(this.monsters[0])
// 发送两次ajax请求
// return axios.get("http://localhost:63342/axios/data/response.json");
})
// .then(response => console.log("第二次请求, ", response))
// 有异常就进到catch
.catch(error => console.log(error))
}
},
created() {
//在声明周期函数里面调用
this.list();
}
})
</script>
小技巧, 到时候可以通过 JSON.stringify() 把对象转化为字符串, 使用网站 www.json.cn/ 在线查看结构, 很方便