学习vue的笔记

之前学过vue,上一个项目做小程序,发现跟vue差不多,于是给一个星期的时间自己重拾vue,但是发现高估了自己,并发现自己已变成一个小白...看了几天vue文档之后,再也不想说小程序与vue相似,小程序简单太多了,看完文档就可以做出来了,但是vue不一样。。。个人觉得vue的文档很散,讲的都是小零件,所以很难想着拼起来。在学习过程中做一下笔记吧...忘了可以看...

创建实例
new Vue({
 el: "#app",
 data:{},
 methods: {},
 filters: {},
 directives: {},
 computed:{},
    router: vueRouter
})
过滤器

过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。

  • 全局过滤器(自定义)
Vue.filter("dateFmt",function (param,fmtStr) {
        let year = param.getFullYear();
        let month = param.getMonth() + 1;
        let day = param.getDate();
        let hour = param.getHours();
        let minute = param.getMinutes();
        let second = param.getSeconds();
        if(fmtStr == "yyyy-mm-dd"){
            return year + "-" + month + "-" + day;
        }else if(fmtStr == "yyyy-mm-dd hh:mm:ss"){
            return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
        }
    });
  • 局部过滤器(自定义)
filters:{
            dateFmt(param,fmtStr){
                let year = param.getFullYear();
                let month = param.getMonth() + 1;
                let day = param.getDate();
                let hour = param.getHours();
                let minute = param.getMinutes();
                let second = param.getSeconds();
                if(fmtStr == "yyyy-mm-dd"){
                    return year + "-" + month + "-" + day;
                }else if(fmtStr == "yyyy-mm-dd hh:mm:ss"){
                    return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
                }
             },
        }
  • 使用过滤器(管道符后跟着过滤器名(参数))
    <td>{{item.time | dateFmt("yyyy-mm-dd hh:mm:ss")}}</td>
自定义指令(这指令的钩子函数,看不太懂...)

钩子函数

  • bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作
  • inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。

钩子函数参数

  • binding: 一个对象,包含以下属性:
    value: 指令的绑定值, 例如: v-my-directive="1 + 1", value 的值是 2,又如:v-color="{colorname:'red',colorname2:'green'}",value.colorname的值是red,value.colorname2的值是green

我想,暂时这两个够用了...毕竟其他还不会...

  • 全局指令
    // 定义一个全局自定义属性指令
    Vue.directive('focus', {
        // 当绑定元素插入到 DOM 中时调用(父节点存在即可调用,不必存在于 document 中)
        inserted: function (el) {
            // 聚焦元素
            el.focus();
            console.log(el);
        }
    });
  • 局部指令
directives: {
            focus:{
                inserted(el){
                    el.focus();
                }
            },
            "color":{
                bind: function (el,binding) {
                    console.log(binding.value.colorname);
                    el.style.color = binding.value.colorname;
                },
                inserted: function (el,binding) {
                    console.log(binding.value.colorname);
                }
            }
}
  • 使用指令
    <label>学号:<input class="add" type="text" v-model="newNo" v-focus v-color="{colorname:'red'}"></label>
计算属性(局部)

vue.js v1的系统过滤器filterBy换成计算属性了

computed: {
            searchQuery: function () {
                var self = this;
                return self.studentsList.filter(function (user) {
                    return (user["name"].indexOf(self.searchValue) !== -1 || user["no"].indexOf(self.searchValue) !== -1 || user["gender"].indexOf(self.searchValue) !== -1);
                })
            }
        }
vue-resource

响应.then()内的成功回调中的参数是响应报文体
这相当于jq的ajax

  • get
this.$http.get('/someUrl').then(successCallback, errorCallback);
  • post
    需要加上emulateJSON:true,其本质是在请求报文头上增加了Content-Type:application/x-www-form-urlencode,由此,服务器中才可以获取{no:1,sex:1}属性值
this.$http.post('/someUrl',{no:1,sex:1(请求报文体)},{emulateJSON:true}).then(successCallback, errorCallback);
  • jsonp
    原理:jsonp不是一个ajax请求,采取的是浏览器的同源策略来实现跨域,在请求的时候会在url后带上callback=生成的函数名称 一起提交给服务器,在服务器中利用callback传入的值当做一个方法来将要响应回去的数据当做参数传入。
