Vue.js 学习记录

Posted 言叶以上のBLOG

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue.js 学习记录相关的知识,希望对你有一定的参考价值。

一、Vue起步

Vue:构建用户界面的渐进式框架。

1.helloworld

<div id="app">{{content}}</div>

原生方法:

<script>
    var dom = document.getElementById(\'app\');
    dom.innerhtml = \'helloworld\';
</script>

Vue 方法:

<script>
    //创建Vue实例
    var app = new Vue({
        //el项 :Vue实例接管的区域
        el: "#app",
        //定义数据
        data: {
            content: "helloworld!"
        }
    }); 
</script>

 

2.两秒后修改文字

<div id="app">{{content}}</div>

 

原生方法:

var dom = document.getElementById(\'app\');
dom.innerHTML = \'helloworld\';

setTimeout(function() {
    dom.innerHTML = \'byeworld\';
},2000)

 

Vue 方法:

var app = new Vue({
    el: "#app",
    data: {
        content: "helloworld!"
    }
});

setTimeout(function() {
    //$data 是 data的别名,指 data 对象
    app.$data.content = "byeworld!";
},2000);

 

 

当书写 vue 时,不需要关注DOM操作,而是要注重数据的管理,当数据发生变化时,页面就会跟着变。

 

3.Vue实现简单的TodoList

<div id="app">
    <!-- 
        v-model 双向绑定,当表单框内容发生改变时,对应的data内的数据也会发生改变,反之同理
    -->
    <input type="text" v-model="inputValue"/>
        <!-- v-on绑定事件-->
    <button v-on:click="handleBtnClick">提交</button>
    <ul>
        <!--
            循环 list 数据,循环的每一项都放到 item 内,list有几项就会循环出几个 li 标签
        -->
        <li v-for="item in list">{{item}}</li>
    </ul>
</div>

<script type="text/javascript">
    
    var app = new Vue({
        el: \'#app\',
        data: {
            // 但是页面一开始都是干净的
            // list: [\'第一课内容\', \'第二课内容\',\'2333333\']
            list: [],
            inputValue: \'\'
        },
        // 方法都放在 methods 里
        methods: {
            handleBtnClick: function() {
                // 因为 li 遍历 list,每次点击获取input中的内容添加到 list 数组内
                this.list.push(this.inputValue);
                this.inputValue = \'\';
            }
        }
    });
    
</script>

 

 

4.MVVM模式

传统的MVP设计模式:面向DOM开发

Model —— Presenter —— View

模型层(数据层) —— 业务逻辑控制层 —— 视图层

 

jQuery 实现 todolist

当按钮点击时视图被操作,控制器会执行,通过DOM操作改变视图

<div>
    <input id="input" type="text" />
    <button id="btn">提交</button>
    <ul id="list"></ul>
</div>

<script>
    // 构造函数
    function Page() {
        
    }
    /*    $.extend()函数用于将一个或多个对象的内容合并到目标对象,
        此处给显示原型添加init方法        */
    $.extend(Page.prototype,{
        init: function() {
            this.bindEvents();
        },
        bindEvents: function() {
            var btn = $(\'#btn\');
            // $.proxy() 用来改变 this 将上下文环境的this,改变为要执行函数内的this
            // 也可以用 btn.on(\'click\',this.handleBtnClick),因为handleBtnClick内部不需要 this
            btn.on(\'click\',$.proxy(this.handleBtnClick, this));
        },
        handleBtnClick: function() {
            var inputElem = $(\'#input\');
            var inputValue = inputElem.val();
            var ulElem = $(\'#list\');
            ulElem.append(\'<li>\'+ inputValue +\'</li>\');
            inputElem.val(\'\');
        }
    })
    
    var page = new Page();
    page.init();
</script>

 

 MVVM 设计模式:面向数据开发

 

无需任何DOM 操作,全部操作数据(M层),V层自动改变,由VM层来实现。

 VM层:

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

虚拟DOM。

 

5.使用组件化思想修改TodoList

<div id="app">
    <input type="text" v-model="inputValue"/>
    <button v-on:click="handleBtnClick">提交</button>
    <ul>
        <!--使用组件-->
        <!--向子组件传入一个绑定值-->
        <!--循环list 每一项,通过content变量传给了 todo-item 子组件 -->
        <todo-item 
            v-bind:content="item" 
            v-for="(item, index) in list" 
            v-bind:index="index" 
            @delete="handleItemDelete">
        </todo-item>
    </ul>
</div>

<script type="text/javascript">
    // 定义全局组件
    Vue.component(\'todo-item\',{
        // 从父组件接收一个 content参数
        props: [\'content\',\'index\'],
        // 依然用插值符接收
        template: "<li @click=\'handleItemClick\'>{{content}}</li>",
        methods: {
            handleItemClick: function() {
                //点击子组件,子组件会向外触发一个 delete 事件 
                this.$emit("delete")
            }
        }
    });
    
    /*
     定义局部组件
         var TodoItem = {
        props: [\'content\'],
        template: "<li>{{content}}</li>"
    }
    */
    
    // Vue实例 其实就是父组件
    // #app 标签下的所有内容实际上就是父组件的模板
    var app = new Vue({
        el: \'#app\',
        /*    
        在实例中使用局部组件
        components: {
            // 组件名:变量名
            \'todo-item\': TodoItem
        },
        */
        data: {
            list: [],
            inputValue: \'\'
        },
        methods: {
            handleBtnClick: function() {
                this.list.push(this.inputValue);
                this.inputValue = \'\';
            },
            handleItemDelete: function(index) {
                this.list.splice(index,1);
            }
        }
    });
    
</script>

 

 

 6.简单的组件间传值

父组件向子组件传值:在子组件用 v-bind 动态绑定一个变量 ,把对应的值传给该变量。

子组件向父组件传值:通过 $emit() 的方式自定义事件,子组件触发父子间设置事件监听。

 

二、Vue 基础

1.Vue 实例

一个程序进行加载的时候,入口点是 new Vue() 实例,也叫根实例,其次Vue 中的每一个组件也是一个实例。

一个Vue 项目是由无数个实例组成的。

Vue的实例属性由 $ 符开头,如:vm.$data   vm.$el

vm.$destroy() :作用是销毁vue 实例

 

2.生命周期钩子

 

 

 

 

 

beforeCreate

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

created

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

beforeMount

在挂载开始之前被调用:相关的 render 函数首次被调用。

mounted

el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。

beforeUpdate

数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。

updated

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。

该钩子在服务器端渲染期间不被调用。

beforeDestroy

实例销毁之前调用。在这一步,实例仍然完全可用。

destroyed

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

 

 3.Vue 的模板语法

{{}} :插值表达式

Vue 指令对应的内容都是JS表达式

v-text :让该元素的innerText 内容变成绑定的变量所对应的值,功能同 {{}}

v-html :让该元素的innerHTML 内容变成绑定的变量所对应的HTML内容

v-on :事件绑定

v-bind :属性动态绑定

 

 4.计算属性,方法和侦听器

 

<div id="app">
    <!--最好不要在模板上出现逻辑-->
    <!-- {{firstName + \' \' + lastName}} -->
    {{fullName}}
    {{age}}
</div>

<script>
    
    var vm = new Vue({
        el: "#app",
        data: {
            firstName: \'Anqw\',
            lastName: \'Joe\',
            fullName: \'Anqw Joe\',
            age: 25
        },
        // 方法一:侦听器,内置缓存,但是代码复杂很多
        watch: {
            // 当firstName 发生改变时
            firstName: function() {
                console.log("计算了一次");
                this.fullName = this.firstName + \' \' + this.lastName;
            },
            //当 lastName 发生改变时
            lastName: function() {
                console.log("计算了一次");
                this.fullName = this.firstName + \' \' + this.lastName;
            }
        }
        
        // 方法二:计算属性,内置缓存,简洁性能高,优先推荐
        /*computed: {
            fullName: function() {
                
                     fullName 依赖 firstName 与 lastName ,
                     当这二者没有发生改变时,计算属性就不会重新计算,
                     继续使用上次计算结果
                 
                console.log("计算了一次");
                return this.firstName + \' \' + this.lastName;
            }
        }*/
        
        /*
        //    方法三:定义方法函数,每次都会重新执行一次     
        methods: {
            fullName: function() {
                console.log("计算了一次");
                return this.firstName + \' \' + this.lastName;
            }
        }
        */
    });
    
</script>

 

 

 5.计算属性的 setter 和 getter

 

<div id="app">
    <!--这里 fullName 也会跟着改变-->
    {{fullName}}
</div>

<script>
    
    var vm = new Vue({
        el: "#app",
        data: {
            firstName: \'Anqw\',
            lastName: \'Joe\'
        },
        computed: {
            fullName: {
                // 读取时会走 get 方法
                get: function() {
                    // 执行set()后值会改变,因此重新计算 fullName 
                    return this.firstName +\' \'+ this.lastName;
                },
                // 设置属性值走 set 方法
                set: function(value) {
                    // 设置 fullName 值,value会被打印出来
                    //console.log(value);
                    var arr = value.split(\' \');
                    this.firstName = arr[0];
                    this.lastName = arr[1];
                }
            }
        }
    });
    
</script>

 

6.Vue 的样式绑定

<div id="app">
    <!--动态的向一个DOM元素 去添加或删除一个类,实现页面效果的变更-->
    <!--方法一:class的对象绑定-->
    <!--isActivated 为 true时,activated的样式名字就会显示-->
    <div @click="handleDivClick1" 
        :class="{activated: isActivated}">
        hello world
    </div>
    
    <!--方法二:class和数组绑定-->
    <!--把样式名传入变量中以数组的形式绑定给 class-->
    <div @click="handleDivClick2" 
        :class="[activated, activatedOne]">
        bye world
    </div>
    
    <!--用style 改变样式-->
    <!--方法三:把样式对象直接传入变量中,与style绑定-->
    <div :style="styleObj" @click="handleDivClick3">touch world</div>
    
    <!--方法四: 把样式变量直接传入数组中,或直接把样式写进去-->
    <div :style="[styleObj,{fontSize: \'20px\'}]" @click="handleDivClick3">love world</div>
    
</div>
    
<script>
    
    var vm = new Vue({
        el: "#app",
        data: {
            //变量存放布尔值
            isActivated: false,
            //变量存放 class名
            activated: \'\',
            activatedOne: \'activated-one\',
            //变量存放样式
            styleObj: {
                color: "black"
            }
        },
        methods: {
            handleDivClick1: function() {
                //点击改变 class名绑定的布尔值 
                this.isActivated = !this.isActivated;
            },
            handleDivClick2: function() {
                //点击改变 class名
                this.activated = this.activated === \'activated\' ? \'\' : \'activated\';
            },
            handleDivClick3: function() {
                //点击直接改变样式
                this.styleObj.color = this.styleObj.color ===\'black\' ? \'red\' : \'black\'
            }
        }
    });
    
</script>

 

class 绑定:

  • 将 布尔值 赋给变量,变量 与 class样式名 以对象形式绑定
  • 将 class 样式名赋给变量,变量以数组形式绑定

style 绑定