• Vue.js 基础入门(二)


    1. 品牌管理案例

    实现功能:

    • 添加新品牌:add
    • 删除品牌:数组循环,根据 ID 查找索引,调用 splice 方法删除
    • 根据品牌名过滤:数组循环
    • 格式化时间:过滤器
    • 时间补全:padStart() , ES6 新增, 如:2020-2-6 补全后为 2020-02-06
    <!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>Document</title>
        <link rel="stylesheet" href="./lib/bootstrap-3.3.7.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>
                        Id:
                        <input type="text" class="form-control" v-model="id">
                    </label>
    
                    <label>
                        Name:
                        <input type="text" class="form-control" v-model="name">
                    </label>
    
                    <!-- 在Vue中,使用事件绑定机制,为元素指定处理函数的时候,如果加了小括号,就可以给函数传参了 -->
                    <input type="button" value="添加" class="btn btn-primary" @click="add()">
    
                    <label>
                        搜索名称关键字:
                        <input type="text" class="form-control" v-model="keywords">
                    </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>
                    <tr v-for="item in search(keywords)">
                        <td>{{ item.id }}</td>
                        <td v-text="item.name"></td>
                        <td>{{ item.ctime | dateFormat() }}</td>
                        <td>
                            <a href="/" @click.prevent="del(item.id)">删除</a>
                        </td>
    
                    </tr>
                </tbody>
            </table>
    
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
            // 自定义过滤器
            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')
    
                if (pattern.toLowerCase === 'yyyy-mm-dd') {
                    return `${y}-${m}-${d}`
                } else {
                    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}`
                }
            })
    
    
            var vm = new Vue({
                el: '#app',
                data: {
                    id: '',
                    name: '',
                    keywords: '',
                    list: [
                        { id: 1, name: '奔驰', ctime: new Date() },
                        { id: 2, name: '宝马', ctime: new Date() }
                    ]
                },
                methods: {
                    add() {
                        var newData = { id: this.id, name: this.name, ctime: new Date() };
                        this.list.push(newData);
                        this.id = this.name = ''
                    },
                    del(id) {
                        // 根据 id 查找数组索引,再根据索引删除元素
                        var index = this.list.findIndex(item => {
                            if (item.id === id) {
                                return true;
                            }
                        })
        
                        this.list.splice(index, 1)  
                    },
                    search(keywords) {
                        // 根据关键字搜索
                        // var newList = []
                        // this.list.forEach(item => {
                        //     if (item.name.indexOf(keywords) != -1) {
                        //         newList.push(item)
                        //     }
                        // })
                        // return newList
                        
                        // ES6 中 String.prototype.includes('要包含的字符串')
                        return this.list.filter(item => {
                            if (item.name.includes(keywords)) {
                                return item
                            }
                        })
                    }
                }
    
            })    
        </script>
    </body>
    
    </html>
    

    2. 过滤器

    过滤器定义语法:

     Vue.filter('过滤器的名称', function(参数一, 参数二...){})
    

    过滤器中的 function ,第一个参数,永远都是过滤器管道符前面传递过来的数据。

    使用:

    {{ name | 过滤器的名称 }}
    

    2.1 全局过滤器

     <td>{{ item.ctime | dateFormat() }}</td>
    
    
    // 自定义过滤器
    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')
    
        if (pattern.toLowerCase === 'yyyy-mm-dd') {
            return `${y}-${m}-${d}`
        } else {
            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 实例
    
    var vm = new Vue({
    
    })
    

    Tips:全局过滤器在全局 Vue 实例中使用

    2.1 私有过滤器

    私有过滤器在 Vue 实例中定义:

    <div id="app2">
        <h3>{{ dt | dateFormat }}</h3>
    </div>
    
    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        // 自定义过滤器
        Vue.filter('dateFormat', function (dateStr, pattern = "") {
            var dt = new Date(dateStr)
    
            var y = dt.getFullYear()
            var m = dt.getMonth() + 1
            var d = dt.getDate()
    
            if (pattern.toLowerCase === 'yyyy-mm-dd') {
                return `${y}-${m}-${d}`
            } else {
                var hh = dt.getHours()
                var mm = dt.getMinutes()
                var ss = dt.getSeconds()
    
                return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
            }
        })
    
        var vm2 = new Vue({
            el: '#app2',
            data: {
                dt: new Date()
            },
            filters: {
                dateFormat: function (dateStr, pattern = '') {
                    var dt = new Date(dateStr)
    
                    var y = dt.getFullYear()
                    var m = dt.getMonth() + 1
                    var d = dt.getDate()
    
                    if (pattern.toLowerCase === 'yyyy-mm-dd') {
                        return `${y}-${m}-${d}`
                    } else {
                        var hh = dt.getHours()
                        var mm = dt.getMinutes()
                        var ss = dt.getSeconds()
    
                        return `${y}-${m}-${d} ${hh}:${mm}:${ss}~~~`
                    }
                }
            }
        })
    </script>
    

    Tips:若私有过滤器与全局过滤器名字一致,则采取就近原则,即使用私有过滤器!

    3. 键盘修饰符和自定义键盘修饰符

    全部按键别名:enter、tab、delete(捕获删除和退格)、esc、up、down、left、right、ctrl、alt、shift、meta

    // 回车触发 add 事件
    <input type="text" class="form-control" v-model="name" v-on:keyup.13="add">
    
    // 简写 使用 keycode
    <input type="text" class="form-control" v-model="name" @keyup.13="add">
    
    // 或者使用按键别名
    <input type="text" class="form-control" v-model="name" @keyup.enter="add">
    

    自定义按键修饰符

    我们自己也可以自定义按键修饰符,便于记忆。

    // 配置,
    Vue.config.keyCodes.f2 = 113;
    
    // 使用
    <input type="text" v-model="name" @keyup.f2="add">
    

    参考文档:

    • js 里面的键盘事件对应的键码:https://www.cnblogs.com/wuhua1/p/6686237.html

    4. 自定义指令

    4.1 自定义全局指令

    语法:

    // 参数一:指令名称,定义时名称前面不需要加 v-,但是在 html 中使用时,需要加 v- 的前缀来调用
    // 参数二:为一个对象,里面可以配置一些指令相关的函数,这些函数在特定的阶段,执行相关操作
    // 常见的有 bind、inserted、updated
    Vue.directive('指令名称', {
        // el 为被绑定指令的元素,为一个原生的 js 对象,因此可以进行一些 js 方面的操作
        bind: function(el){
            // 当指令绑定到元素上时,会立即执行,执行一次
        },
        inserted: function(el){
            // 元素插入的 DOM 中时,会执行 inserted 函数,触发一次
        },
        uodated: function(el) {
            // 当VNode 更新的时候,会执行 updated,可能会触发多次
        }
    })
    

    何时用 bind、inserted 和 updated

    • 与 JS 行为相关的操作,最好使用 inserted 中执行,放置 JS行为不生效
    • 与样式相关的操作,一般都可以在 bind 执行

    示例一:

    初始化页面时,给搜索框获取焦点:

    <div id="app">
        <label>
            搜索名称关键字:
            <input type="text" class="form-control" v-model="keywords" v-focus>
        </label>
    </div>
    
    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        // 自定义全局指令
        Vue.directive('focus', {
            bind: function(el) {},
            inserted: function(el) {
                el.focus()
            },
            updated: function(el) {}
        })
    
        var vm = new Vue({
            el: '#app'
        })
    </script>
    

    4.2 局部自定义指令

    <body>
        <div id="app">
            <label for="fo">页面加载时自动聚焦</label>
            <input v-focus id="fo"/>
        </div>
        
        <script src="https://cdn.staticfile.org/vue/2.2.2/vue.js"></script>
        <script>
            Vue.directive('focus', {
                inserted: function(el) {
                    el.focus()
                }
            })
            
            var vm = new Vue({
                el: '#app',
                // 局部定义
                directives: ('focus', {
                    inserted: function(el) {
                        el.focus()
                    }
                })
            })
        </script>
    </body>
    

    4.3. 钩子函数

    指令定义函数提供了几个钩子函数(可选):

    • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
    • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
    • update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
    • componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
    • unbind: 只调用一次, 指令与元素解绑时调用。

    钩子函数参数

    • el: 指令所绑定的元素,可以用来直接操作 DOM 。
    • binding: 一个对象,包含以下属性:
      • name: 指令名,不包括 v- 前缀。
      • value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2。
      • oldValue: 指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
      • expression: 绑定值的表达式或变量名。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
      • arg: 传给指令的参数。例如 v-my-directive:foo, arg 的值是 "foo"。
      • modifiers: 一个包含修饰符的对象。 例如: v-my-directive.foo.bar, 修饰符对象 modifiers 的值是 { foo: true, bar: true }。
    • vnode: Vue 编译生成的虚拟节点。
    • oldVnode: 上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

    示例二:

    自定义一个 设置字体颜色的 指令:

    <div id="app">
        <label>
            搜索名称关键字:
            <!-- <input type="text" class="form-control" v-model="keywords" v-focus v-color> -->
            <input type="text" class="form-control" v-model="keywords" v-focus v-color="'red'">
        </label>
    </div>
    
    <script src="./lib/vue-2.4.0.js"></script>
    <script>
        // 自定义全局指令:颜色
        Vue.directive('color', {
            bind: function(el, binding) {
                // el.style.color = 'red'
                el.style.color = binding.value  // 使用指令绑定的值
            }
        })
    
        var vm = new Vue({
            el: '#app'
        })
    </script>
    

    4.4 函数简写

    在很多时候,你可能想在 bindupdate 时触发相同行为,而不关心其它的钩子。比如这样写:

    Vue.directive('color-swatch', function (el, binding) {
      el.style.backgroundColor = binding.value
    })
    

    示例三:

    <div id="app2">
        <h3 v-fontsize="50">{{ dt | dateFormat }}</h3>
    </div>
    
    <script>
        // 自定义全局指令,获取焦点
        Vue.directive('focus', {
            bind: function(el) {},
            inserted: function(el) {
                el.focus()
            },
            updated: function(el) {}
        })
    
        // 自定义全局指令:颜色
        Vue.directive('color', {
            bind: function(el, binding) {
                el.style.color = binding.value
            }
        })
    
        var vm2 = new Vue({
            el: '#app2',
            data: {
                dt: new Date()
            },
            directives: {
                'fontsize': function(el, binding) {
                    el.style.fontSize = parseInt(binding.value) + 'px'
                }
            }
        })
    </script>
    

    5. vue实例的生命周期

    什么是生命周期:从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期!

    声明周期钩子函数

    即在生命周期内发生的事件,以下为所有钩子函数:

    • 创建期间的生命周期函数:
      • beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
      • created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
      • beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
      • mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示
    • 运行期间的生命周期函数:
      • beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
      • updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
    • 销毁期间的生命周期函数:
      • beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用
      • destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

    示例

    <body>
        <div id="app">
            <input type="button" value="修改msg" @click="msg='No'">
            <h3 id="h3">{{ msg }}</h3>
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    msg: 'Hello'
                },
                methods: {
                    show() {
                        console.log('函数 show')
                    }
                },
                beforeCreate() {
                    // 实例创建之前触发
                    // 在 beforeCreate 生命周期函数执行的时候,data 和 methods 中的 数据都还没有没初始化
                    //    console.log(this.msg)
                    //    this.show()
                },
                created() {
                    // 实例创建后触发
                    // 在 created 中,data 和 methods 都已经被初始化好了!
                    // 如果要调用 methods 中的方法,或者操作 data 中的数据,最早,只能在 created 中操作
                    //    console.log(this.msg)
                    //    this.show()
                },
                beforeMount() {
                    // 挂载之前触发
                    // 模板已经在内存中编辑完成了,但是尚未把 模板渲染到 页面中
                    // 在 beforeMount 执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的一些模板字符串
                    // console.log(document.getElementById('h3').innerText)    // {{ msg }}
                },
                mounted() {
                    // 模板挂载后触发
                    // 内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了
                    // mounted 是 实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,
                    // 此时,如果没有其它操作的话,这个实例,就静静的 躺在我们的内存中,一动不动
                    // console.log(document.getElementById('h3').innerText)    // Hello
                },
    
                // 运行中生命周期钩子函数
                // 以下两个钩子函数,当 data 发生改变时才会触发,msg 内容原本为 Hello,当点击后变为 No
                beforeUpdate() {
                    // 模板挂载完毕,只有当 data 发生改变时才会触发
                    // 当执行 beforeUpdate 的时候,页面中的显示的数据,还是旧的,此时 data 数据是最新的,页面尚未和 最新的数据保持同步
                    // console.log('界面上元素的内容:' + document.getElementById('h3').innerText)       // No
                    // console.log('data 中的 msg 数据是:' + this.msg)          // No
                },
                updated() {
                    // 模板挂载完毕,只有当 data 发生改变时才会出发
                    // updated 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的
                    console.log('界面上元素的内容:' + document.getElementById('h3').innerText)     // No
                    console.log('data 中的 msg 数据是:' + this.msg)    // No
                }
            })
        </script>
    </body>
    

    参考文档:

    6. vue-resource

    Vue 要实现异步加载需要使用到 vue-resource 库。Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求。

    6.1 GET 请求

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Vue-Resource</title>
    <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
    <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
    </head>
    <body>
    <div id="box">
    	<input type="button" @click="get" value="点我异步获取数据(Get)">
    </div>
    <script type = "text/javascript">
    window.onload = function(){
    var vm = new Vue({
        el:'#box',
        data:{
            msg:'Hello World!',
        },
        methods:{
            get() {
                //发送get请求
                this.$http.get('/try/ajax/ajax_info.txt').then(function(res){
                    document.write(res.body);    
                },function(){
                    console.log('请求失败处理');
                });
            }
        }
    });
    }
    </script>
    </body>
    </html>
    

    如果需要传递数据,可以使用 this.$http.get('get.php',{params : jsonData}) 格式,第二个参数 jsonData 就是传到后端的数据。

    this.$http.get('get.php',{params : {a:1,b:2}}).then(function(res){
        document.write(res.body);    
    },function(res){
        console.log(res.status);
    });
    

    6.2 POST 请求

    post 发送数据到后端,需要第三个参数 {emulateJSON:true}emulateJSON 的作用: 如果 Web 服务器无法处理编码为 application/json 的请求,你可以启用 emulateJSON 选项。

    <body>
    <div id="box">
    	<input type="button" @click="post" value="点我异步获取数据(Post)">
    </div>
    <script type = "text/javascript">
    window.onload = function(){
    	var vm = new Vue({
    	    el:'#box',
    	    data:{
    	        msg:'Hello World!',
    	    },
    	    methods:{
    	        post(){
    	            //发送 post 请求
    	            this.$http.post('/try/ajax/demo_test_post.php',{name:"POST 请求",url:"http://www.runoob.com"},{emulateJSON:true}).then(function(res){
                        document.write(res.body);    
                    },function(res){
                        console.log(res.status);
                    });
    	        }
    	    }
    	});
    }
    </script>
    </body>
    

    语法 & API

    既可以全局对象方式发送请求,也可以在一个 vue 实例中发送请求,使用方式如下:

    // 基于全局Vue对象使用http
    Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback);
    Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
    
    // 在一个Vue实例内使用$http
    this.$http.get('/someUrl', [options]).then(successCallback, errorCallback);
    this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
    

    七种 REST 风格的请求方式:

    get(url, [options])
    head(url, [options])
    delete(url, [options])
    jsonp(url, [options])
    post(url, [body], [options])
    put(url, [body], [options])
    patch(url, [body], [options])
    

    options 参数

    参数 类型 描述
    url string 请求的目标URL
    body Object, FormData, string 作为请求体发送的数据
    headers Object 作为请求头部发送的头部对象
    params Object 作为URL参数的参数对象
    method string HTTP方法 (例如GET,POST,...)
    timeout number 请求超时(单位:毫秒) (0表示永不超时)
    before function(request) 在请求发送之前修改请求的回调函数
    progress function(event) 用于处理上传进度的回调函数 ProgressEvent
    credentials boolean 是否需要出示用于跨站点请求的凭据
    emulateHTTP boolean 是否需要通过设置X-HTTP-Method-Override头部并且以传统POST方式发送PUT,PATCH和DELETE请求。
    emulateJSON boolean 设置请求体的类型为application/x-www-form-urlencoded

    响应

    1、属性:

    属性 类型 描述
    url string 响应的 URL 源
    body Object, Blob, string 响应体数据
    headers Header 请求头部对象
    ok boolean 当 HTTP 响应码为 200 到 299 之间的数值时该值为 true
    status number HTTP 响应码
    statusText string HTTP 响应状态

    2、方法:

    方法 类型 描述
    text() 约定值 以字符串方式返回响应体
    json() 约定值 以格式化后的 json 对象方式返回响应体
    blob() 约定值 以二进制 Blob 对象方式返回响应体

    6.3 JSONP 请求

    JSONP的实现原理

    • 由于浏览器的安全性限制,不允许AJAX访问 协议不同、域名不同、端口号不同的 数据接口,浏览器认为这种访问不安全;
    • 可以通过动态创建script标签的形式,把script标签的src属性,指向数据接口的地址,因为script标签不存在跨域限制,这种数据获取方式,称作JSONP(注意:根据JSONP的实现原理,知晓,JSONP只支持Get请求)

    具体实现过程

    • 先在客户端定义一个回调方法,预定义对数据的操作
    • 再把这个回调方法的名称,通过URL传参的形式,提交到服务器的数据接口;
    • 服务器数据接口组织好要发送给客户端的数据,再拿着客户端传递过来的回调方法名称,拼接出一个调用这个方法的字符串,发送给客户端去解析执行
    • 客户端拿到服务器返回的字符串之后,当作Script脚本去解析执行,这样就能够拿到JSONP的数据了
    <body>
      <div id="app">
        <input type="button" value="jsonp请求" @click="jsonpInfo">
      </div>
    
      <script>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
          el: '#app',
          data: {},
          methods: {
            jsonpInfo() { // 发起JSONP 请求
              this.$http.jsonp('http://vue.studyit.io/api/jsonp').then(result => {
                console.log(result.body)
              })
            }
          }
        });
      </script>
    </body>
    

    Node.js 服务器示例

    1、app.js

    // 导入 http 内置模块
    const http = require('http')
    
    const urlModule = require('url')
    
    // 创建一个 http 服务器
    const server = http.createServer()
    
    // 监听 http 服务器的 request 请求
    server.on('request', function (req, res) {
        const { pathname: url, query } = urlModule.parse(req.url, true)
    
        if (url === '/getscript') {
            // 拼接一个合法的 JS 脚本,拼接的是一个方法的调用
            var data = {
                name: 'rose',
                age: 18,
                gender: '女',
                phone: '18674447633'
            }
    
            var scriptStr = `${query.callback}(${JSON.stringify(data)})`
    
            // res.end 发送给客户端,客户端将这个字符串当前 JS 代码去解析执行
            res.end(scriptStr)
        } else {
            res.end('404')
        }
    })
    
    // 指定端口号并启动服务器监听
    server.listen(3000, function () {
        console.log('server listen at http://127.0.0.1:3000')
    })
    

    执行 node app.js 运行 node 服务器。

    2、client.html

    <!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>Document</title>
    </head>
    <body>
        <div id="app">
            <input type="button" value="get 请求" @click="getinfo">
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
        <script>
            var vm = new Vue({
                el: '#app',
                methods: {
                    getinfo() {
                        // get 请求
                        this.$http.get('http://vue.studyit.io/api/getlunbo').then(function (result) {
                            console.log(result)
                        })
                    }
                }
            })    
        </script>
    </body>
    </html>
    

    7. 配置本地数据库和数据接口 API

    品牌管理案例改造

    • 获取接口:http://www.liulongbin.top:3005/api/getprodlist
    • 添加接口:http://www.liulongbin.top:3005/api/addproduct
    • 删除接口:http://www.liulongbin.top:3005/api/delproduct/id

    API 接口

    1、获取品牌数据

    • 请求方式:get
    • 返回数据格式:json
    • 请求参数:无
    • 请求URL:http://www.liulongbin.top:3005/api/getprodlist
    • 返回数据示例
    {"status":0,"message":[{"id":5,"name":"宝马","ctime":"2020-02-08T04:32:58.000Z"},{"id":6,"name":"玛莎拉蒂","ctime":"2020-02-08T04:33:03.000Z"},{"id":12,"name":"1","ctime":"2020-02-08T04:51:21.000Z"}]}
    

    2、添加新品牌

    • 请求方式:post
    • 返回数据格式:json
    • 请求参数:{name: 品牌名}
    • 请求URL:http://www.liulongbin.top:3005/api/addproduct
    • 返回数据示例
    {"status":0,"message":"添加成功"}
    

    3、删除品牌

    • 请求方式:get
    • 返回数据格式:json
    • 请求参数:品牌id api/delproduct/1
    • 请求URL:http://www.liulongbin.top:3005/api/delproduct/id
    • 返回数据示例
    {"status":0,"message":"删除成功"}
    
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="./lib/bootstrap-3.3.7.css">
    </head>
    
    <body>
        <div id="app">
            <div class="panel panel-primary">
                <div class="panel-body form-inline">
                    <input type="text" placeholder="品牌名" class="form-control" v-model="name" @keyup.enter="add">
                    <input type="button" value="添加" class="btn btn-primary" @click="add">
                </div>
            </div>
    
    
            <table class="table table-bordered table-hover table-striped">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>Name</th>
                        <th>Ctime</th>
                        <th>Opration</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="item in list" :key="item.id">
                        <td>{{ item.id }}</td>
                        <td>{{ item.name }}</td>
                        <td>{{ item.ctime }}</td>
                        <td>
                            <a href="" @click.prevent="del(item.id)">删除</a>
                        </td>
                    </tr>
                </tbody>
            </table>
    
        </div>
    
        <script src="./lib/vue-2.4.0.js"></script>
        <script src="./lib/vue-resource-1.3.4.js"></script>
        <script>
            // 全局配置根目录
            Vue.http.options.root = 'http://www.liulongbin.top:3005/';
            // 全局启用 emulateJSON 选项
            Vue.http.options.emulateJSON = true;
    
            var vm = new Vue({
                el: '#app',
                data: {
                    name: "",
                    list: [
                        { id: 1, name: '奔驰', ctime: new Date() },
                        { id: 2, name: '宝马', ctime: new Date() }
                    ]
                },
                created() {
                    // 页面初始化时,执行 getinfo() 函数,获取品牌数据
                    this.getinfo()
                },
                methods: {
                    getinfo() {
                        // 获取品牌信息
                        this.$http.get('api/getprodlist').then(result => {
                            // 赋值给 this.list,从而实现数据的显示
                            if (result.body.status === 0) {
                                this.list = result.body.message
                            }
                        })
                    },
                    add() {
                        // 添加新品牌
                        // 发送 post 请求,获取
                        this.$http.post('api/addproduct', { name: this.name }).then(result => {
                            if (result.body.status === 0) {
                                console.log('添加成功!')
                                // 重新调用获取数据接口,实现页面刷新
                                this.getinfo()
                                // 清空输入框
                                this.name = ''
                            } else {
                                alert('添加失败!')
                            }
                        })
                    },
                    del(id) {
                        // 根据删除品牌
                        this.$http.get("api/delproduct/" + id).then(result => {
                            if (result.body.status === 0) {
                                this.getinfo()
                            } else {
                                alert('删除失败!')
                            }
                        })
                    }
                }
            })
        </script>
    </body>
    
    </html>
    

    参考文章:

  • 相关阅读:
    pytorch的函数中的group参数的作用
    pytorch的函数中的dilation参数的作用
    resnet18全连接层改成卷积层
    Pytorch实现UNet例子学习
    MyEclipse中出现Address already in use:JVM_Bind:8080
    为SQL数据库创建登录名和密码
    集合体系
    排序算法及其java实现
    java泛型通配符?
    Arrays.asList的用法
  • 原文地址:https://www.cnblogs.com/midworld/p/13611024.html
Copyright © 2020-2023  润新知