// jsonp是设置回调的属性名,有些是cb=jqxxxx,有些是callback=jqxxxx,默认是callback
this.$http.post('/someUrl',{jsonp: "cb"}).then(successCallback, errorCallback);
生命周期
<div id="app">
    <span ref="span">hello vue</span>
</div>

new Vue({
    el: "#app",
    data: {
        msg:"hello"
    },
    // 在实例初始化之后,data和event/watcher 事件配置之前
    // 还不能取到this.data、事件
    beforeCreate(){
        console.log("1---beforeCreate",this.msg,this.$refs.span);
    },
    // 实例已完成以下的配置:data,属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
    // >>>>想要显示页面的时候就有数据的话,就在这个函数里请求数据
    created(){
        console.log("2---created",this.msg,this.$refs.span);
    },
    // 在挂载开始之前被调用:相关的 render 函数首次被调用。(可以理解为渲染前)
    beforeMount(){
        console.log("3---beforeMount",this.msg,this.$refs.span);
    },
    // el 被新创建的 vm.$el 替换(如{{}}差值表达式、v-show="isShow"等替换值),并挂载到实例上去之后调用该钩子。(可以理解为渲染后不知道这个vm.$el怎么用...)
    mounted(){
        console.log("4---mounted",this.msg,this.$refs.span);
    }
})
过渡

感觉这个过渡真的好鬼复杂!官网最简答的例子是点击按钮触发,但是我不想要这种,我要一打开网页就有动画,怎么实现?于是我就开始尝试用过渡的CSS类名和过渡钩子。

  • 过渡CSS类名实现
    ↓ 这个CSS其实我也不懂为什么要这样写,真的不懂,但是按照这个格式.XXXX-enter-active, .XXXX-leave-active { } .XXXX-enter, .XXXX-leave-active { }就可以有过渡的效果。
// CSS
    <style>
        .box { position: absolute; left: 0; top: 100px; width: 50px; height: 50px; background: skyblue;}
        .box1-enter-active, .box1-leave-active {
            transition: all .5s;
            transform: translateX(0px);
        }
        .box1-enter, .box1-leave-active {
            transform: translateX(200px)
        }
    </style>

↓ 一开始是用按钮触发isMove,后来被我注释了。

// html
    <div id="app">
        <!--<button @click="isMove=!isMove">移动</button>-->
        <transition name="box1">
            <div v-if="isMove" class="box"></div>
        </transition>
    </div>

看代码就知道一开始我在created钩子控制isMove,后来发现不行就换成mounted钩子,为什么mounted钩子就行,我是在过渡钩子发现的。

// JS
    new Vue({
        el: "#app",
        data: {
            isMove: false
        },
        // created(){
        // this.isMove = true;
        // },
        mounted(){
            this.isMove = true;
        }
    })
  • 过渡钩子实现
    ↓ 一定要给过渡元素加上类名,而且要有过渡(transition)属性。
// CSS
    <style>
        .box { width: 50px; height: 50px; background: skyblue; transition: all 3s linear;}
    </style>

@before-enter @enter @after-enter都是固定的,函数名随你,v-show很重要哦,就是要靠他触发

// html
    <div id="app">
        <transition name="moveBox"
            @before-enter="beforeEnter"
                    @enter="enter"
            @after-enter="afterEnter">
            <div v-show="isShow" class="box"></div>
        </transition>
    </div>

↓ 一开始我在created控制isShow,失败之后我想应该在哪个钩子控制变量呢,(错误思想:我看着过渡钩子,看到了el,哦!恍然大悟!mounted钩子不是跟el有关系的吗?写!搞定~)问了朋友关于生命周期mounted的问题后,得出答案:过渡元素还没有渲染完,元素渲染完在改变isShow,所以放在mounted执行

// JS
        new Vue({
            el: "#app",
            data: {
                isShow: false
            },
            methods: {
                beforeEnter: function (el) {
                    // 控制动画的准备进入
                    el.style.transform = 'translateX(0px)';
                },
                enter: function (el, done) {
                    // 控制动画的最终状态
                    let a = el.offsetLeft;
                    this.$nextTick(()=>{
                        el.style.transform = 'translateX(300px)';
                    });
                    done();
                },
                afterEnter: function (el) {
                    // 动画完以后的一些逻辑处理
                }
            },
            // created(){
            // this.isShow = true;
            // console.log(this.isShow);
            // },
            mounted(){
                this.isShow = true;
            }
        })
