vue.js 2.0学习记录第二天

194 阅读13分钟

我的vue.js 2.0学习路线是参考技术胖老师的博客,感谢!

一、v-model指令

v-model指令,就是在表单控件或者组件上创建双向绑定。

修饰符:

.lazy - 取代 input 监听 change 事件
.number - 输入字符串转为有效的数字
.trim - 输入首尾空格过滤

完整html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-model</title>
</head>
<body>
<h1>v-model用法</h1>
<hr/>
<div id="app">

    <p>原始文本信息:{{message}}</p>
    <h3>文本框</h3>
    <p>v-model:<input type="text" v-model="message"></p>

    <p>v-model:<input type="text" v-model.lazy="message"></p>
    <p>v-model:<input type="text" v-model.number="message"></p>
    <p>v-model:<input type="text" v-model.trim="message"></p>

    <!--一个25个字符宽1行高的文本区-->
    <textarea cols="25" rows="1" v-model="message"></textarea>

    <h3>多选按钮绑定一个值</h3>
    <input type="checkbox" id="isTrue" v-model="isTrue">
    <label for='isTrue'>{{isTrue}}</label>

    <h3>多选绑定一个数组</h3>
    <p>
        <input type="checkbox" id="JSPang" value="JSPang" v-model="web_Names">
        <label for="JSPang">JSPang</label><br/>
        <input type="checkbox" id="Panda" value="Panda" v-model="web_Names">
        <label for="Panda">Panda</label><br/>
        <input type="checkbox" id="PanPan" value="PanPan" v-model="web_Names">
        <label for="PanPan">PanPan</label>
    <p>{{web_Names}}</p>
    </p>

    <h3>单选按钮绑定</h3>
    <input type="radio" id="one" value="男" v-model="sex">
    <label for="one">男</label>
    <input type="radio" id="two" value="女" v-model="sex">
    <label for="two">女</label>
    <p>{{sex}}</p>
</div>
<script src="js/vue.min.js"></script>
<script>
var vue=new Vue({
    el:'#app',
    data:{
        message:'hello vue!',
        isTrue:true,
        web_Names:['JSPang'],
        sex:'男'
    },
    methods:{
        add:function () {
            this.count++;
        },
        sub:function () {
            this.count--;
        },
        onEnter:function () {
            if(this.secondCount.length>0)
            {
                this.count=this.count+parseInt(this.secondCount)
            }

        }
    }
})
</script>
</body>
</html>

二、v-bind指令

v-bind可以动态地绑定一个或多个特性,或一个组件 prop 到表达式。在绑定 class 或 style 特性时,支持其它类型的值,如数组或对象。

完整html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-bind指令</title>
    <style>
        .classA{
            color: #ee453e;
        }
        .classB{
            font-weight: bold;
        }
    </style>
</head>
<body>
<h1>v-bind指令</h1>
<hr/>
<div id="app">
    <img v-bind:src="imgSrc"  width="200px">
    <img :src="imgSrc"  width="200px"><!--v-bind缩写形式:-->

    <!--绑定css样式-->
    <div :class="className">1、绑定classA</div>
    <div :class="{classA:isOk}">2、绑定class中的判断.isOk:{{isOk}}</div>
    <div :class="[className1,className2]">3、绑定class中的数组</div>
    <div :class="isOk?className1:className2">4、绑定class中的三元表达式判断.isOk:{{isOk}}</div>
    <div :style="{color:red,fontSize:font}">5、绑定style</div>
    <div :style="styleObject">6、用对象绑定style样式</div>
</div>
<script src="js/vue.min.js"></script>
<script>
var vue=new Vue({
    el:'#app',
    data:{
        imgSrc:'https://ss1.baidu.com/9vo3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=ad628627aacc7cd9e52d32d909032104/32fa828ba61ea8d3fcd2e9ce9e0a304e241f5803.jpg',
        className:'classA',
        isOk:false,
        className1:'classA',
        className2:'classB',
        red:'red',
        font:'20px',
        styleObject:{
            fontSize:'24px',
            color:'green'
        }
    }
})
</script>
</body>
</html>

三、其他内部指令(v-pre & v-cloak & v-once)

v-pre指令
在模板中跳过vue的编译,直接输出原始值。就是在标签中加入v-pre就不会输出vue中的data值了。

v-cloak指令
这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

v-once指令
只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

完整html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>其他内部指令(v-pre & v-cloak & v-once)</title>
    <style>
        [v-cloak] {
            display: none!important;/*为了防止被优先级别高的样式覆盖,添加!important*/

        }
    </style>
