• vue.js 学习笔记


    Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统

    核心思想是:数据驱动、组件系统。

    MVC和MVVM的区别?
      
      MVVM即Model-View-ViewModel的简写。即模型-视图-视图模型。模型(Model)指的是后端传递的数据。视图(View)指的是所看到的页面。视图模型(ViewModel)是mvvm模式的核心,它是连接view和model的桥梁。它有两个方向:一是将模型(Model)转化成视图(View),即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。二是将视图(View)转化成模型(Model),即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。

      MVC是Model-View- Controller的简写。即模型-视图-控制器。M和V指的意思和MVVM中的M和V意思一样。C即Controller指的是页面业务逻辑。使用MVC的目的就是将M和V的代码分离。MVC是单向通信。也就是View跟Model,必须通过Controller来承上启下。MVC和MVVM的区别并不是VM完全取代了C,只是在MVC的基础上增加了一层VM,只不过是弱化了C的概念,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。也就是说MVVM实现的是业务逻辑组件的重用,使开发更高效,结构更清晰,增加代码的复用性。
     
    vue双向绑定原理?
      vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
    var obj = {};
    var demo = document.querySelector('#demo')
    var inp = document.querySelector('#inp')
    Object.defineProperty(obj, 'name', {
        get: function () {
            return val;
        },
        set: function (newVal) { //当该属性被赋值的时候触发
            inp.value = newVal;
            demo.innerHTML = newVal;
        }
    })
    inp.addEventListener('input', function (e) {
        // 给obj的name属性赋值,进而触发该属性的set方法
        obj.name = e.target.value;
    });
    obj.name = 'fei'; //在给obj设置name属性的时候,触发了set这个方法

     

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

     
    Object.defineProperty(obj, prop, descriptor)

    obj要在其上定义属性的对象。
    prop要定义或修改的属性的名称。
    descriptor将被定义或修改的属性描述符。

    11个生命周期函数 

    beforecreated:el 和 data 并未初始化 -------------在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

    created:完成了 data 数据的初始化,el没有 -----------在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

    beforeMount:完成了 el 和 data 初始化 --------在挂载开始之前被调用:相关的 render 函数首次被调用。该钩子在服务器端渲染期间不被调用。

    mounted :完成挂载--------el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted:
    mounted: function () {
    this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
    })
    }
    该钩子在服务器端渲染期间不被调用。 

    beforeUpdate:数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。 

    updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。注意 updated 不会承诺所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以用 vm.$nextTick 替换掉 updated:
    updated: function () {
    this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been re-rendered
    })
    }
    该钩子在服务器端渲染期间不被调用。

    activated:keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用。 

    deactivated:keep-alive 组件停用时调用。该钩子在服务器端渲染期间不被调用。 

    beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用。 

    destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

    errorCaptured:2.50版本新增 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数: 错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

    vue-cli 主要目录结构:
      index.html:一般只定义一个空的根节点,在main.js里面定义的实例将挂载在#app节点下,内容通过vue组件填充。
      src/ App.vue:是项目主组件,也是项目所有组件和路由的出口,之后它会被渲染到项目根目录的 index.html 中显示出来,我们可以在这里写一些适合全局的css样式。
      src/ main.js:入口文件,引入了vue模块和app.vue组件以及路由router,我们需要在全局使用的一些东西也可以定义在这里面。
      src/router index.js:路由配置文件。

    指令:
    v-bind 属性的绑定 简写 " : "
    v-if 控制一个元素是否显示(会对DOM进行创建和删除操作 有较高的切换性能消耗)
    v-show 控制一个元素是否显示(切换了元素的display:none/block;样式,有较高的初始渲染消耗)
    v-for 数据循环
    v-on 事件绑定 简写 " @ "
    v-model 数据的双向绑定

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <title>计算器</title>
            <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        </head>
        <body>
            <div id="app">
                <input type="text"  v-model="first" />
                <select v-model="opt">
                    <option value="+">+</option>
                    <option value="-">-</option>
                    <option value="*">*</option>
                    <option value="/">/</option>
                </select>
                <input type="text" v-model="last" />
                <input type="button" value="=" @click="add"/>
                <input type="text" v-model="result" />
            </div>
        </body>
    </html>
    <script type="text/javascript">
        var Vue = new Vue({
            el:"#app",
            data:{
                first:0,
                last:0,
                result:0,
                opt:"+"
            },
            methods:{
                add(){
                    var jieguo = "parseInt(this.first)"+ this.opt + "parseInt(this.last)";
                    this.result= eval(jieguo);
                }
            }
        })
    </script>

    v-cloak 使用v-cloak 能够解决插值表达式闪烁的问题
      [v-cloak] { display:none;}


    v-on @ 事件修饰符:
      .stop:等同于JavaScript中的event.stopPropagation(),防止事件冒泡
      .prevent:等同于JavaScript中的event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播)
      .capture:与事件冒泡的方向相反,事件捕获由外到内
      .self:只会触发自己范围内的事件,不包含子元素
      .once:只会触发一次

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <title>vue跑马灯</title>
            <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        </head>
        <body>
            <div id="app">
                <input type="button" value="" @click="love"/>
                <input type="button" value="不爱" @click="anlove" />
                <h4>{{msg}}</h4>
            </div>
        </body>
    </html>
    <script type="text/javascript">
        var Vue = new Vue({
            el:"#app",
            data:{
                msg:"爱你一万年!!!",
                setId:null
            },
            methods:{
                love(){
                    if(this.setId != null){
                        return false;
                    }
                    this.setId = setInterval(() => {
                        var str = this.msg.substring(0,1);
                        var str2 = this.msg.substring(1);
                        this.msg = str2 + str;
                    }, 200) 
                },
                anlove(){
                    clearInterval(this.setId);
                    this.setId = null;
                }
            }
        })
    </script>


    v-for:如果用v-for迭代数字的话,前面的count值从1开始
      <p v-for = "count in 10">这是第{{ count }} 次循环</p>

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <title>添加删除</title>
            <script src="https://cdn.jsdelivr.net/npm/vue"></script>
            <style type="text/css">
            *{padding:0;margin:0;border:0;-webkit-box-sizing: border-box;
               -moz-box-sizing: border-box;
                    box-sizing: border-box;}
            .add{padding:50px;}
            .add input{100px;border:1px #eee solid;height:40px;line-height:40px;text-align: center;}
            .biao{500px;margin-left:50px;}
                .biao ul li{overflow: hidden;border:1px #eee solid;line-height: 40px;}
                .biao ul li+li{border-top:none;}
                .biao ul li span{float: left;33.33%;text-align: center;cursor:pointer;}
                .biao ul li span+span{border-left:1px #eee solid;}
            </style>
        </head>
        <body>
            <div id="app">
                <div class="add">
                    <input type="text" v-model="id"/>
                    <input type="text" v-model="name"/>
                    <input type="button" value="添加" @click="add"/>
                </div>
                <div class="biao">
                    <ul>
                        <li v-for="item in list" :key="item.id">
                            <span>{{item.id}}</span>
                            <span>{{item.name}}</span>
                            <span @click="del(item.id)">删除</span>
                        </li>
                    </ul>
                </div>
            </div>
        </body>
    </html>
    <script type="text/javascript">
        var Vue = new Vue({
            el:"#app",
            data:{
                id:"",
                name:"",
                list:[
                    {id: 1, name: '天籁' },
                    {id: 2, name: '雅阁' },
                    {id: 3, name: '帕萨特'}
                ]
            },
            methods:{
                add(){
                    var arr = {id:this.id,name:this.name}
                    this.list.push(arr);
                },
                del(id){
                    // console.log("aa");
                    this.list.some((item,i)=>{
                        if(item.id == id){
                            this.list.splice(i,1);
                        }
                        return true;
                    })
                }
            }
        })
    </script>

    组件化实例
      <div id="app">
        <app-nav></app-nav>
        <app-view>
          <app-sidebar></app-sidebar>
          <app-content></app-content>
        </app-view>
      </div>

    在子组件中定义data ,data必须是个函数而不能是个对象
    data:function(){
      return {
        content: "xiaozhong"
      }
    }

    在vue中我们可以通过ref="zjz"获取DOM节点  this.$refs.zjz.      ,进而来操作DOM

    vue中单向数据流概念:子组件中只能使用父组件中传过来的值,而不能更改,如需更改需克隆一份修改父组件通过属性的方式向子组件传值,子组件通过事件触发的方式向父组件传值

    vue组件的属性使用和不使用冒号的区别:加冒号的,说明后面的是一个变量或者表达式;没加冒号的后面就是对应的字符串字面量!

    非父子组件间的传值:{
      1.vuex
      2.发布订阅模式---总线机制---Bus---观察者模式 not_father_son.html
    }

    插槽(slot):具名插槽,作用域插槽

    使用animate.css :只要在需要动画的标签外的transition标签里添加对应属性,比如enter-active-class=“animated swing”,leave-active-class=“animated shake”即可

    js动画效果:注意事件函数中所传递的参数及某些事件函数返回的函数
      1. 进入动画钩子:before-enter; enter; after-enter
      2. 离开动画钩子:before-leave; leave; after-leave
      3. 在enter钩子中的函数调用done()告诉VUE js动画完成
      4. 使用velocity.js动画库实现动画:Velocity(el,{样式属性},{duration:1000,complete:done})
      5. 中文文档:http://www.mrfront.com/docs/velocity.js/index.html

  • 相关阅读:
    小学四则算式扩充
    软件工程初涉之感
    回头
    个人最终总结
    团队作业
    结对编程
    老李的blog使用日记(3)
    进度
    老李的blog使用日记(2)
    红果果
  • 原文地址:https://www.cnblogs.com/zjz666/p/11115149.html
Copyright © 2020-2023  润新知