vue.js解析学习
vue.j
Vue概述:
MVX模式简介,Vue框架简介,Vue.js的安装与使用。
Vue基础语法:
实例对象,生命周期,模板语法,计算属性,methods方法
Vue渲染:
列表渲染,条件渲染
Vue事件与表单:
事件处理,事件对象,事件委派,表单处理
MVX模式简介:
MVX框架模式:MVC+MVP+MVVM
MVC:
Model模型+View视图+Controller控制器
View通过Controller和Model联系,Controller是View和Model的协调者,View和Model不直接联系。用户通过控制器Controller来操作模板从而达到视图view的变化。
MVP是通过MVC模式演变而来,都是通过Controller/Persenter负责逻辑的处理+Model提供数据+View负责显示。
MVC为View,Controller,Model三部分。
MVP理解:
Presenter包含UI的处理逻辑,负责与View和model通讯,Model为数据和数据的处理逻辑,只能与Persenter通讯,View负责呈现只能与Persenter通讯
MVVM组成:
View,展示UI,Model为数据模型,ViewModel视图模型负责绑定控制视图,使之Model与View关联,同时降低耦合。
MVC模式和MVVM模式
移动端应用广泛软件架构之一的模式:MVC模式。MVC模式分为三部分,Model模型,View视图,Controller控制器,MVC模式的过程。
将View层展示给用户,通过HTML页面接收用户动作,将指令传递给Controller,触发的业务传递给Controller,Controller完成业务逻辑。
MVC模式执行过程:
MVVM模式:
MVVM模式是将MVC模式的Controller改成ViewModel。view的变化会自动更新ViewModel,ViewModel的变化也会自动变化到View层。
view是用来接收用户请求的,model是处理数据的,不再与view层进行交互数据,viewmodel监听view层请求的变化,ViewModel和Model层之间进行数据双向绑定,Model层监听ViewModel的变化。
MVC模式和MVVM模式的区别:
MVC模式,数据是单向的,由view->Controller->Model->View方向循环,而在MVVM模式中,数据是可以双向通信,核心是ViewModel对象。
Vue.js是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不同的是,Vue设计为可以自底向上逐层应用,Vue的核心库只关注视图层。
目录结构:
build:项目构建相关代码
config:配置目录,包括端口号等
mode_modules:npm加载的项目依赖模块
src:
assets:放置一些图片,components:目录里面放了一些组件文件,App.vue项目入口文件,main.js:项目的核心文件。
static:静态资源目录
test:初始测试目录
index.html:首页入口文件
package.json:项目配置文件
Vue框架简介:
Vue是一套构建用户界面的渐进式框架,Vue只关注视图层,采用自底向上增量开发的设计,Vue的目标是通过API实现数据绑定和组合视图组件。
Vue框架的好处:
数据绑定,指令,轻量级,插件化。
Vue掌握Vue基础知识,Vue框架基础语法,Vue开发工具,Vue组件,Vue模块化开发,Vue工程工具,npm/yarn和webpack开发工具,Vue CLI开发工具,Express服务器开发和axios网络请求,创建Express应用程序,axios发送AJAX请求,Postman插件,Vue路由,单页面应用SPA,vue-router实现路由机制,Vuex状态管理,本地存储,Vue UI库,Vue中的UI库。
三大主流框架:
主流的MVVM框架有Angular,React和Vue.js。
Angular是谷歌推出的MVVM框架,功能强大,含有模板,数据双向绑定,路由,模块化,服务,自带了丰富的Angular指令,由谷歌维护。React是由Facebook推出的JavaScript库,Vue.js是于2014年开发的MVVM框架。
vue.js的安装
vue.js的下载地址为
https://vuejs.org/js/vue.js
安装地址:
https://cn.vuejs.org/v2/guide/installation.html
一为:在vue.js的官网上直接下载vue.min.js并用<script>标签引入。
二为:利用CDN方式引入Vue.js文件。
Vue地址:
https://unpkg.com/vue
利用npm和webpack模块包形式引入Vue.js文件
创建一个Vue实例:
引入CDN文件,创建Vue实例对象,在HTML文件中添加关联Vue实例对象。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>第一个Vue实例</title>
<script type="text/javascript"></script>
</head>
<body>
<div id="app">
name={{name}}
</div>
<script src="https://unpkg.com/vue"></script>
<script>
// 创建一个Vue实例对象
var vm = new Vue({
el: '#app', // el绑定的id为app的div元素
data: {
name: 'vue'
}
});
</script>
</body>
</html>
Vue框架开发工具
开发文档:
vue地址:
https://cn.vuejs.org/v2/guide
npm地址:
https://www.kancloud.cn/shellway/npm-doc
webpack地址:
https://doc.webpack-china.org//concepts/
浏览器:
Chrome浏览器
vue-devtools调式工具
代码工具:
atom,sublime text,visual studio code
基础语法:
vue实例对象是vue框架的核心
什么是vue实例对象,vue框架的核心是vue实例对象,即是viewmodel对象,vue实例对象是连接view视图层和model模型层,核心是viewmodel对象。
view层执行一个数据的双向绑定,view触发后告诉viewmodel对象的dom listeners事件的监听机制,从而更新model层中的数据,当model层中的数据发生变化后,交给数据双向绑定机制,也会告诉view层要更新数据。
vue实例对象的语法:
var vm = new Vue({});
1
<body>
<div id="app">
name=={{name}}
</div>
<script src="https://unpkg.com/vue"></script>
<script>
// 创建一个vue实例对象
var vm = new Vue({
// 绑定的dom元素
el: '#app',
data: {
// 双向数据绑定机制
name: 'da'
}
});
console.log(vm); // 包含一系列属性
</script>
</body>
</html>
生命周期
vue生命周期是vue实例对象衍生的一个机制,生命周期是vue实例对象创建过程中所实现的回调函数,可以在回调函数中写代码,去实现一些所要的功能。
具体的回调函数:
beforeCreate()
vue实例对象创建之前
created()
vue实例对象创建之后
beforeMount()
vue实例对象和文档节点挂载之前
mounted()
vue实例对象和文档节点挂载之后
beforeUpdate()
view视图更新之前
beforeUpdate()
view视图更新之前
updated()
view视图更新之后
beforeDestroy()
vue实例对象销毁之前
destroyed()
vue实例对象销毁之后
beforeCreate()和created()
vue创建实例对象:
阶段一,初始化事件绑定机制,初始化生命周期的循环,初始化后触发beforeCreate()回调函数。
阶段二,初始化注入器,初始化实体对象,此刻vue实例对象已创建完成,初始化后触发created()回调函数。
beforeCreate():
Vue实例对象创建之前的回调,此时的el属性和data属性为空。
created():
Vue实例对象创建后的回调,此时的el属性为空,data属性已经存在。
<body>
<div id="app">
name=={{name}}
</div>
<script src="https://unpkg.com/vue"></script>
<script>
var vm = new Vue({
el: '#app',
data:{
name: 'da'
},
// 生命周期回调函数
beforeCreate:function(){
//vue实例对象创建之前的回调
console.log('beforeCreate');
console.log(this.$el); // undefined
console.log(this.$data);
},
created:function(){
// vue实例对象创建之后的回调
console.log('created');
console.log(this.$el); // undefined
console.log(this.$data);
}
});
</script>
</body>
beforeMount()和mounted()
创建el属性前先执行beforeMount()回调函数,接着创建el属性同dom进行绑定后,触发mounted()回调函数。
beforeMount():
view和model绑定完成之前,在vue实例对象和文档节点挂载前,此时el属性为绑定之前的值。
mounted():
view和model绑定完成后的回调,在vue实例对象和文档节点挂载后,此时是el属性绑定后的值。
<div id="app">
name=={{name}}
</div>
<script src="https://unpkg.com/vue"></script>
<script>
var vm = new Vue({
el: '#app',
data:{
name: 'da'
},
// 生命周期回调函数
beforeMount:function(){
console.log('beforeMount');
console.log(this.$el.innerHTML);
},
mounted:function(){
console.log('mounted');
console.log(this.$el.innerHTML);
}
});
</script>
</body>
beforeMount:
name=={{name}}
Mounted:
name==da
beforeUpdate()和updated()
beforeUpdate():
view视图更新之前的回调,el属性为更新前的值。
updated():
view视图更新之后的回调,el属性为更新之后的值。
beforeDestroy()和destroyed()
beforeDestroy():
vue实例对象销毁之前的回调,el属性和data属性仍然具有原始值。
destroyed():
vue实例对象销毁之后的回调,el属性和data属性仍然具有原始值,但是后面再次修改model,就不会改变view了。
模板语法
格式:
name = {{name}}
user.name = {{user.name}}
{{name[0]}}
var data={
name: 'da',
user: {
name: 'da',
age: 2
},
names: ['d','a'],
}
var vm = new Vue{(
el:'#app',
data: data
});
<div>
{{html}}
</div>
<div v-html="html"></div>
<script>
// 双向
var data={
html: '<font color="red">da</font>'
}
var vm = new Vue{(
el:'#app',
data: data
});
v-bind:href="link.link"
:href="link.link"
{{link.name}}
{{link.name}}
{{5+5}}
{{ok?'yes':'no'}}
{{message.split('').reverse().join('')}}
v-bind:id="'list='+id"
var data={
ok: true,
message: 'dada',
id: 1
}
计算属性
为什么要使用计算属性,它是用来计算简单的运算。不能有太多的处理逻辑,会让模板复杂,难以维护。
<div id="app">
<div>
{{amount}}
</div>
</div>
var data={
count: 5,
price: 10,
discount: 0.8,
freight: 5
}
// 计算属性
computed:{
// 每个计算属性值是函数形式,并且有返回值
amount: function() {
// this表示当前vue实例对象
// this.$data 表示当前vue实例对象装载的双向绑定数据
// 代理
// this.$data.count <=> this.count
return this.$data.count * this.$data.price*this.$data.discount;
}
}
computed属性是由一系列json方法组成,表示一系列计算属性
每个计算属性是一个function,并定义了一个函数,这个函数必须由return语句返回计算属性的返回值。
与v-html相比,只是定义的形式不同而已,计算属性和data属性的操作一致。
<div>
<span v-html="amount"></span>
</div>
computed: {
amount: function() {
return '<span>' + this.$data.count*this.$data.price + '</span>';
}
}
method方法
methods方法由一系列json方法组成。
methods: {
// 方法,函数,返回值
getNum: function() {
return this.$data.count;
}
}
<div>
{{getNum()}}
</div>
计算属性和methods方法的区别
本质区别:
计算属性是再其依赖的关系上,如果依赖发送改变才会重新计算,就是说依赖的data数据发生改变时,才会重新计算。
methods方法无论其依赖的data数据是否发生改变,每一次调用都会重新计算。
vue渲染
数组元素和对象元素渲染
// v-for指令循环一组相同格式的数据
v-for="item in items"
v-for=(item, index) in items
<ul>
<li v-for="(goods,index) in goodslist">
{{index+1}}-{{goods.name}}
</li>
</ul>
v-for指令可以渲染数据元素,也可以渲染JavaScript对象:
(value, key, index) in object
<ul>
<li v-for="goods in goodslist">
<ul>
<li v-for="(value,key,index) in goods">
{{key}}-{{value}}
</li>
</ul>
</li>
</ul>
计算属性与列表渲染
<li v-for="goods in filterGoodslist">
{{goods.name}}==={{goods.price}}
</li>
var vm = new Vue ({
el: '#app',
data: {
goodslist: {
{name: 'iphone', price: '9999'},
}
},
computed: {
filterGoodslist: function(){
// 渲染filter时一个数组方法,需要接收一个回调函数
return this.goodslist.filter(function(goods){
return goods.price > 50000;
});
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue数组更新</title>
<script type="text/javascript"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
list: ['1','2','3']
}
});
</script>
</body>
</html>
如何修改数组的元素?
第一种方法:使用Vue.set()或vm对象.$set()形式修改数组元素
第二种方法:使用数组变异方法修改数组元素
Vue.set(vm.list, 0 '10')
"10"
vm.$set(vm.list, 0, '20')
"20"
数组变异方法:
改变原始数组内容的方法,就是JavaScript的基本内容。
数组变异方法:
push(),pop(),unshift(),shift()
sort(),reverse()
splice()
push():
在数组元素末尾添加元素
pop():
在数组元素末尾删除元素
vm.list.pop() // 数组元素末尾删除
vm.list.push('m4') // 数组元素末尾添加元素
unshift()
在数组元素开头添加元素
shift()
在数组元素开头删除元素
vm.list.unshift('da')
vm.list.shift()
sort()
对数组元素进行排序
reserve()
对数组元素进行翻转
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue-排序</title>
<script type="text/javascript"></script>
</head>
<body>
<div id="app">
<h2>达达前端</h2>
<div>
<ul>
<li v-for="item in users">
{{item.name}}-{{item.age}}
</li>
</ul>
</ul>
</div>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
users: {
{name:'da',age:1},
{name:'dada',age:2},
}
}
});
</script>
</body>
</html>
vm.users.sort(function(a,b){return a.age-b.age})
1
添加或删除数组多个元素
splice():
添加或删除数组多个元素
vm.list.splice(3,0,'23') // 添加
[]
vm.list.splice(1,1) // 删除
{'da'}
splice从数组种删除元素,array.splice
删除位置下标,删除元素个数
splice向数组种添加元素,array.splice
添加位置下标,0, 待添加的元素
条件渲染
v-if指令和v-show指令
判断是否登录:
<body>
<div id="app">
<div>
<div v-if="isLogined==true">
欢迎你
</div>
<div v-else>
<a href="#">登录</a>
</div>
</div>
</div>
....
<script>
var vm = new Vue({
el: '#app',
data: {
// 用户没有处于登录状态
isLogined: false
}
});
</script>
v-if,v-else-if,v-else指令
v-for指令具有更高的优先级,比v-if,注意这里如果两者合用,那么v-if只是重复循环而已。
template标签,既是一个整体,又是一个模板,template没有实际意义。
如何让v-if指令优先于v-for指令呢?
<template v-if="users.length>1">
<ul>
<li v-for="item in user">
...
</li>
</ul>
</template>
v-if指令在查看浏览器中,HTML的元素的,为否,而v-show指令在div的样式中: display:none。v-show指令式切换渲染css属性的display,v-if指令决定是否生成dom渲染元素。
vue事件和表单
事件处理的语法格式:
v-on:事件名,@事件名绑定事件处理函数,可用的事件,两大类分别为鼠标事件和键盘事件。
<button v-on:click="count += 1">+1</button>
<button @click="count -= 1">-1</button>
count={{count}}
var vm = new Vue({
el: '#app',
data: {
count: 0
}
});
// 或者
methods: {
increment: function() {
}
}
鼠标事件:
click鼠标单击
dbclick鼠标双击
mouseover鼠标经过
mouseout鼠标移开
键盘事件
keydown:
键盘按下
keyup:
键盘弹起
<input type="text" @keyup = "keyupevent"/>
keyupevent: function() {
}
鼠标事件:
stop阻止事件冒泡
prevent阻止事件默认行为
capture捕获内部元素事件
once只执行一次事件
键盘事件:
keyCode值
keyCode别名
指定按键触发事件
<a href="test.html" @click.prevent="aclick">text
</a>
事件对象
event事件对象表示当前事件的状态
event.target
获取触发事件的HTML的元素
event.type
得到触发事件的类型
event.type()
触发事件的类型
event.target()
触发事件的HTML元素
event.preventDefault()
阻止事件的默认行为
event.stopPropagation()
阻止事件冒泡
传递事件对象,手动传递,如果有多个参数,那么event永远式最后的参数,event永远式最后的参数,event永远式最后的参数,event表示当前的使用对象
接收事件对象:
dada: function(event){
// event表示接收到的事件对象
}
事件委派
提高应用程序的性能:借助事件对象上线一个事件委托机制。
那么什么是事件委派机制呢?
就是借助event事件对象,在父元素上绑定事件处理函数,不是在子元素上。
<table @click="edit($event)">
<tr v-for="(goods,index) in list">
这种方式,就连点击单元格都会触发事件。
做个判断就行:(对事件对象进行判断)
methods: {
dada: function(event) {
if(event.target.nodeName.toLowerCase() == "a") {
...
}
}
<a href="#" v-bind:data-index="index">dada</a>
methods: {
da:function(event){
if(event.target.nodeName.toLowerCase() == 'a') {
...
console.log(event.target.dataset.index);
}
}
}
表单处理
<input type="radio" v-model="gender" name="gender"
value="man">
<input type="radio" v-model="gender" name="gender"
value="woman">
<select v-model="province">
<option value="1"> d </option>
<option value="2"> a </option>
</select>
focus
文本框获取光标
blur
文本框失去光标
click
选中某一个单选按钮或复选框
change
切换下拉列表选项
submit
提交按钮
分页应用
每一页显示10条数据,当前页page参数
第一页从0,…,9 数组数据下标是从0开始的
开始下标:offset = (page-1)*pagesize
结束下标: offset + pagesize
items.slice(offset, offset+pagesize)
分页:
总页码 = Math.ceil(总记录数/每一页记录数)
生命周期的四个阶段:
create(初始)、mount(加载)、update(更新)、destroy(销毁)
var data={
items: [
{name: 'da', age: 1 }
],
item: {
name: '',
status: 1
},
pagesize; 5,
page:1
};
1
2
3
4
5
6
7
8
9
10
11
computed: {
// 总页数
pagecount: function() {
return Math.ceil(this.items.length/this.pagesize);
},
// 当前
pageitems: function() {
var offset=(this.page-1) * this.pagesize;
return this.items.slice(offset, offset + this.pagesize);
}
},
methods: {
// 删除
delitem(index){
this.item[index].status=3;
}
jumpToPage(p) {
this.page = p;
},
lastpage() {
this.page--;
},
nextpage(){
this.page++;
}
}
vue生命周期可以分为11个阶段,分别是:
beforeCreate(创建前)、created(创建后)、beforeMount(载入前)、mounted(载入后)、beforeUpdate(更新前)、updated(更新后)、beforeDestroy(销毁前)、destroyed(销毁)、activated(组件创建最初始)deactivated( 组件内被切换)errorCaptured(主要用来处理一些异常错误,基本不怎么去使用)