VueVue入门--双向绑定,Vue的组件,Axios异步通信,计算属性,插值,自定义事件
Posted a碟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VueVue入门--双向绑定,Vue的组件,Axios异步通信,计算属性,插值,自定义事件相关的知识,希望对你有一定的参考价值。
目录
1.Vue双向绑定
Vue.js是一个MVVM框架,即数据双向绑定,即当数据发生变化的时候,视图也就发生变化,当视图发生变化的时候,数据也会同步变化。这就是Vue.js的精髓之处了。
可以使用v-model
指令在表单<input>
,<textarea>
以及<select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方式来更新元素。
注意:v-model会忽略所有表单元素的value,checked,selected特性的初始值而总是将Vue实例的数据作为数据来源。应该通过js在组件的data选项中生命初始值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
输入的文本:<input type="text" v-model="message">{{message}}
</div>
<!-- 1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:{
message: "123"
},
});
</script>
</body>
</html>
我们在更新文本框的时候,后面的message也能实现同步的更新,是因为我们实现了双向绑定
单选框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="radio" name="sex" v-model="checked" value="男">男
<input type="radio" name="sex" v-model="checked" value="女">女
<p>
选中了:{{checked}}
</p>
</div>
<!-- 1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:{
checked:'女'
},
});
</script>
</body>
</html>
下拉框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<select v-model="selected">
<option value="" disabled>--请选择--</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<p>
选中了:{{selected}}
</p>
</div>
<!-- 1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:{
selected:''
},
});
</script>
</body>
</html>
2.Vue的组件
组件是可复用的Vue
实例,就是一组可以重复使用的模板,就跟JSTL的自定义标签,Thymeleaf的th:fragment
等框架有着异曲同工之妙。通常一个应用会以一颗嵌套的组件树的形式来组织
例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- v-for遍历了items中的每一项,取出来了值,然后可以在自定义组件中访问这个值it-->
<adie v-for="item in items" v-bind:it="item"></adie>
</div>
<!-- 1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
Vue.component("adie",{
//在这里接收了参数it,it和上面的绑定了
props: ['it'],
template: '<li>{{it}}</li>'
});
var vm=new Vue({
el: "#app",
data:{
items:["java","linux","前端"]
}
})
</script>
</body>
</html>
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。为了给博文组件传递一个标题,我们可以用一个 props
选项将其包含在该组件可接受的 prop 列表中:
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data
中的值一样。
当prop被注册后,可以这样把数据作为一个自定义attribute传递进来。
<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>
此外,可能在data中有一个博文的数组
new Vue({
el: '#blog-post-demo',
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
]
}
})
并想要为每篇博文渲染一个组件:
<blog-post
v-for="post in posts"
v-bind:title="post.title"
></blog-post>
我们可以使用 v-bind
来动态传递 prop
3.Axios异步通信
3.1.什么是Axios
Axios是一个开源的可以用在浏览器端和Node JS
的异步通信框架, 主要作用就是实现AJAX异步通信,其功能特点如下:
- 从浏览器中创建
XMLHttpRequests
- 从node.js创建http请求
- 支持Promise API[JS中链式编程]
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF(跨站请求伪造)
GitHub:https://github.com/axios/axios
中文文档:http://www.axios-js.com/
3.2.为什么要使用Axios
由于Vue.js
是一个视图层框架并且作者(尤雨溪) 严格准守SoC(关注度分离原则)所以Vue.js
并不包含AJAX的通信功能, 为了解决通信问题,作者单独开发了一个名为vue-resource
的插件, 不过在进入2.0版本以后停止了对该插件的维护并推荐了Axios
框架。少用jQuery, 因为它操作Dom太频繁。
3.3.第一个Axios应用程序
因为接口大部分都是json格式的数据,所以我们模拟一个json格式的数据用来测试 data.json
{
"name": "a碟",
"url": "https://blog.csdn.net/ladiez",
"page": 1,
"isNonProfit": true,
"address": {
"street": "人民东路",
"city": "湖南",
"country": "中国"
},
"links": [
{
"name": "bilibili",
"url": "https://blog.csdn.net/ladiez"
},
{
"name": "blog",
"url": "https://blog.csdn.net/ladiez"
},
{
"name": "百度",
"url": "https://blog.csdn.net/ladiez"
}
]
}
测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- v-clock解决闪烁问题-->
<style>
[v-clock]{
display: none;
}
</style>
</head>
<body>
<div id="app" v-clock>
<div>{{info.name}}</div>
<a v-bind:href="info.url">点击</a>
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm=new Vue({
el: "#app",
//data 属性:vm
//方法
data(){
// 请求的返回参数格式,必须和json字符串一样
return{
info:{
//里面也可以不写
name:null,
address:{
street:null,
city:null,
country:null
},
utl:null,
}
}
},
mounted(){ // 钩子函数 链式编程 ES6新特性
axios.get('../data.json').then(response=>(this.info=response.data))
}
})
</script>
</body>
</html>
说明:
- 在这里使用了v-bind将a:href的属性值与Vue实例中的数据进行绑定
- 使用axios框架的get方法请求AJAX并自动将数据封装进了Vue实例的数据对象中
- 我们在data中的数据结构必须和
Ajax
响应回来的数据格式匹配
4.Vue的生命周期
https://cn.vuejs.org/v2/guide/instance.html#生命周期图示
Vue实例有一个完整的生命周期,也就是从开始创建初始化数据、编译模板、挂载DOM、渲染一更新一渲染、卸载等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。
在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册JS方法,可以让我们用自己注册的JS方法控制整个大局,在这些事件响应方法中的this直接指向的是Vue的实例。
5.计算属性
计算属性的重点突出在属性
两个字上(属性是名词),首先它是个属性
其次这个属性有计算
的能力(计算是动词),这里的计算
就是个函数:简单点说,它就是一个能够将计算结果缓存起来的属性(将行为转化成了静态的属性),仅此而已;可以想象为缓存,节约开销。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<p>currentTime1 {{currentTime1()}}</p>
<p>currentTime2 {{currentTime2}}</p>
</div>
<!-- 1.导入Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
var vm = new Vue({
el:"#app",
data:{
message:"hello,adie"
},
methods:{
currentTime1:function () {
return Date.now();//返回一个时间戳
},
},
computed:{//计算属性:methods和computed方法名不能重名,重名之后只会调用methods的方法
currentTime2:function () {
this.message // 数据存在了缓存中,只有当当前数据发生了改变才会再次调用方法
return Date.now();//返回一个时间戳
}
}
});
</script>
</body>
</html>
可以看到上述案例,同样是返回一个时间戳的currentTime1和currentTime2。在浏览器中我们并没有发现有什么区别。但是如果我们在控制台中输出vm.message='a碟'
.见以下案例
- methods:定义方法, 调用方法使用currentTime1(), 需要带括号
- computed:定义计算属性, 调用属性使用currentTime2, 不需要带括号:this.message是为了能够让currentTime2观察到数据变化而变化
- 只要方法中的值发生了变化,则缓存就会刷新。可以在控制台使用
vm.message=”a碟"
, 改变下数据的值,可以看到上面的效果
结论:
调用方法时,每次都需要讲行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;
6.插槽
插槽的用法很多,详细的了解可以前往官网查看。
在Vue.js
中我们使用<slot>
元素作为承载分发内容的出口,作者称其为插槽,可以应用在组合组件的场景中。
实例
比如准备制作一个待办事项组件(todo) ,该组件由待办标题(todo-title) 和**待办内容(todo-items)**组成,但这三个组件又是相互独立的,该如何操作呢?
1.定义一个待办事项的组件
我们需要让待办事项的标题和值实现动态绑定,所以在代码中留出来了一个插槽,即slot
因为我们有时需要多个插槽,对于这种情况,<slot>
有一个特殊的attribute:name
。这个attribute可以用来定义额外的插槽。
一个不带 name
的 <slot>
出口会带有隐含的名字“default”。
Vue.component("todo",{
template: '<div>\\
<slot name="a"></slot>\\
<ul>\\
<slot name="b"></slot>\\
</ul>\\
</div>'
});
2.定义一个名为todo-title的待办事项标题和todo-items待办事项内容
Vue.component("todo-title",{
props: ['title'],
template: '<div>{{title}}</div>'
})
Vue.component("todo-items",{
props: ['item'],
template: '<li>{{item}}</li>'
})
3.实例Vue并初始化内容
var vm = new Vue({
el:"#app",
data:{
Title: "a碟",
todoItems: [
'Java',
'Linux',
'Python'
]
}
});
4.将这些值通过插槽传入
在向具名插槽提供内容的时候,我们可以在一个 <template>
元素上使用 v-slot
指令,并以 v-slot
的参数的形式提供其名称
现在 <template>
元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot
的 <template>
中的内容都会被视为默认插槽的内容。
注意 ** v-slot
只能添加在 <template>
上 ** (只有一种例外情况)
我在官网了解到以上template是最新的使用方法。而我学习时使用的方法好像是废弃的。下面是官网提供的最新的使用方法
<div id="app">
<todo>
<template v-slot:a>
<todo-title v-bind:titleVueVue中单向绑定与双向绑定的理解与使用