组件

不说废话直接上码

  • 基础组件
    • html 分成3块看
      ↓ 这#app就是根组件,www是父组件
      <div id="app">
          <www></www>
      </div>
      
      ↓ 这就是父组件www的模板,这个模板里面有两个<a>,点击登录变量which = login,点击注册变量which = register,还有子组件,这个是动态组件, <component>的元素属性is = which决定渲染哪个子组件,而which由点击哪个a标签决定。(keep-alive此时我还不知道有什么用,随意加上去的)
      <template id="account">
        <div>
          <h3>{{msg}}</h3>
          <a href="#" @click="which='login'">登录</a>
          <a href="#" @click="which='register'">注册</a>
          <!--动态组件-->
          <keep-alive>
              <component :is="which"></component>
          </keep-alive>
        </div>
      </template>
      
      ↓ 父组件模板的子组件模板
      <template id="login">
        <div>
          <h4>登录组件内容</h4>
        </div>
      </template>
      <template id="register">
        <div>
          <h4>注册组件内容</h4>
        </div>
      </template>
      
    • JS
      ↓ 全局注册父组件,父组件中注册子组件
      Vue.component('www',{   // www 为组件元素名
          template:'#account',    // template元素的id
          data: function () {
              return{
                  msg: "账户组件内容:",
                  which: "login"
              }
          },
          // 父组件中注册子组件
          components:{
              "login":{   // 组件元素名
                  template: "#login"
              },
              "register":{   // 组件元素名
                  template: "#register"
              }
          }
      });
      new Vue({
         el:'#app'
      });
      
      ↓ 还可以局部注册父组件
      new Vue({
          el:'#app',
          components: {
              "www":{
                  template:'#account',    // template元素的id
                  data: function () {
                      return{
                          msg: "账户组件内容:",
                          which: "login"
                      }
                  },
                  // 父组件中注册子组件
                  components:{
                      "login":{   // 组件元素名
                          template: "#login"
                      },
                      "register":{   // 组件元素名
                          template: "#register"
                      }
                  }
              }
          }
      });
      
  • 父组件传值子组件
    在上面的例子基础上动工!
    • html
      ↓ 在父组件模板中加了一个<input>,输入登录人名称,在动态子组件中赋值给user属性,实现传值,要注意的是给组件属性赋值必须是父组件的已知值,不能是子组件的值
      ↓ 在登录子组件模板中加了<span>{{user}},欢迎登陆!</span>,子组件通过属性user取得登录人名称存放到props中,再用{{ }}取出。
      <template id="account">
         <div>
           <h3>{{info}}</h3>
           <a href="#" @click="which='login'">登录</a>
           <a href="#" @click="which='register'">注册</a>
           <br>
           <label>登录的人是 <input type="text" v-model="msg"></label>
           <!--动态组件-->
           <keep-alive>
               <component :user="msg" :is="which"></component>
           </keep-alive>
         </div>
      </template>
      <template id="login">
       <div>
           <h4>登录组件内容</h4>
           <span>{{user}},欢迎登陆!</span>
       </div>
      </template>
      <template id="register">
         <div>
           <h4>注册组件内容</h4>
         </div>
      </template>
      
      <div id="app">
         <www></www>
      </div>
      
    • JS
      ↑ 解释的很清楚了,这里不说了。
      Vue.component('www',{
        template:'#account',
        data: function () {
            return{
                info: "账户组件内容:",
                which: "login",
                msg: ""
            }
         },
        components:{
            "login":{
                template: "#login",
                props:["user"]
            },
            "register":{
                template: "#register"
            }
        }
      });
      new Vue({
        el:'#app'
      });
      
  • 子组件传值父组件
    这个栗子是点击登录以后,出现登录组件,在该组件中输入一句话,这句话在父组件中出现。
    • html
      ↓ 在父组件模板中加了<span>登陆之后,{{msg}}说:</span><span>{{userSay}}</span>用来显示子组件输入的话。在动态子组件中绑定自定义事件get-child-say(这个必须是羊肉串命名,不可以驼峰),事件处理程序就是sayWhat
      ↓ 在登录子组件模板中增加<label>我说: <input type="text" v-model="childSay" @keyup.enter="sendToFoo"></label>,当输入一句话后按回车键就会触发事件sendToFoo
      <template id="account">
        <div>
          <h3>{{info}}</h3>
          <a href="#" @click="which='login'">登录</a>
          <a href="#" @click="which='register'">注册</a>
          <br>
          <label>登录的人是 <input type="text" v-model="msg"></label>
          <div>
              <span>登陆之后,{{msg}}说:</span><span>{{userSay}}</span>
          </div>
          <!--动态组件-->
          <keep-alive>
              <component v-on:get-child-say="sayWhat" :user="msg" :is="which"></component><!-- 这个自定义事件get-child-say不能用驼峰命名,只能用羊肉串 -->
          </keep-alive>
          <!--打开vue tool观察:加了这个keep-alive,不显示的子组件一直在父组件中保存着,不加的话父组件下只有正在显示的子组件-->
        </div>
      </template>
      <template id="login">
        <div style="border: 1px solid red;">
          <h4>登录组件内容</h4>
          <span>{{user}},欢迎登陆!</span>
          <br>
          <label>我说: <input type="text" v-model="childSay" @keyup.enter="sendToFoo"></label>
        </div>
      </template>
      <template id="register">
        <div>
          <h4>注册组件内容</h4>
        </div>
      </template>
      
      <div id="app">
        <www></www>
      </div>
      
    • JS
      ↓ 在login组件有一个sendToFoo(),当该方法触发时,就会触发get-child-say事件,并且会带上参数this.childSay,就是输入的一句话,而这个事件在父组件中绑定的,故而执行sayWhat(value)获取参数渲染到父组件中。
      Vue.component('www',{
        template:'#account',
        data: function () {
            return {
                info: "账户组件内容:",
                which: "login",
                msg: "",
                userSay: ""
            }
        },
        methods: {
            sayWhat(value){
                this.userSay = value;
            }
        },
        components:{
            "login":{
                template: "#login",
                props:["user"],
                data:function () {
                    return {
                        childSay: ""
                    }
                },
                methods: {
                    sendToFoo(){
                        this.$emit("get-child-say",this.childSay);
                    }
                }
            },
            "register":{
                template: "#register"
            }
        }
      });
      new Vue({
        el:'#app'
      });
      
  • keep-alive
    在开始写基础组件的时候就有疑问了:动态组件中被keep-alive包着有什么用?终于搞完 子组件传值父组件 之后大概知道了一点了。
    • keep-alive包裹动态组件:运行基础组件,打开Vue.js devtools,然后看↓

      默认显示登录组件
      点击注册组件后

      .

    • 没有用keep-alive包裹动态组件:运行基础组件,打开Vue.js devtools,然后看↓

      默认显示登录组件
      点击注册组件后

