参考【狂神说Java】Vue最新快速上手教程通俗易懂 视频学习内容
Axios 是一个开源的可以用在浏览器和 NodeJS 的异步通信框架,它的主要作用就是实现 Ajax 异步请求通信。
CDN 安装方法:
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js">script>
为什么要使用 Axios?
由于 Vue.js 是一个视图层框架且作者严格遵守 SoC(关注度分离原则),所以 Vue.js 并不包含 Ajax 的通信功能。为了解决通信问题,作者单独开发了一个名为 vue-resources
的插件,不过在进入 2.0 版本之后停止了对该插件的维护,并推荐使用 Axios 框架,减少使用 JQuery 下的 Ajax 请求,因为它操作 DOM 元素过于频繁。
使用方法:
Vue.axios.get(api).then((response) => {
console.log(response.data)
})
数据准备 JSON:
{
"name": "trainingl",
"age": "22",
"sex": "男",
"url":"https://www.suda.edu.cn/",
"address": {
"street": "干将东路",
"city": "江苏省苏州市",
"country": "中国"
},
"links": [
{
"name": "Web of suda",
"url": "https://www.suda.edu.cn/"
},
{
"name": "baidu",
"url": "https://www.baidu.com"
},
{
"name": "Graduate of SUDA",
"url": "http://yjs.suda.edu.cn/"
}
]
}
测试内容:给按钮绑定一个点击事件 v-on:click="getInfo()"
,当用户点击按钮时会通过 axios 触发异步请求,请求的内容是本地的一个 JSON 数据。
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<h3>{{message}}h3>
<button v-on:click="getInfo()">获取用户信息button>
<div>{{info.name}}div>
<div>{{info.age}}div>
<div>{{info.address.country}}{{info.address.city}}{{info.address.street}}div>
<div><a v-bind:href="info.url">点我跳转a>div>
div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js">script>
<script>
var vm = new Vue({
el:"#app",
data(){
return{
message: 'Hello World',
//请求调用的返回参数格式,必须和json字符串一样
info:{
name: null,
age: null,
sex: null,
url: null,
address: {
street: null,
city: null,
country: null
}
}
}
},
methods:{
getInfo: function () {
axios
.get("./data.json")
.then(response => (this.info=response.data))
.catch(function (error) { //请求失败处理
console.log(error);
})
}
},
//钩子函数,链式编程,ES6新特性
mounted(){
//如果希望加载页面时触发异步请求,则将axios写在这里
}
})
script>
body>
html>
计算属性的重点突出在属性两个字上(属性是名词),首先它是个属性,其次这个属性有计算的能力(计算是动词),这里的计算就是个函数。简单地说,它就是一个能够将计算结果缓存起来的属性(将行为转化成立静态的属性)。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<div>currentTime1:{{currentTime1()}}div>
<div>currentTime2:{{currentTime2}}div>
div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello, World!'
},
methods:{
currentTime1: function () {
return new Date().toLocaleString(); //返回一个时间
}
},
computed: {
//计算属性:method,computed 方法名不能重名
currentTime2: function () {
this.message;
return new Date().toLocaleString();
}
}
})
script>
body>
html>
我们可以使用 methods 来替代 computed,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
结论:调用方法时,每次都需要进行计算,既然有计算过程则必然产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这一点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销。
在了解 slot 插槽之前,需要对 vue 组件基础以及传值过程有所理解。
Vue 实现了一套内容分发的 API,将
元素作为承载分发内容的出口,被称作插槽。**插槽实质是对子组件的扩展,通过
插槽向组件内部指定位置传递内容。**可以应用在组合组件的场景中。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:name="title">todo-title>
<todo-items slot="todo-items" v-for="item in todoItems" v-bind:item="item">todo-items>
todo>
div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
<script>
//slot 插槽。这个组件要定义在前面
Vue.component("todo", {
template: '\
\
\
\
\
'
});
//子组件,子组件的传值方式与组件是一样的
Vue.component('todo-title',{
//属性
props: ["name"],
template: '{{name}}'
});
Vue.component('todo-items',{
//属性
props: ["item"],
template: '{{item}} '
});
var vm = new Vue({
el:"#app",
data:{
//标题
title: "中国华东五大名校",
//列表
todoItems: ['浙江大学', '上海交通大学', '复旦大学', '南京大学', '中国科学技术大学']
}
})
script>
body>
html>
在自定义组件 todo
中声明两个 slot 插槽,然后定义两个子组件 todo-title
和 todo-items
,将这两个组件插入到这两个槽位。组件与子组件之间如果需要传递数据,就会用到 v-bind
和 props
。
我们现在如果想在 slot 插槽(子组件) 上绑定事件,比如在每个
项后增加一个删除按钮,用户点击该按钮则删除该项。由于数据项在 Vue 的实例中,但删除操作要在组件中完成,那么组件如何才能删除 Vue 实例中的数据呢?
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<todo>
<todo-title slot="todo-title" v-bind:name="title">todo-title>
<todo-items slot="todo-items" v-for="(item, index) in todoItems" v-bind:item="item" v-bind:index="index" v-on:removes="removeItem(index)">todo-items>
todo>
div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
<script>
//slot 插槽。这个组件要定义在前面
Vue.component("todo", {
template: '\
\
\
\
\
'
});
Vue.component('todo-title',{
//属性
props: ["name"],
template: '{{name}}'
});
Vue.component('todo-items',{
//属性
props: ["item", "index"],
template: '{{item}} ',
methods: {
remove: function (index) {
//this.$emit 自定义事件分发
this.$emit('removes', index)
}
}
});
var vm = new Vue({
el:"#app",
data:{
//标题
title: "中国华东五大名校",
//列表
todoItems: ['浙江大学', '上海交通大学', '复旦大学', '南京大学', '中国科学技术大学']
},
methods: {
removeItem: function (index) {
console.log("删除了"+this.todoItems[index]+"OK");
this.todoItems.splice(index,1);
}
}
})
script>
body>
html>
下面我们分析一下上面的执行过程:
首先,我们给每个列表项增加一个按钮并绑定点击事件 '
,在该子组件 todo-items 的 methods 方法中进行事件分发 this.$emit('自定义事件名', 参数)
。
methods: {
remove: function (index) {
//this.$emit 自定义事件分发
this.$emit('removes', index)
}
}
将该事件分发到上层处理 v-on:removes="removeItem(index)"
,最后调用 Vue 实例 methods
属性中定义的方法完成。
methods: {
removeItem: function (index) {
console.log("删除了"+this.todoItems[index]+"OK");
this.todoItems.splice(index,1);
}
}
注:this.todoItems.splice(index, len)
是 JavaScript 的数组内置方法,表示从数组某一个索引开始,向后删除 len 个元素。