Vue.js学习No.2

  • 欢迎关注个人公众号 css

    公众号

  • 学习的内容以下html

  • 开始前端

  • 过滤器的定义方法 主要去解决时间显示的问题 过滤器调用的格式 {{ name | nameope }}vue

// Vue.filter("过滤器的名称",function(data){
        //      return data+"123"
        // })

  Vue.filter("msgFormat",function(msg,args){
             return msg+"arg"+args
        })
     <td>{{item.Ctime | msgFormat('你好仕明同窗')}}</td>
复制代码
  • 这个是干吗的??? <link rel="stylesheet" href="./lib/bootstrap.min.css">node

  • @keyup.enter="add" 点击了回车键的话,就触发事件 所有的按键别名.enter .tab .delete .esc .space .up .down .left .right 若是想要指定的某一个某个按键的话 就必须从新的定义 找键盘码git

  • 定义全局键盘码es6

Vue.config.keyCodes.f2=113
复制代码
  • @click="add(传入参数)
  • v-text在插值表达式中,不能使用{{item,Ctime}}只能这样使用使用 v-text="item.Ctime

过滤器

  • 调用就近原则,若是全局过滤器和私有过滤器名称同样,做用同样的,那么先调用私有的
  • 过滤器调用的格式 {{ name | nameope }},过滤器能够屡次调用
  • 要想使全局过滤器生效的话,就必须初始化在 全局过滤器以后
//   全局过滤器,全部的实例对象都共享了 
        // 其实这个时间会默认的给与他  pattern="" 以防止调用者不给他赋值
        Vue.filter("dateFromat", function (date, pattern = "") {
            var dt = new Date(date);
            var y = dt.getFullYear();
            var m = dt.getMonth() + 1
            var d = dt.getDate()
            console.log("shiming" + pattern)
            console.log("shiming" + date)
            // return `${y}-${m}-${d}`

            // pattern 这个要判断一下是否为null 
            if (pattern.toLowerCase() === "yyyy-mm-dd") {
                // return y+"-"+m+"-"+d
                // 魔法字符串
                return `${y}-${m}-${d}`
            } else {
                var hh = dt.getHours();
                var mm = dt.getMinutes()
                var ss = dt.getSeconds()

                return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
            }
        })
复制代码
  • forEach some filter findIndex 都会遍历数组的每一项,
    • forEach没有办法终止
    • some 能够return true 把它终止掉
    • filter
    • findIndex 找索引

一个添加和删除数据的Demo

<!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>
    <script src="./lib/vue.min.js"></script>
    <!-- 这个是干吗的??? -->
    <link rel="stylesheet" href="./lib/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>
                    Id:<input type="text" class="form-control" v-model="id">
                </label>
                <label>
                    <!-- class="form-control" 一个好看一个很差看  @keyup="add" 事件-->
                    <!--  @keyup.enter="add" 点击了回车键的话,就触发事件 
                    所有的按键别名
                    .enter  .tab .delete  .esc  .space  .up  .down .left .right 
                    若是想要指定的某一个某个按键的话 就必须从新的定义 找键盘码 
                    -->
                    <!-- Name:<input type="text" v-model="name" @keyup.enter="add"> -->
                    <!-- 这样就能够其做用了 使用f2 去触发某些的操做 -->
                    Name:<input type="text" v-model="name" @keyup.f2="add">
            
                </label>
                <!-- 传入参数 ,加了小括号  -->
                <input type="button" value="添加" class="btn btn-primary" @click="add()">


                <label>
                    搜索关键字:<input type="text" class="form-control" v-model="key">
                </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>
                <!-- 若是这个list是个固定的集合的话,那么页面就不能刷新了,我我的的理解
                这个list须要根据代码来改变的,这样子才很好  
                -->
                <tr v-for="item in search(key)" :key="item.id">
                    <td>{{item.id}}</td>
                    <td>{{item.name}}</td>
                    <!-- v-text在插值表达式中,不能使用{{item,Ctime}} 只能这样使用使用 
                         <td v-text="item.Ctime"></td>

                          这种用法是错误的,下面的使用的方法    <td v-text="{{item.Ctime}}"></td>
                    -->
                    <!-- <td v-text="item.Ctime"></td> -->

                    <!-- <td>{{item.Ctime | msgFormat('你好仕明同窗')|test}}</td> -->

                    <td>{{ item.Ctime | dateFromat("yyyy-mmd-dd") }}</td>
                    <td>
                        <!-- .prevent 阻止默认行为 -->
                        <a href="" @click.prevent="del(item.id)">删除</a>
                    </td>
                </tr>
            </tbody>
        </table>


    </div>


    <div id="app2">


        {{1+1}}

        {{ dt |dateFromat }}

        <h1> {{ dt |dateFromat }} </h1>
    </div>


    <div id="app3">
        {{1+1}}

    </div>
    <script>




        // Vue.filter("msgFormat", function (msg, args) {
        //     return msg + "arg" + args
        // })
        // // 过滤器能够屡次调用

        // Vue.filter("test", function (msg) {
        //     return msg + "test" 
        // })
        //   全局过滤器,全部的实例对象都共享了 
        // 其实这个时间会默认的给与他  pattern="" 以防止调用者不给他赋值
        Vue.filter("dateFromat", function (date, pattern = "") {
            var dt = new Date(date);
            var y = dt.getFullYear();
            var m = dt.getMonth() + 1
            var d = dt.getDate()
            console.log("shiming" + pattern)
            console.log("shiming" + date)
            // return `${y}-${m}-${d}`

            // pattern 这个要判断一下是否为null 
            if (pattern.toLowerCase() === "yyyy-mm-dd") {
                // return y+"-"+m+"-"+d
                // 魔法字符串
                return `${y}-${m}-${d}`
            } else {
                var hh = dt.getHours();
                var mm = dt.getMinutes()
                var ss = dt.getSeconds()

                return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
            }
        })

        // 定义全局键盘码 
        Vue.config.keyCodes.f2=113

      
        //  要想使全局过滤器生效的话,就必须初始化在 全局过滤器以后
        var vm2 = new Vue({
            el: "#app2",
            data: {
                dt: new Date()
            },
            methods: {

            },
            // 定义私有过滤器
            filters: {

                // 调用就近原则,若是全局过滤器和私有过滤器名称同样,做用同样的,
                // 那么先调用私有的
                dateFromat: function (date, pattern = "") {
                    var dt = new Date(date);
                    var y = dt.getFullYear();
                    // 有多是一位数的  padStart(2,"0") 表示长度为2 ,不够的话0来补充
                    var m = (dt.getMonth() + 1).toString().padStart(2,"0")
                    var d = dt.getDate().toString().padStart(2,"0")
                    console.log("shiming" + pattern)
                    console.log("shiming" + date)
                    // return `${y}-${m}-${d}`

                    // pattern 这个要判断一下是否为null 
                    if (pattern.toLowerCase() === "yyyy-mm-dd") {
                        // return y+"-"+m+"-"+d
                        // 魔法字符串
                        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: "",
                key: "",
                list: [
                    { id: 1, name: "宝马", Ctime: new Date() },
                    { id: 2, name: "长安", Ctime: new Date() },
                ]
            },
            methods: {
                add() {
                    console.log("log")

                    var car = { id: this.id, name: this.name, Ctime: new Date() }

                    this.list.push(car)
                    this.name = this.id = ""

                },
                del(id) {
                    //vue中使用some删除list中的数据 能够在some内部作任何的事情 
                    //    this.list.some((item,i)=>{
                    //        if(item.id==id){
                    //            this.list.splice(i,1)
                    //            return true; 
                    //        }
                    //    })  
                    //这个就是专门来找id的 
                    var index = this.list.findIndex(item => {
                        if (item.id == id) {

                            return true;
                        }
                    })
                    this.list.splice(index, 1)
                    console.log("找到的索引 :" + index)
                },
                //根据关键字查询集合
                search(key) {
                    //方法一
                    // var newList=[];
                    // // 这里这个循环注意是使用的那个item,是条件的哦
                    // this.list.forEach(item => {
                    //     if (item.name.indexOf(key)!=-1) {
                    //         newList.push(item)
                    //     }
                    // }); 
                    // return newList

                    //  forEach some filter findIndex 都会遍历数组的每一项,
                    // forEach没有办法终止 
                    // some 能够return true 把它终止掉
                    // filter 
                    // findIndex 找索引 
                    //过滤器,符合的都返回
                    return this.list.filter(item => {
                        // 若是能取到的话,就不等于-1 
                        if (item.name.indexOf(key) != -1) {

                        }
                        // es6中提供新的方法,叫作includes 若是包含返回true
                        if (item.name.includes(key)) {
                            return item
                        }
                    })
                    //  newList
                }

            }
        })
        // 过滤器的定义方法 主要去解决时间显示的问题
        // Vue.filter("过滤器的名称",function(data){
        //      return data+"123"
        // })


    </script>
</body>

</html>


<!-- 过滤器调用的格式  {{ name | nameope }} -->
复制代码
  • 自定义指令 在Vue中全部的指令都是V开头 <input type="text" class="form-control" v-model="key" v-focus>github

  • 使用Vue.directive 定义全局的指令express

    • 参数1:指令的名称,注意不须要加上V- ,可是调用的时候,须要加上V-
    • 参数2:是一个对象,有指令相关的函数,函数能够在特色的阶段执行相关的操做
// 使用Vue.directive 定义全局的指令
// 参数1:指令的名称,注意不须要加上V- ,可是调用的时候,须要加上V-
// 参数2:是一个对象,有指令相关的函数,函数能够在特色的阶段执行相关的操做
         Vue.directive("focus",{
            //  指令绑定在元素上的时候,只调用一次,在指令第一次绑定到元素上时调用。就是一个元素的对象
             bind:function(el){
                // 每一个函数中,第一个参数永远是el,表示被绑定,其实就是text 原声的js对象
                // 一个元素,只有插入Dom以后,才会有焦点
                // el.focus() 因此这个方法在这里不行
             },
            //  inserted 表示元素插入Dom中的时候,会执行一次
             inserted:function(el){
                el.focus()
             },
               // 值更新时的工做
             // 也会以初始值为参数调用一次
             updated:function(){

             }
         })
复制代码
Vue.directive("color",{
            //  为啥设置颜色能够生效,其实理解为初始化了这个属性
            // 只要经过指令绑定了元素,无论这个元素有没有插入进去,这个元素确定有一个内联的样式
            // 和样式相关的操做 
             bind:function(el,binding){
                  el.style.color="red"
//                   binding:一个对象,包含如下属性:
// name:指令名,不包括 v- 前缀。
// value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
// oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。不管值是否改变均可用。
// expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
// arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
// modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
                  console.log("shiming value=---"+binding.value)  
                  console.log("shiming name=---"+binding.name)       
                  console.log("shiming expression=---"+binding.expression) 

                         el.style.color=binding.value   
             },
            //  和行为有关的操做,最好在inserted中执行
             inserted:function(){

             },
             updated:function(){

             }
         })
复制代码
  • 定义私有的指令,写到vm实例中去了
// 定义私有的指令
            directives:{
                "fontweight":{
                    bind:function(el,binding){
                        el.style.fontWeight=binding.value
                    }
                }
            }
复制代码
  • 注意directives ,引用的时候是大写的V <h1 v-color="'pink'" V-fontweight="900"> {{ dt |dateFromat }} </h1>npm

  • 函数简写

    • 在不少时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。
// 定义私有的指令
            directives:{
                "fontweight":{
                    bind:function(el,binding){
                        el.style.fontWeight=binding.value
                    }
                },
                // 这个方法其实就两个方法合成一个了,bind和update中去了
                "fontsize" :function(el,binding){
                   el.style.fontSize=binding.value
                }

            }
复制代码

Vue的生命周期

  • 一、new Vue()

  • 二、 Init :刚刚初始化了一个Vue实例,只有默认的生命周期函数和默认的事件,其余的没有建立

  • 三、 实例彻底被建立出来,会执行他,在这个生命周期函数执行的时候,datamethods的尚未被初始化

  • 四、初始化datamethods

  • 五、created 方法执行,datamethods 初始化好了

  • 六、Vue开始编译模板,Vue代码中的指令进行执行,最终在内存中生成一个编译好的最终模板,而后把这个模板字符串,渲染为内存中的Dom,此时,只是在内存中,渲染好了模板,并无把模板挂载到正真的页面中去

  • 七、内存中已经已经编译完成了,可是没有把模板渲染到页面中beforeMount(),console.log(document.getElementById("pp").innerText)就是 输出 innerText {{msg}} 尚未正真的渲染出来,还咩有挂载到页面中去

  • 八、强内存中编译好的模板,正式的替换到页面中去

  • 九、内存中的模板挂载到页面中,用户能够看到页面的 mounted实例最后的一个生命周期的函数只要执行完了mountedVue实例已经初始化完毕了,此时已经进入到了运行阶段

  • 十、beforeUpdate 最少执行0次,也有可能触发屡次,运行中的事件

  • 十一、 update 最少执行0次,也有可能触发屡次,运行中的事件

  • 十二、beforeDestoryVue实例就已经从运行阶段进入到销毁阶段,可是此时候实例上全部datamethods,过滤器和指令都是处于可用的状态,尚未执行销毁的过程

  • 1三、destoryed到这里就所有销毁了

    lifecycle.png

  • Demo 代码

<!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>
    <script src="./lib/vue.min.js"></script>
</head>

<body>

    <div id="app">
        <p>好好学习</p>

        <p id="pp">{{ msg }}</p>
        <input type="button" value="修改msg" @click="msg='我被修改了'">
    </div>


    <script>
        // 一、new Vue
        //二、 init:刚刚初始化了一个Vue实例,只有默认的生命周期函数和默认的事件,其余的没有建立

        var vm = new Vue({
            el: "#app",
            // 四、初始化data和methods 
            data: {
                msg: "msg消息"
            },
            methods: {
                show() {
                    console.log("show方法")
                }
            },
            //三、 实例彻底被建立出来,会执行他,在这个生命周期函数执行的时候,data和methods的尚未被初始化
            beforeCreate() {
                console.log("beforeCreate方法")
                // 输出为undefined
                console.log(this.msg)
            },
            // 五、created 方法执行,data和methods 初始化好了
            created() {
                console.log("created方法")
                console.log(this.msg)
            },
            // 六、Vue 开始编译模板,Vue代码中的指令进行执行,最终在内存中生成一个编译好的最终模板,
            // 而后把这个模板字符串,渲染为内存中的Dom,此时,只是在内存中,渲染好了模板,并无把模板挂载到正真的页面中去
            //   七、内存中已经已经编译完成了,可是没有把模板渲染到页面中
            beforeMount() {
                console.log("beforeMount方法")
                // 就是 输出  innerText {{msg}} 尚未正真的渲染出来,还咩有挂载到页面中去
                console.log(document.getElementById("pp").innerText)
            },
            // 八、强内存中编译好的模板,正式的替换到页面中去
            // 九、内存中的模板挂载到页面中,用户能够看到页面的 mounted实例最后的一个生命周期的函数
            // 只要执行完了mounted,Vue实例已经初始化完毕了,此时已经进入到了运行阶段
            mounted(){
                console.log("mounted方法")
                console.log(document.getElementById("pp").innerText)
            },
            // 十、beforeUpdate  最少执行0次,也有可能触发屡次,运行中的事件
            beforeUpdate(){
                console.log("beforeUpdate方法")
                // 这个消息仍是旧的
                console.log(document.getElementById("pp").innerText)
            } ,
               // 十一、 update 最少执行0次,也有可能触发屡次,运行中的事件
            updated(){
                console.log("updated方法")
                console.log(document.getElementById("pp").innerText)
            },
            // 十二、beforeDestory Vue实例就已经从运行阶段进入到销毁阶段,可是此时候实例上全部data和methods,过滤器和指令都是处于可用的状态,尚未执行销毁的过程

            beforeDestroy(){
                console.log("beforeDestroy方法")
            },
            // 1三、到这里就所有销毁了
            destoryed(){
                console.log("destoryed方法")
            }   

        })

    </script>
</body>

</html>
复制代码

vue-resource的使用

  • 依赖于 Vue有个前后的顺序
  • <script src="https://cdn.jsdelivr.net/npm/vue-resource@1.5.1"></script>
<script src="./lib/vue.min.js"></script>
    <!-- vue-resource 依赖于 Vue 有个前后的顺序  this.$http.get -->
    <script src="https://cdn.jsdelivr.net/npm/vue-resource@1.5.1"></script>

// global Vue object
Vue.http.get('/someUrl', [config]).then(successCallback, errorCallback);
Vue.http.post('/someUrl', [body], [config]).then(successCallback, errorCallback);

// in a Vue instance
this.$http.get('/someUrl', [config]).then(successCallback, errorCallback);
this.$http.post('/someUrl', [body], [config]).then(successCallback, errorCallback);
复制代码
  • Demo
<!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>
    <script src="./lib/vue.min.js"></script>
    <!-- vue-resource 依赖于 Vue 有个前后的顺序  this.$http.get -->
    <script src="https://cdn.jsdelivr.net/npm/vue-resource@1.5.1"></script>
</head>

<body>
    <div id="app">
        <input type="button" value="get" @click="getInfo">
    </div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {

            },
            methods: {
                getInfo() {
                    console.log("getInfo")


                    // GET /someUrl then返回的数据
                    this.$http.get('https://cn.vuejs.org/v2/guide/ssr.html').then(response => {


                        console.log(response)
                        // get body data  通常获取body 就能够了
                        this.someData = response.body;
                        console.log(this.someData)


                    }, response => {
                        // error callback
                        console.log(response)
                    });
                    
                    this.$http.post('http://vue.studyit.io/api/post',{},{emulateJSON:true}).then(result=>{
                        console.log(result.body)
                    })
                     

                    // // POST /someUrl
                    // this.$http.post('/someUrl', { foo: 'bar' }).then(response => {

                    //     // get status
                    //     response.status;

                    //     // get status text
                    //     response.statusText;

                    //     // get 'Expires' header
                    //     response.headers.get('Expires');

                    //     // get body data
                    //     this.someData = response.body;

                    // }, response => {
                    //     // error callback
                    //     console.log("error"+response)
                    // });
                }
            }

        })
    </script>