<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。为此可以添加一个 keep-alive 指令参数。在API 参考查看更多 <keep-alive> 的细节。

  • 路由参数实现url传值
    下面的这个栗子是:在根组件输入数据作为路由参数(同时修改路由),然后通过路由传去组件。
// html
<div id="app">
    <label>传值:<input type="text" v-model="msg"></label>
    <br>
    <router-link :to="'/sub1/' + msg">sub1</router-link>
    <router-link to="/sub2">sub2</router-link>
    <!-- 组件的显示占位区域 -->
    <router-view></router-view>
</div>
<!-- 第一个子组件模板 -->
<template id="sub1">
    <div>
        <h3>这是第一个子路由</h3>
        <div>传来的值是:{{txt}}</div>
    </div>
</template>
<!-- 第二个子组件模板 -->
<template id="sub2">
    <div>
        <h3>这是第2个子路由</h3>
    </div>
</template>
// JS
    // 定义第一个子组件
    let sub1 = Vue.extend({
        template: "#sub1",
        data: function () {
            return {
                txt: ""
            }
        },
        // 导航完成后,在组件的 created 钩子中获取数据
        // 还可以在数据获取期间展示一个 loading 状态
        created: function () {
            this.txt = this.$route.params.id;
        }
    });
    // 定义第二个子组件
    let sub2 = Vue.extend({
        template: "#sub2"
    });
     // 定义路由对象并且注册路由规则
    let vueRouter = new VueRouter({
        routes: [
            {path: '/',redirect: '/sub2'},    // 默认路由
            {path: '/sub1/:id',component: sub1},
            {path: '/sub2', component: sub2}
        ]
    });
    // 使vueRouter生效
    new Vue({
        el: "#app",
        data: {
            msg: ""
        },
        router: vueRouter
    })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容