</head>
<body>
<h1>其他内部指令(v-pre & v-cloak & v-once)</h1>
<hr/>
<div id="app">
    <div v-pre>{{message}}</div>

    <div v-cloak>
        {{ message }}
    </div>

    <div v-once>第一次绑定的值:{{message}}</div>
    <div><input type="text" v-model="message"></div><!--修改message的值,上方div{{message}}的值不会改变-->
</div>
<script src="js/vue.min.js"></script>
<script>
var vue=new Vue({
    el:'#app',
    data:{
        message:'hello vue!'
    }
})
</script>
</body>
</html>

四、Vue.directive 自定义指令

除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。

自定义指令的生命周期
一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode更新之前。指令的值可能发生了改变, 也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

    接下来我们来看一下钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。

自定义指令中传递的三个参数

  • el:指令所绑定的元素,可以用来直接操作 DOM 。
  • 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 }。
  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

完整html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue.directive 自定义指令</title>
</head>
<body>
<h1>Vue.directive 自定义指令</h1>
<hr/>
<div id="app">
   <div v-color="color">
       {{num}}
   </div>
    <button @click="add">Add</button>
</div>
<script src="js/vue.min.js"></script>
<script>
    Vue.directive('color',{
        bind:function(){//被绑定
            console.log('1 - bind');
        },
        inserted:function (el,binding,vnode) { //el: 指令所绑定的元素,可以用来直接操作DOM。binding: 一个对象,包含指令的很多信息。vnode: Vue编译生成的虚拟节点。
                el.style='color:'+binding.value;
            },
        update:function(){//组件更新
            console.log('3 - update');
        },
        componentUpdated:function(){//组件更新完成
            console.log('4 - componentUpdated');
        },
        unbind:function(){//解绑
            console.log('1 - bind');
        }
    })
var vue=new Vue({
    el:'#app',
    data:{
        num:10,
        color:'green'
    },
    methods:{
        add:function () {
            this.num++;
        },

    },

})
</script>
</body>
</html>

五、Vue.extend构造器的延伸

Vue.extend 返回的是一个“扩展实例构造器”,也就是预设了部分选项的Vue实例构造器。经常服务于Vue.component用来生成组件,可以简单理解为当在模板中遇到该组件名称作为标签的自定义元素时,会自动调用“扩展实例构造器”来生产组件实例,并挂载到自定义元素上。

完整html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue.extend-扩展实例构造器</title>
</head>
<body>
<h1>vue.extend-扩展实例构造器</h1>
<hr/>
<div id="app">
    <!--<author></author>-->

    <div id="author"></div>
</div>
<script src="js/vue.min.js"></script>
<script>
    var authorExtend=Vue.extend({
        template:'<p><a :href="authorHref">{{authorName}}</a></p>',
        data:function () {
            return{
                authorHref:'https://baidu.com',
                authorName:'百度'
            }
        }
    })
    // new authorExtend().$mount('author')
    //还可以通过HTML标签上的id或者class来生成扩展实例构造器,Vue.extend里的代码是一样的,只是在挂载的时候,我们用类似jquery的选择器的方法,来进行挂载就可以了。
    new authorExtend().$mount('#author')
</script>
</body>
</html>

六、Vue.set全局操作

向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = 'hi')

由于 JavaScript 的限制, Vue 不能检测以下变动的数组:

  1. 利用索引直接设置一个项时,例如: vm.items[indexOfItem] = newValue

  2. 修改数组的长度时,例如: vm.items.length = newLength

为了避免以上情况,以下两种方式将达到像 vm.items[indexOfItem] = newValue 的效果, 同时也将触发状态更新:

  1. Vue.set(example1.items, indexOfItem, newValue)

  2. example1.items.splice(indexOfItem, 1, newValue)

完整html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue.set 全局操作</title>
</head>
<body>
<h1>Vue.set 全局操作</h1>
<hr/>
<div id="app">
    <p v-for="item in items" :key="item.id">
        {{item.message}}
    </p>
    <button class="btn" @click="btn1Click()">点我试试</button>
    <button class="btn" @click="btn2Click()">动态赋值</button><br/><br/>
    <button class="btn" @click="btn3Click()">为data新增属性</button>
    <br/>
