个人博客:http://blog.kunpw.cn:9000/
Vue
1.简介
1.1 概念介绍
Vue 是一款渐进式JavaScript框架,所谓渐进式就是逐步实现新特性的意思,如实现模块化开发、路由、状态管理等新特性。其特点是综合了Angular(模块化)和React(虚拟DOM)的优点,与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库(如: vue-router,vue-resource,vuex)或既有项目整合。
1.2 MVVM
Model:模型层,在这里表示JavaScript对象;View:视图层,在这里表示DOM(HTML 操作的元素);ViewModel:连接视图和数据的中间件,Vue.js 就是MVVM中的ViewModel层的实现者
View层展现的不是Model层的数据,而是ViewModel的数据,由ViewNodel负责与 Model层交互,这就完全解耦了View层和Model层,这个解耦是至关重要的,它是前后端分离方案实施的重要一环。
1.3 搭配环境
下载vue.js文件:
https://vuejs.org/js/vue.jshttps://vuejs.org/js/vue.min.js上面一个是全包,下面一个是简化包,代码中引用一个就OK
如果不下载到本地,可以使用cdn外部引入:
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js"></script>
再在IDEA中 settings->plugins中搜索安装vue.js:
安装之后重启再设置下一步:
附模板:
<template>
</template>
<script>
export default {
name:"${NAME}"
}
</script>
<style scoped>
</style>
注:上图与模板代码取自博客:https://blog.csdn.net/jdq8576/article/details/104055707/
然后就可以在IDEA文件中new一个Vue Component文件啦!
2.基础语法
2.1 初步使用
<div id="app">
{{message}}
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
message:"hello,vue!"
}
});
vm.message = 'hello zhaoxiaoan'
>"hello zhaoxiaoan"
</script>
Vue常用的七个属性:
el :占位符,用来绑定标签、id和class,指示编译器解析;data :存放数据区域;methods :存放方法逻辑区域;render :创建Virtual Domcomputed :用于计算watch :
watch:function(new,old){};监听data中数据的变化; template :用来设置模板,替换页面元素,包括占位符;
2.2 v-bind指令
该指令的含义是绑定信息,如 v-bind:title="massage" 就是绑定了标题信息,将鼠标移动到标签语句悬停可显示其绑定信息;v-bind:可以简写为 : ;
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<div id="app">
<span v-bind:title="massage">
鼠标悬停几秒查看此处绑定的信息
</span>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
massage:"hello,vue"
}
});
</script>
2.3 if判断语句
<div id="app">
<h1 v-if="type==='A'">A
</h1>
<h1 v-else-if="type==='B'">B
</h1>
<h1 v-else>C
</h1>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
type:"A"
}
});
</script>
2. 4 循环列表(重要)
列表配合for循环就可以简单实现从数据库中导出数据并且循环输出成列表展示;
<div id="app">
<li v-for="item in items">
{{item.message}}
</li>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
items: [
{message:"hello,vue"},
{message:"hello zhaoxiaoan"}
]
}
});
</script>
2.5 v-on 绑定事件
v-on: 用来绑定事件,如事件click ,其余事件可以查找jQuery事件文档(可以自己创建新事件);v-on:可以简写为 @ ;
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<div id="app">
<button v-on:click = "sayHi">Click Me
</button>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
message: "hello,vue!"
},
methods: {
sayHi:function (envent) {
alert(this.message);
}
}
});
</script>
3.双向绑定(重点)
使用v-model指令;v-model指令会忽略所有表单元素的checked、selected等值,因此在下拉框中初始默认选择为空,必须设置一个disabled不可选中项并且设置其值为空来作为默认选择域;
3.1 文本
本质是{{message}}用来绑定data{message}显示内容,而message又通过v-model="message"绑定了文本域,所以当输入框值域变化时修改了data{message}数据,接着message就跟着变化;
<div id="app">
输入的文本:
<input type="text" v-model="message">
{{message}}
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
message: "hello,vue!"
},
});
</script>
3.2 textarea文本域
<div id="app">
输入的文本:
<textarea v-model="message"></textarea>>
{{message}}
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
message: "hello,vue!"
},
});
</script>
3.3 radio单选框
<div id="app">
性别:
<input type="radio" name="sex" value="男" v-model="message">男
<input type="radio" name="sex" value="女" v-model="message">女
<p></p>
{{message}}
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
message: ""
},
});
</script>
3.4 select下拉框
<div id="app">
下拉框:
<select v-model="message">
<option value="" disabled >--请选择--
</option>
<option>A
</option>
<option>B
</option>
<option>C
</option>
</select>
<p>选择了:{{message}}
</p>
</div>
<script src="../lib/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
message: ""
},
});
</script>
4.组件
组件最大的作用就是其良好的复用性,但是复用性的本质只能复用框架外围,内在的本质数据必须从另一方获取,接下来讲述的就是获取数据的过程;
4.1 新建component组件
给新组件命名为zhaoxiaoan;template为替换的模板内容;
Vue
.component("zhaoxiaoan",{
template
: '<li>Hello</li>'
})
let vm
= new Vue({
el
: "#app",
data
: {
items
: ["Java","Linux","前端"]
},
});
4.2 使用新组件
从绑好的Data中遍历取出数据;并且使用v-bind:itemX绑定新变量itemX,并且将v-for遍历得到的数据赋值给新变量
<div id="app">
<zhaoxiaoan v-for="item in items" v-bind:itemX="item"></zhaoxiaoan>
</div>
4.3 将数据传入新组件
使用属性props接收新参数itemX此参数就是v-bind新定义并且绑定的那个变量,最终这个新变量传递给template模板中的itemX;
Vue
.component("zhaoxiaoan",{
props
:['itemX'],
template
: '<li>{{itemX}}</li>'
})
最终代码与运行结果如下:
<div id="app">
<zhaoxiaoan v-for="item in items" v-bind:item="item"></zhaoxiaoan>
</div>
<script src="../lib/vue.js"></script>
<script>
Vue.component("zhaoxiaoan",{
props:['item'],
template: '<li>{{item}}</li>'
})
let vm = new Vue({
el: "#app",
data: {
items: ["Java","Linux","前端"]
},
});
</script>
5.Axios异步网络通信
5.1 Axios简介
Axios是一个开源的可以用在浏览器端和 Node3S 的异步通信框架,它的主要作用就是实现 AJAX异步通信,其功能特点如下:
从浏览器中创建 XMLHttpRequests从 node.js 创建http请求支持 Promise API [JS中链式编程]拦截请求和响应转换请求数据和响应数据取消请求自动转换 JSON 数据客户端支持防御 XSRF(跨站请求伪造)
由于Vue.js是一个视图层框架并且作者(尤雨溪)严格准守SoC(关注度分离原则),所以Vue.js并不包含AJAX的通信功能,为了解决通信问题,作者单独开发了一个名为vue-resource的插件,不过在进入2.0版本以后停止了对该插件的维护并推荐了Axios框架。少用jQuery,因为它操作Dom太频繁
5.2 Vue实例生命周期图示介绍
这是一个Vue实例生命周期,在生命周期过程中会执行相应的“钩子函数”,这些“钩子函数”是可以被外部调用进而影响到整个实例的;
5.3 引入Axios
外部cdn引入:
<script src="https://unpkg.com/axios/dist/axios.min.js "></script>
官方文档安装Axios:
http://www.axios-js.com/zh-cn/docs/vue-axios.html
5.4 模拟网络通信
开发的接口大部分使用JSON格式,先在项目里模拟一段JSON数据:
创建一个新文件命名为data.json ,数据如下:
{
"name":"狂神说Java" ,
"url":"https://blog.kuangstudy.com",
"page": 1,
"isNonProfit": true,
"address": {
"street":"含光门",
"city":"陕西西安",
"country" :"中国"
},
"links" :[
{
"name": "bilibili",
"url": "https://space.bilibili.com/95256449"
},
{
"name": "狂伸说java",
"url": "https://blog.kuangstudy.com"
},
{
"name":"百度",
"url": "https://www.baidu.com/"
}
]
}
html文件代码如下:
先写mounted()函数,在这个钩子函数中调用axios.get()获取json文件数据;
response
=>(this.info
=response
.data
)
再通过双向绑定在html中引用data属性的数值;
对于链接标签中链接的动态生成,则使用v-bind指令将href属性的值绑定为info.url,不能直接将info.url传递给href,否则只能识别为一串字符串;
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title
</title>
</head>
<body>
<div id="vue">
<div>{{info.name}}
</div>
<div>{{info.address.street}}
</div>
<a v-bind:href="info.url">click
</a>
</div>
<script src="../lib/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var vm = new Vue({
el: "#vue" ,
data(){
return{
info: {
name: null,
address: {
street: null,
city: null,
country: null
},
url:null
}
}
},
mounted(){
axios.get("../data.json").then(response=>(this.info=response.data));
}
});
</script>
</body>
</html>
json文件在编码时没有使用UTF-8编译,所以上述请求执行后会得到乱码内容,解决方法是将json文件用notepad++打开之后在视窗栏 编码->使用UTF-8编码和转为UTF-8编码;
6.计算属性
存在于computed属性中;
methods与computed属性中的函数名不能重名,否则优先调用methods中的函数而不会调用computed中的属性(定义为函数,调用为属性);
调用方法时,每次都需要进行计算,既然有计算过程则必定产生系统开销,那如果这个结果是不经常变化的呢?此时就可以考虑将这个结果缓存起来,采用计算属性可以很方便的做到这一点,计算属性的主要特性就是为了将不经常变化的计算结果进行缓存,以节约我们的系统开销;
computed属性中的缓存只在数据发生增删改之后才会重新刷新变化,而methods内的函数随时变化;
<div id="app">
<p>currentTime1 {{currentTime1()}}
</p>
<p>currentTime2 {{currentTime2}}
</p>
</div>
<script src="../lib/vue.js"></script>
<script>
var vm = new Vue({
el: "#app" ,
data: {
message: "hello,world"
},
methods:{
currentTime1:function () {
return Date.now();
}
},
computed:{
currentTime2:function () {
this.message;
return Date.now();
}
}
});
</script>
7.插槽slot
插槽的本质就是嵌套组合复用;
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-item" v-for="item in todoItems" :item="item"></todo-items>
</todo>
</div>
<script src="../lib/vue.js"></script>
<script>
Vue.component("todo",{
template: '<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-item"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props:["title"],
template: '<div>{{title}}</div>'
});
Vue.component("todo-items",{
props:["item"],
template: '<li>{{item}}</li>'
});
var vm = new Vue({
el: "#app" ,
data:{
title: "学习篇",
todoItems:["Java","Linux","前端"]
}
});
</script>
8.自定义事件分发
实现在slot基础上的自定义删除事件;具体问题及解决方式:
component组件中定义事件函数,但是并不能直接修改vue实例内容
间接,在vue实例中定义函数事件用于删除data数据内容;将该事件removeItem 通过 v-on 绑定到自定义事件 remove 上;再在component组件中通过this.$emit('remove',index)自定义事件分发传参并调用自定义事件remove;
<div id="app">
<todo>
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-item" v-for="(item,index) in todoItems"
:item="item" :index="index" @remove="removeItem(index)" ></todo-items>
</todo>
</div>
<script src="../lib/vue.js"></script>
<script>
Vue.component("todo",{
template: '<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-item"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props:["title"],
template: '<div>{{title}}</div>'
});
Vue.component("todo-items",{
props:["item","index"],
template: '<li>--{{index}}--{{item}} <button @click="remove(index)">删除</button></li>',
methods:{
remove: function (index) {
this.$emit('remove',index);
}
}
});
var vm = new Vue({
el: "#app" ,
data:{
title: "学习篇",
todoItems:["Java","Linux","前端"]
},
methods:{
removeItem:function (index) {
this.todoItems.splice(index,1);
}
}
});
</script>
点击删除按钮能够动态删除data数据并且刷新页面显示:
关系示意图:最终都是通过前端的view视图来连接
从Typora直接导入的文件,可能会有误差,这里导出图片,可以对照: