MVVM框架
MVVM是Model-View-ViewModel,即模型-视图-视图模型。模型是后端的数据,视图是前端的页面。其设计思想是:关注Model的变化,让MVVM去自动更新Model的变化;从而把开发者从Dom繁琐的步骤解脱出来。vm是v和m的调度者(桥梁)是设计思想的核心。
实现的方式:DOM事件监听。这两个方向都实现的,我们称之为数据的双向绑定。在MVVM的框架下视图和模型是不能直接通信的。它们通过ViewModel来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。
与后台MVC框架的区别:
- 实现了数据和视图的分离
- 通过数据来驱动视图,开发者只需要关心数据变化,DOM操作被封装了。
vue基本的学习
Vue就是基于MVVM模式实现的一套框架
文档:https://cn.vuejs.org/v2/api/
一些JS的API先了解
- Array.prototype.filter()
过滤掉不满足条件的数组,返回一个新的通过测试的元素的集合的数组,如果没有通过测试则返回空数组
const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
let newFruits = fruits.filter(function(item){//过滤,组成新数组
return item.toLowerCase().indexOf('apple')==-1
//过滤,排除掉apple,组成新数组
})
console.log(newFruits)
// ["banana", "grapes", "mango", "orange"]
- String.prototype.includes()
includes() 方法用于判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false。(主要用来实现搜索功能,当然也可以使用indexOf
console.log(str.includes('to be'))//判断str是否包括to be
//返回true
+Array.prototype.findIndex()
var array1 = [5, 12, 8, 130, 44];
var index = array1.findIndex(function(item){//item是每一项
return item>13;
// 当array1中有一项大于13,返回该项索引
})
console.log(index)//3
引入vue文件
下载vue
git clone https://github.com/vuejs/vue-syntax-highlight
引入我们下载好的vue的vue.min.js
为了使界面美观,我们引入bootstrap
(和平常一样引入即可)
在webpack使用vue
或则我们可以使用vue组件,在webpack中使用
import Vue from 'vue'
import 'bootstrap/dist/css/bootstrap.css'
import app from './app.vue'
var vm = new Vue({
el:'#app',
data:{
msg:'vue+webpack'
},
render:c=>c(app)
})
在webpack中使用vue组件也可以,使用上面引入vue文件–直接引入也可以,结合bootstrap来使用即可,这里我们在webpack使用vue为例子
基本页面
app.vue
<template>
<div class='container'>
<h1 class="text-center">汽车品牌案例</h1>
<hr>
<form class="form-inline text-center">
<div class="form-group">
<label for="car_id">ID</label>
<input type="text" class="form-control" id="car_id" placeholder="汽车编号" v-model="carId">
</div>
<div class="form-group">
<label for="car_name">Name</label>
<input type="text" class="form-control" id="car_name" placeholder="汽车名字" v-model="carName">
</div>
<button type="submit" class="btn btn-primary" @click.prevent="add">添加</button>
<div class="form-group">
<label for="car_key">Keywords</label>
<input type="email" class="form-control" id="car_key" placeholder="关键字" v-model='keywords'>
</div>
</form>
<hr>
<table class="table table-bordered text-center">
<thead>
<tr>
<td>ID</td>
<td>Name</td>
<td>Timer</td>
<td>Operation</td>
</tr>
</thead>
<tbody class="text-center">
<tr v-for="(item,i) in carMsg" :key="item.id" :class="[i%2==0?'success':'']">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.timer}}</td>
<td><a href="javascript:;" @click.prevent="del(item.id)">删除</a></td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default{
data(){
return{
carId:'',
carName:'',
keywords:'',
carMsg:[
{id:1,name:"奔驰",timer:new Date()},
{id:2,name:"宝马",timer:new Date()},
{id:3,name:"法拉利",timer:new Date()}
]
}
},
methods:{
add(){
//add添加功能
},
search(keywords){
//搜索功能
},
del(id){
//删除功能
}
}
};
</script>
<style>
</style>
基本的页面(主要功能在即可,也可以自己写页面)
添加功能
let obj = {id:this.carId,name:this.carName,timer:new Date()}//获取input输入的数据
this.carMsg.unshift(obj)//添加到我们data数据里面的carMsg
点击添加按钮即可添加
删除功能
del(id){//根据id删除
let index = this.carMsg.findIndex(item=>{
return id = item.id//当找到与data数据里面carMsg一样时,返回该条数据的索引值
})
this.carMsg.splice(index,1)//根据索引值进行删除该条数据
}
点击删除按钮即可实现
搜索功能
- 前面两个功能比较容易,主要是运用API即可,可以多种方法实现
- 我实现搜索功能,给搜索的输入框绑定了@change来绑定search功能,发现没效果,使用@keydown,获取的是上一个的数据,使用@keyup,发现当数据被清空了,就没法在改变了,会改变原有的数据,总之大大小小的bug
- 使用search方法返回一个数据,直接v-for循环search
search(keywords){
// 使用keydown获取的是上一个值
return this.carMsg.filter((item,index)=> {
if(item.name.includes(this.keywords)){
// 任何一个字符串都包含一个空的字符串(''),当搜索框没有输入的时候任何字符时,当然carMsg所有的数据都满足,如果有输入,则匹配返回满足条件的数据
return true;
}
});
},
直接使用v-for循环方法
<tbody class="text-center">
<tr v-for="(item,i) in search(keywords)" :key="item.id" :class="[i%2==0?'success':'']">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.timer}}</td>
<td><a href="javascript:;" @click.prevent="del(item.id)">删除</a></td>
</tr>
</tbody>
全部代码
<template>
<div class='container'>
<h1 class="text-center">汽车品牌案例</h1>
<hr>
<form class="form-inline text-center">
<div class="form-group">
<label for="car_id">ID</label>
<input type="text" class="form-control" id="car_id" placeholder="汽车编号" v-model="carId">
</div>
<div class="form-group">
<label for="car_name">Name</label>
<input type="text" class="form-control" id="car_name" placeholder="汽车名字" v-model="carName">
</div>
<button type="submit" class="btn btn-primary" @click.prevent="add">添加</button>
<div class="form-group">
<label for="car_key">Keywords</label>
<input type="email" class="form-control" id="car_key" placeholder="关键字" v-model='keywords'>
</div>
</form>
<hr>
<table class="table table-bordered text-center">
<thead>
<tr>
<td>ID</td>
<td>Name</td>
<td>Timer</td>
<td>Operation</td>
</tr>
</thead>
<tbody class="text-center">
<tr v-for="(item,i) in search(keywords)" :key="item.id" :class="[i%2==0?'success':'']">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.timer}}</td>
<td><a href="javascript:;" @click.prevent="del(item.id)">删除</a></td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default{
data(){
return{
carId:'',
carName:'',
keywords:'',
carMsg:[
{id:1,name:"奔驰",timer:new Date()},
{id:2,name:"宝马",timer:new Date()},
{id:3,name:"法拉利",timer:new Date()}
]
}
},
methods:{
add(){
let obj = {id:this.carId,name:this.carName,timer:new Date()}
this.carMsg.unshift(obj)
this.carId = this.carName = ''
},
search(keywords){
return this.carMsg.filter((item,index)=> {
return item.name.includes(this.keywords)
});
},
del(id){
let index = this.carMsg.findIndex(item=>{
return id = item.id
})
this.carMsg.splice(index,1)
}
}
};
</script>
<style>
</style>
改进
- 可以使用Vue过滤器格式化时间
- 可以结合路由