</div>
<script src="js/vue.min.js"></script>
<script>
    var vue = new Vue({
        el: '#app',
        data: {
            items: [
                {message: "Test one", id: "1"},
                {message: "Test two", id: "2"},
                {message: "Test three", id: "3"}
            ],
        },
        methods: {
            btn1Click: function () {
                // this.items[3]={message:"Change Test",id:'10'};
                this.items.splice(3,1,{message: "动态新增",id:'4'});//为data中的items动态新增一条数据
                console.log(this.items)
            },
            btn2Click: function () {
               // this.items[0]={message:"Change Test",id:'10'}
               //console.log(this.items)

                 Vue.set(this.items,0,{message:"Change Test",id:'10'})
            },
            btn3Click: function () {
                var itemLen=this.items.length;
                Vue.set(this.items,itemLen,{message:"Test add attr",id:itemLen+1});
                console.log(this.items)
            }
        }
    })
</script>
</body>
</html>

七、Vue的生命周期

Vue实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁等一系列过程,我们称这是Vue的生命周期。通俗说就是Vue实例从创建到销毁的过程,就是生命周期。

每一个组件或者实例都会经历一个完整的生命周期,总共分为三个阶段:初始化、运行中、销毁。

  1. 实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的dom,一般不做操作

  2. 挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取

  3. 接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取

  4. 接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情...

  5. 当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿

  6. 当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的虚拟dom

  7. 当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等

  8. 组件的数据绑定、监听...去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以。

完整html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="js/vue.min.js"></script>
    <title>构造器的声明周期</title>
</head>
<body>
<h1>构造器的声明周期</h1>
<hr>
<div id="app">
    {{message}}
    <p><button @click="jia">加分</button></p>
</div>
<button onclick="app.$destroy()">销毁</button>

<script type="text/javascript">
    var app=new Vue({
        el:'#app',
        data:{
            message:1
        },
        methods:{
            jia:function(){
                this.message ++;
            }
        },
        beforeCreate:function(){
            console.log('1-beforeCreate 初始化之后');
        },
        created:function(){
            console.log('2-created 创建完成');
        },
        beforeMount:function(){
            console.log('3-beforeMount 挂载之前');
        },
        mounted:function(){
            console.log('4-mounted 被创建');
        },
        beforeUpdate:function(){
            console.log('5-beforeUpdate 数据更新前');
        },
        updated:function(){
            console.log('6-updated 被更新后');
        },
        beforeDestroy:function(){
            console.log('9-beforeDestroy 销毁之前');
        },
        destroyed:function(){
            console.log('10-destroyed 销毁之后')
        }

    })
</script>
</body>
</html>

八、Template 制作模版

一、直接写在选项里的模板

直接在构造器里的template选项后边编写。这种写法比较直观,但是如果模板html代码太多,不建议这么写。

二、写在template标签里的模板

这种写法更像是在写HTML代码,就算不会写Vue的人,也可以制作页面。

三、写在script标签里的模板 这种写模板的方法,可以让模板文件从外部引入。

完整html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Template 制作模版</title>
    <script type="text/javascript" src="js/vue.min.js"></script>

</head>
<body>
    <h1>Template 制作模版</h1>
    <hr>

    <div id="app"></div>

    <template id="demo2">
        <h2 style="color:red">我是template标签模板</h2>
    </template>

    <script type="x-template" id="demo3">
        <h2 style="color:red">我是script标签模板</h2>
    </script>
<script>
    var app=new Vue({
        el:'#app',
        data:{
            message:'hello Vue!'
        },
        template:`
        <h1 style="color:red">我是选项模板</h1>
     `,
        template:'#demo2',
        template:'#demo3'
    })
</script>
</body>
</html>

九、Component初识组件

component组件是Vue学习的重点、重点、重点,重要的事情说三遍。所以你必须学好Vue component。其实组件就是制作自定义的标签,这些标签在HTML中是没有的。

组件和指令的区别
组件注册的是一个标签,而指令注册的是已有标签里的一个属性。在实际开发中我们还是用组件比较多,指令用的比较少。因为指令看起来封装的没那么好,这只是个人观点。

完整html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Component初识组件</title>
</head>
<body>
<h1>component-1</h1>
<hr>
<div id="app">
    <!--全局化注册组件-->
    <component1></component1>
    <!--局部注册组件-->
    <component2></component2>
</div>
<script type="text/javascript" src="js/vue.min.js"></script>
<script>
    // 全局化注册组件
    Vue.component('component1',{
        template:`<div style="color:red;">全局化注册的component1标签</div>`
    })
    var app=new Vue({
        el:'#app',
        data:{
        },
        //局部注册组件
        components:{
            "component2":{
                template:`<div style="color:red;">局部注册的component2标签</div>`
            }
        }
    })
</script>
</body>
</html>

好啦,今天就学习了这些,拜拜~