vue.js入门三

<!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.113113位键值),就可以随意用哪个键来触发事件 -->
                </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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值