<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vueStudy3</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- Vue 要实现异步加载需要使用到 vue-resource 库 -->
<!-- vue-resource 依赖于 Vue ,所以先后顺序要注意 -->
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
<link rel="stylesheet" href="css/vueTest.css" />
<link rel="stylesheet" href="css/bootstrap.min.css">
</head>
<body>
<div id="app">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">添加品牌</h3>
</div>
<div class="panel-body form-inline">
<label for="">
Id:
<input type="text" class="form-control" v-model="id">
</label>
<label for="">
Name:
<input type="text" class="form-control" v-model="name" @keyup.enter="add" >
<!-- 点了 enter 键才触发 add 事件 -->
<!-- 如果写成 @keyup.113 (113位键值),就可以随意用哪个键来触发事件 -->
</label>
<!-- add() 函数加了小括号可以传参。不用传是加不加无所谓 -->
<input type="button" value="添加" class="btn btn-primary" @click="add()">
<label for="">
搜索名称关键字:
<input type="text" class="form-control" v-model="keyword" id="search" v-focus v-color="'orange'">
</label>
</div>
</div>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>ctime</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<!-- 自定义一个search方法,同时搜索的关键字,通过传参的形式,传递给了search方法 -->
<!-- 在search方法内部,通过执行for循环,把所有符合搜索关键字的数据保存到一个新数组中返回。 -->
<tr v-for="item in search(keyword)" :key="item.id">
<td>{{item.id}}</td>
<td v-text="item.name"></td>
<td>{{item.ctime | dateFormat('')}}</td>
<!-- .prevent 阻止默认行为-->
<td><a href="" @click.prevent="del(item.id)"> 删除 </a></td>
</tr>
</tbody>
</table>
<!--
<p v-fontweight="100" v-fontsize="30">uuuuuuuuuuu</p>
<input type="button" value="get请求" @click="getInfo">
<input type="button" value="post请求" @click="postInfo">
<input type="button" value="jsonp请求" @click="jsonpInfo"> -->
</div>
<script>
Vue.http.options.root = 'http://vue.studyit.io/';
// 全局启用 emulateJson选项
Vue.http.options.emulateJson = true;
// 定义一个 Vue 全局的过滤器,名字叫做 msgFormat
// 全局过滤器
Vue.filter('dateFormat',function(dateStr,pattern=""){
//根据给定的字符串,得到特定的时间
var dt = new Date(dateStr)
var y = dt.getFullYear()
var m = (dt.getMonth() +1).toString().padStart(2,'0')
var d = dt.getDate().toString().padStart(2,'0')
// return y + '-' + m + '-' + d
return `${y}-${m}-${d}`
if(pattern.toLowerCase() === 'yyyy-mm-dd'){
return `${y}-${m}-${d}`
}else{ // padStart(2,'0') 从前面开始填充,共两位,不足的用‘0’填充
var hh = dt.getHours().toString().padStart(2,'0');
var mm = dt.getMinutes().toString().padStart(2,'0');
var ss = dt.getSeconds().toString().padStart(2,'0');
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}
})
// 自定义全局键盘码
Vue.config.keyCodes.f2 = 113;
// 使用 Vue.directive() 定义全局的指令
// 其中:参数1 : 指令的名称
Vue.directive('focus',{
bind: function(el){
//每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
// 在每个函数中,第一个参数,永远是 el ,表示被绑定了指令的那个元素,这个 el 参数,是一个原生的 JS 对象( DOM 对象)
// 在元素刚绑定了指令的时候 ,还没有插入到 DOM 树中去的时候,调用 focus 方法没有作用
// 因为一个元素只有插入 DOM 之后,才能获取焦点
// 和样式相关的,一般都可以在 bind 中执行
//el.focus()
},
inserted: function(el){
// 表示元素插入到 DOM 中的时候,会执行 inserted函数, 只触发一次
// 和 JS 相关的最好在 inserted 中去执行,防止 JS 行为不生效
el.focus()
},
updated: function(){
// 当 VNode 更新的时候,会执行 updated ,可能会触发多次
}
})
// 自定义一个设置字体颜色的指令
Vue.directive('color',{
// 样式只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式
bind: function(el,binding){
//el.style.color = 'red'
el.style.color = binding.value
}
})
//new 出来的这个vm对象就是 MVVM 中的VM调度者
var vm = new Vue({
el: '#app',
data:{
list:[
{id:1,name:"Benz", ctime: new Date()},
{id:2,name:"BWM", ctime: new Date()},
{id:3,name:"Ferrari", ctime: new Date()},
{id:4,name:"Lincoln", ctime: new Date()},
],
id:'',
name:'',
keyword:'',
dateStr:''
},
created(){//第二个生命周期函数
//在 created 中,data 和 methods 都已经初始化好了
// 如果要调用 methods 中的方法或者操作 data 中的数据,最早只能在 created 中操作
this.getAllList()
},
methods:{
add(){//这是添加的方法
var car = {id: this.id, name: this.name , ctime:new Date()}
this.list.push(car)
this.name = this.id = ''
},
del(id){//根据id删除数据
//1.先根据id找到要删除项的索引 2.找到索引后,直接调用数组的 splice方法
// 在数组的的some方法中,如果return true,就会立即终止这个数组的后续循环
/* this.list.some((item,i) => {
if(item.id == id){
this.list.splice(i,1)
return true;
}
}) */
var index = this.list.findIndex(item =>{
if(item.id == id){
return true;
}
})
// console.log(index)
this.list.splice(index,1)
},
search(keyword){//根据关键字进行数据的搜索
/* var newList = []
this.list.forEach(item=>{
if(item.name.indexOf(keyword) != -1){
newList.push(item)
}
})
return newList; */
// 注意:forEach some filter findIndex 这些都属于数组的新方法,
// 都会对数组中的每一项 ,进行遍历 ,执行相关的操作;
var newList = this.list.filter(item=>{
if(item.name.includes(keyword)){
return item;
}
})
return newList;
},
getInfo(){//发起 get请求
// 当发起 get请求之后,通过 .then 来设置成功的回调函数
this.$http.get("http://vue.studuit.io/api/getlunbo").then(function(result){
// console.log(result)
})
},
postInfo(){//发起 post请求
// 手动发起的 POST请求,默认没有表单格式( application/x-wwww-form-urlencoded),所以有的服务器处理不了
// post方法: post( url,[body],[option])
// 通过 post方法的第三个参数,{emulateJSON:true}设置提交的内容类型为普通表单格式
this.$http.post('http://vue.studyit.io/api/post',{},{emulateJSON:true}).then(result=>{
// console.log(result)
})
},
jsonpInfo(){//发起 JSONP请求
this.$http.jsonp('http://vue.studyit.io/api/jsonp').then(result=>{
// console.log(result)
})
},
getAllList(){//获取所有品牌列表
// 由于已经导入了 vue-resource这个包,所以,可以直接通过 this.$http 来发起数据请求
// 根据接口 API 文档,知道获取列表的时候,应该发起一个 get请求
// this.$http.get('url').then( function( result){})
// 当通过 then 指定回调函数之后,在回调函数中,可以拿到数据服务器返回的 result
// 先判断 result.status 是否等于 0 ,如果等于 0 ,就成功了,可以把 result.message赋值给
// this.list;如果不等于 0 ,可以弹框提醒,获取数据失败。
this.$http.get('api/getprolist').then( result=>{
// 通过 this.$http.获取到的数据都在 result.body里放着
var result = result.body
if(result.status ===0){
//成功了
this.list = result.message
}else{
//失败了
alert('获取数据失败!')
}
})
},
addList(){//添加品牌列表到后端服务器
// 添加数据,要发送一个 post 请求,this.$http.post
// this.$http.post() 中接收三个参数:1. 要请求的 url地址 2.要提交给服务器的数据
// 要以对象的形式提交给服务器 { name:this.name}
// 3. 是一个配置对象,要以那种表单数据类型提交过去, { emulateJSON:true},以普通表单
// 格式,将数据提交给服务器 application/x-www-form-urlencoded
// 在 post方法中,通过.then来设置成功的回调函数,如果想要拿到成功的结果,需要 result.body
/* this.$http.post('api/addproduct',{name:this.name},{emulateJSON:true}).then(result=>{
if(result.body.status === 0){
//成功了
// 添加完成后,只需要手动再调用一下 getAllList就能刷新品牌列表
this.getAllList()
// 清空 name
this.name=''
}else{
// 失败了
alert("失败了")
}
})*/
this.$http.post('api/addproduct',{name:this.name}).then(result=>{
if(result.body.status === 0){
//成功了
// 添加完成后,只需要手动再调用一下 getAllList就能刷新品牌列表
this.getAllList()
// 清空 name
this.name=''
}else{
// 失败了
alert("失败了")
}
})
},
delList(id){//删除品牌
this.$http.get('api/delproduct'+id).then(result=>{
if(result.body.status === 0){
//成功了
// 删除完成后,只需要手动再调用一下 getAllList就能刷新品牌列表
this.getAllList()
// 清空 name
}else{
// 失败了
alert("失败了")
})
}
},
filters:{// 局部过滤器
// 过滤器的调用采用就近原则,先调用私有的过滤器,再调用全局的过滤器
// dateFormat:function(dateStr,pattern){
// }
},
directives:{//自定义私有属性
'fontweight':{// 设置字体粗细
bind:function(el,binding){
el.style.fontWeight = binding.value
}
},
'fontsize':function(el,binding){
// 这个 function 等同于把代码写到了 bind 和 update 中去
el.style.fontSize = parseInt(binding.value) + 'px'
}
},//以下生命周期函数,最重要为 created 和 mounted
beforeCreate(){//第一个命周期函数,表示实例完全被创建出来之前,会执行它
// 在 beforeCreate 生命周期函数执行的时候,data 和 methods 中的数据都还没有被初始化
},
beforeMount(){//第三个生命周期函数,表示模板已经在内存中编译完成了,但是尚未把模板渲染在页面中去
// mount:挂载 ;
// 在 beforeMount 执行的时候,页面中的元素的内容,还没有真正被替换过来,只是之前写的一些字符串
},
mounted(){// 第四个生命周期函数,表示内存中的模板已经真实挂载在浏览器的页面中了,
// mounted 是实例创建期间的最后一个生命周期函数,当执行完mounted就表示,实例已经被完全创建好了
// 如果没有其他操作的话,这个实例就一直存在内存之中。
// 如果要通过某些插件操作页面上的 DOM 节点了,最早要在 mounted 中进行
// 只要执行完了 mounted,就表示整个 Vue 实例已经初始化完毕了;
// 此时组件已经脱离了创建阶段,进入了运行阶段
// 包括两个函数 : beforeUpdate( when data changes) 和 updated
// 这两事件会根据 data数据的改变,选择性触发 0次到无穷次
},
// 接下来是运行中的两个事件
beforeUpdate(){//这个时候,表示界面还没有被更新,data被更新
// 当执行这个函数的时候,页面中的数据还是旧的,data中的数据是最新的,页面尚未和最新的数据保持同步
// beforeUpdate 之后,进行 Virtual DOM re-render(再渲染)and patch。这一步执行的是:先根据
// data中最新的数据,在内存中重新渲染出一份最新的内存 DOM 树。DOM 树更新后,会把它重新渲染到页面中去
// 这时候,就完成了数据从 data( Model层 )--> view( 视图层 )的更新
// 之后,再执行 updated 函数
},
updated(){
// 此时,页面和 data 数据已经保持同步了,都是最新的了
// 此后,当页面关闭后,执行 beforeDestroy和 destroyed 方法
},
beforeDestroy(){
// 当执行这个钩子函数的时候,Vue实例就已经从运行阶段进入到销毁阶段;
// 实例身上所有的 data 和所有的 methods 以及过滤器、指令。。。都处于可用状态,还没执行销毁过程
},
destroyed(){
// 当执行到这个函数的时候,组件已经被完全销毁了,此时,,所有的,,都已经不可用了
}
});
</script>
<!-- 生命周期钩子 = 生命周期函数 = 生命周期事件
分为创建阶段、运行阶段、销毁阶段-->
<!-- jsonp的实现原理: 由于浏览器的安全性限制,不允许 AJAX 访问协议不同、域名不同、端口不同的数据接口,
浏览器认为这种访问不安全。可以通过动态创建 script 标签的 src属性,指向数据接口的地址,因为 script
标签不存在跨域限制,这种数据获取方式,称作 JSONP。
具体实现过程:1.先在客户端定义一个回调函数,预定义对数据的操作。
2.再把这个回调方法的名称通过 URL 传参的形式,提交给服务器的数据接口;
3.服务器数据接口组织好要发送给客户端的数据,再拿给客户端传递过来的回调方法名称,
拼接出一个调用方法的字符串,发送给客户端去解析执行。
4.客户端拿到服务器返回的字符串之后,当做 Script 脚本去解析执行,这样就能拿到JSONP的数据了。
-->
</body>
</html>
vue.js入门三
最新推荐文章于 2024-06-12 08:41:10 发布