Vue.js入门
一.Vue.js的两大核心元素 :MVVM 和 虚拟DOM
1. MVVM(model + view + viewmodel):
前端关键,之前的数据处理大部分都是在后端,前端只能通过简单的js代码实现简单逻辑(例如用户名,密码的格式的验证),通过模仿后端的MVC模式(模型,视图,控制器)方式,实现了对于大部分数据的处理,后端只需要通过传入相应的json数据即可
通过Vue.js可以真正做到,模型就是模型,视图就是视图,不包括任何的数据,让所有的模块变的纯粹
2.虚拟DOM
虚拟DOM的意思就是把一些不用经常改变的元素放入内存中,需要时直接从内存中调用即可,不用调用真实的DOM,防止访问量过多,造成服务器卡死,
具体了解真实DOM与虚拟DOM的区别:
https://www.jianshu.com/p/af0b398602bc
二.基本元素(具体使用):
前提:都引入的vue的cdn:
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
1.vue对象
每一个Vue的项目和Vue的元素都会有一个vue对象,在哪里定义的了这个对象,哪个地方就是主界面,一般都是main.js,与之后的组件有很大的关联
<script>
<!-- Model层-->
var vm = new Vue({
// el:绑定view中的视图标签的id
el: "#app",
//Model中的数据 : 数据
data:{
dataname1:"hello,vue1!",
dataname2:"hello,vue2"
},
//方法通过v-on进行事件绑定方法
methods: {
method1: function (){},
method2: function (){}
}
})
</script>
<!-- view层 模板-->
<div id="app">
<span>
<!-- 对象中的数据通过{{数据名拿到}}-->
{{dataname2}}
</span>
</div>
对象中的数据通过{{dataname}}符号拿到
viewmodel:
控制台通过改变对象的数据,改版了视图view展示的数据,中间对其进行改变的就是VM(viewModel)
2.v-if/v-else-if/v-else:
<!-- view层-->
<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>
var vm = new Vue({
el: "#app",
data: {
type: 'A'
}
})
</script>
3.v-for:
<!-- view层-->
<div id="app">
<li v-for="(item,index) in items">
{{item.message}} --- {{index}}
</li>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
//[]:表示数组; {}:表示对象
items:[
{message:"info1"},
{message:"info2"},
{message:"info3"},
]
}
})
</script>
4. v-on(简写为@):
<!-- view层-->
<div id="app">
<!-- 在button中绑定触发点击事件所调用的函数-->
<!-- 方法用 v-on标签绑定:后面加事件名-->
<button v-on:click="Hello">click Me</button>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message:"kkkkkk"
},
methods: {
//方法必须定义在Vue的methods(加s:许多方法)对象中,
Hello: function (){
alert(this.message);
}
}
})
</script>
5. v-model (双向绑定):绑定的是值
双向绑定的意思:就是通过ViewAndModel实现了,View层可以改变Model层的数据,同时Model层可以改变View层的数据
例如下拉框的使用:
逻辑: 当前的model层中的sex元素没有值,通过view视图层,选中按钮,从而改变了model(vue对象)的属性的sex的值,再通过{{}}选中对象拿到当前对象当中的值
<!-- 下拉框-->
<!-- view-->
<select name="" id="" v-model="selected">
<!-- disabled表示该项无法被选中-->
<option value="" disabled>--请选择--</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<p>选中了谁 : {{sex}}</p>
<script>
//model
var vm = new Vue({
el: "#app",
data: {
sex:""
}
})
</script>
6. v-bind(组件绑定参数,可简写为:)
通过在标签中增加v-bind标签,在标签中绑定对象当中的值,通常与组件中的props属性连用
<!-- view层 模板-->
<div id="app">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
<script>
var vm = new Vue({
el: "#app",
data:{
message:"hello,vue!"
}
})
</script>
7.组件(重要):
每一个模块都可以拆分为很多组件,组件与组件进行拼接又能成为一个模块,这样就变得耦合度低,只需要写具体的模块即可,例如:
组件component包括两个参数: 组件名字+ 组件对象{可以接受的参数(props):模板(template)}
<!-- view层-->
<div id="app">
<!-- v-bind 使用参数compont 绑定 for循环中每一个元素的参数
再通过组件中的props属性 传递给组件中模板的具体值的值-->
<mycomponent v-for="item in items" v-bind:s="item"></mycomponent>
</div>
<script>
//定义一个vue组件component
//组件component包括两个参数: 组件名字+ 组件对象{可以接受的参数(props):模板(template)}
Vue.component("mycomponent",{
//props:用于接受组件中v-bind绑定的参数
props:['s'],
template: '<li>{{s}}</li>'
});
var vm = new Vue({
el: "#app",
data: {
items: ["Java","linux","前端"]
}
});
</script>
8.Axios(异步通信)
用于测试,导入到项目中一个json文件(一般都是通过后端的controller层获取)
data.json
{
"name":"java",
"url": "http://baidu.com",
"page": "1",
"isNonProfit":"true",
"address": {
"street": "含光门",
"city":"陕西西安",
"country": "中国"
},
"links": [
{
"name": "B站",
"url": "https://www.bilibili.com/"
},
{
"name": "4399",
"url": "https://www.4399.com/"
},
{
"name": "百度",
"url": "https://www.baidu.com/"
}
]
}
<div id="vue" v-clock>
<div>{{info.name}}</div>
<div>{{info.address.street}}</div>
<!-- v-bind 用于标签上面的元素的绑定-->
<!-- 文本内容用{{}}-->
<!-- 这样无法完成属性的绑定<a href="{{info.url}}">啊啊</a> 标签中只能用v-bind绑定标签中的属性-->
<a v-bind:href="info.url">点我</a>
</div>
<script>
var vm = new Vue({
el: '#vue',
//data 表示属性: 表示vm中的数据
//data() 表示方法:但是用钩子函数进行数据的挂载时,用这个data()方法进行数据的接受
//不使用return包裹的数据会在项目的全局可见,会造成变量污染
//使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。
data(){
//return 返回的是一个json格式
return{
// 请求的返回参数格式,必须和json字符串一样
info:{
name:null,
address:{
street: null,
city: null,
country: null,
},
url:null
}
}
}
,
//mounted数据挂载的钩子函数,具体打算再写一篇钩子函数的博客
mounted(){ //钩子函数 链式编程 ES6新特性
//get表示请求的地址,then(response)表示得到返回的结果 =>指向调用结果后产生的事情
axios.get('../data.json').then(response=>(this.info=response.data));
}
})
</script>
9.计算属性(虚拟dom的实现)
计算属性:将方法计算后的结果变成了属性,属性名就是方法名,直接通过属性名调用
计算属性的实质:就是将不经常变化的结果,缓存起来,放入内存中,直接通过内存中需要时进行调用
<div id="app">
<!-- 方法必须通过()来调用-->
<p>currentTime1 {{currentTime1()}}</p>
<!-- 计算属性,通过属性名调方法名-->
<p>currentTime2 {{currentTime2}}</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message:"xxxx",
},
//methods中定义方法
methods:{
//方法名:函数(){}
currentTime1: function (){
return Date.now(); //返回一个时间戳
}
},
computed:{ //计算属性: 前提: methods和computed 方法名不能重名,重名之后只会调用method中的方法
//方法名:函数(){}
currentTime2: function (){
this.message;
return Date.now(); //返回一个时间戳
}
}
});
</script>
10. Slot(插槽):这一部分可能只有我自己能看懂
一般组件和插槽都是相互配合使用的,通过组件和插槽,可以是view视图层只展示框架,数据都是通过model层进行修改
这里的逻辑为:
这里面进行组件的组合拼接的关键在于slot,通过插槽(相当于入口),插入组件
视图层:
关注点(结合上面图片):
通过组件的slot属性,完成了组件中的插入操作,如果不标注slot的值,则无法实现组件之间的嵌套
: <=> v-bind :用于标签(这个标签表示的为组件)的属性值的绑定(从vue对象中拿到值)进行绑定,绑定到组件的props属性当中
这里也涉及到自定义事件的使用:自定义事件:这里举例是remove()删除事件
为什么使用自定义事件,原因在于:
视图层的数据是通过model层(也就是vue对象的data属性拿到的),而vue对象的数据只能通过vue对象中本身的function()实现操作,现在想通过组件完成对vue对象中数据的改变,所以就引入了自定义事件这个属性.
这里的本质实质上还是通过调用vue对象的中函数,进行对数据的改变,所以说,数据改变的具体的操作也是在vue对象的方法中定义,只是进行绑定,在组件中通过this.$emit(‘自定义时间名’,参数);进行远程的调用
具体实现代码如下:
<!-- vue的对象是通过element标签完成id的绑定-->
<!-- 组件与组件之间的绑定是通过插槽进行绑定-->
<!-- 视图层里面没有数据,数据都是通过model层中获得的-->
<div id="app">
<todo>
<!-- v-bind 这里的绑定是用来 将vue对象的属性绑定到组件的props当中,在再模板中进行调用-->
<todo-title slot="todo-title" :title="title"></todo-title>
<todo-items slot="todo-items" v-for="(item,index) in todaItems"
:item="item" :index="index" v-on:remove="removeItems(index)" ></todo-items>
<!-- remove为自定义的事件,v-on:用来绑定事件-->
</todo>
</div>
<script>
//slot标签定义插槽
Vue.component("todo", {
template:
'<div>\
<slot name="todo-title"></slot>\
<ul>\
<slot name="todo-items"></slot>\
</ul>\
</div>'
});
Vue.component("todo-title",{
props:['title'],
template: '<div>{{title}}</div>'
});
Vue.component("todo-items",{
props: ['item', 'index'],
//模板中的按钮只能绑定当前组件的方法
//v-on: <==> @ 两者等价
template: '<li>{{index}}--{{item}} <button @click="remove">删除</button></li> ',
methods: {
remove: function (index){
//模板中调用绑定的vue对象的事件,远程调用vue对象里面的方法:前提,再view中定义了自定义的方法
//$emit()第一个参数表示:在模板标签中绑定的自定义方法名,第二个参数为传递的参数
this.$emit('remove',index);
}
}
});
var vm = new Vue({
el: "#app",
data:{
title:'框框框',
todaItems: ['java','linx','运维']
},
methods: {
removeItems:function (index){
console.log("删除了"+index+this.todaItems[index]);
//this表示vue这个对象
this.todaItems.splice(index,1); //一次删除一个元素
//index表示当前元素的索引位置,1表示如果删除当前的元素,如果2则,表示删除包括当前元素在内的往后的两个元素
}
}
});
</script>