</body>

</html>
复制代码
  • 使用最多的请求jsonp(url, [config])
  • vue-resource 目前和Vue中最经常使用的请求框架

Jsonp的原理(还要仔细查阅资料)

  • jsonp的实现原理 一、因为浏览器的安全限制,不容许AJAX访问 协议不一样,余名不一样,端口号不一样的数据接口,浏览器认为不安全 二、能够经过动态建立script的标签的形式,把script标签的src属性,指向数据接口的地址,由于script标签不存在跨域限制,这种方式叫作JSONP,JSONP只支持get请求

  • 本身的node服务器

  • node.js服务器的实现我的感受好像go,我擦,这一套代码都是一我的写的??

  • nodejs开发辅助工具nodemon

// 导入http的内置模块
const http = require("http")
// 建立一个 http服务器
const server = http.createServer()
// 监听 http 服务器的request的请求
server.on('request', function (req, res) {

    const url = req.url

    console.log("我是服务器,我启动了url==="+url)

    if (url === "/getDemo") {

        var scrip = "show()"

        res.end(scrip)

    } else {
        // 返回404
        res.end("404")
    }
})
// http://127.0.0.1:3000/getDemo
// 指定端口号并启动服务器监听 感受好像go语言啊
server.listen(3000, function () {
    console.log("我是服务器,我启动了")
})
复制代码
  • 启动
    image.png
  • 客服端
<!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>
     <script>
// jsonp的实现原理
// 一、因为浏览器的安全限制,不容许AJAX访问 协议不一样,余名不一样,端口号不一样的数据接口,浏览器认为不安全
// 二、能够经过动态建立script的标签的形式,把script标签的src属性,指向数据接口的地址,由于script标签不存在跨域限制,这种方式叫作JSONP,JSONP只支持get请求
// 

         function show(){
             console.log("我是客服端的方法,可是经过服务器帮我执行的,show方法是服务器帮我调用的")
         }
        </script>

        <script src="http://127.0.0.1:3000/getDemo"></script>
</body>
</html>
复制代码
  • 后语:Vue+node.js来实现一个前端项目?
相关文章
相关标签/搜索