Vue.js

Vue.js是一个基于MVVM思想的前端框架和angular类似

首先要引用它的js文件

和js一样直接下载源文件引用就可以

但是这次用一个别的方式

通过BootCDN加速服务引用

官网:http://www.bootcdn.cn/

这个网站里有很多前端

里面有很多前端的插件,点进去后有链接,把链接直接复制过去就可以使用,这样就不需要下载为本地文件了,为项目节省的空间,但是使用时必须联网

(简单说其实就是cdn开了一个服务器帮你存储这些文件,你通过网络访问它的服务器)

 下面进入正题

Vue.js的核心是一个简洁的模板语法

写模板时需要一个容器

<!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="https://cdn.bootcss.com/vue/2.5.9/vue.js"></script>
</head>
<body>
    <!--↓h1就是一个容器,{{bug}}为占位符-->
    <h1 id="Id">{{bug}}</h1>
</body>
</html>
<script>
    //↓Vue对象
    var app = new Vue({
        el:"#Id", //要操作的容器
        data:{
            bug:"值" //为容器中的占位符赋真实的值
        }
    });
</script>

这样在运行网页时,{{bug}}就会替换为值

{{}}中不止可以放属性名称,还可以放一些简单的运算符(一行就可以结束,且得出结果的,如三目运算符)

<div>{{100/2*8}}</div>
<div>{{sex==1?"男":"女"}}</div>

除了给标签复制,我们还能为标签添加属性

 <div id="d" v-bind:href="msg">aaaaaa</div>

<script>
    var app = new Vue(
    {
        el:"#d",
        data:{
            msg:"链接"
        }
    });
</script>

除了href.其他属性也可以通过v-bind绑定,如class,name等

v-bind可以省略,简写为

<div id="d" :href="msg">aaaaaa</div>

如果要绑定事件用 v-on

<div id="d" :href="msg">
        <div v-on:click="fangfa">点击事件</div>
</div>

<script>
    var app = new Vue(
    {
        el:"#d",
        data:{
            msg:"链接"
        },methods:{
            fangfa:function(){
                alert("点击了");
            }
        }
    });

这里我们在Vue对象里加了一个methods,是用来创建方法的

v-on也是有简写方法

 <div @click="fangfa">点击事件</div>

插一个有趣的小功能,文字反转

<div id="d" :href="msg">       
       <div>{{msg}}</div>
        <button @click="fangfa">反转</button>
</div>

<script>
    var app = new Vue(
    {
        el:"#d",
        data:{
                msg:"balabaaanalsdakdjakkasnckasncasncjksksnkdsnkfsk"
        },
        methods:{
            fangfa:function(){
                this.msg = this.msg.split('').reverse().join('')
            }
        }
    });
</script>    

reverse() 把数组中元素的顺序颠倒

到这里为止,我们之前的操作都是数据绑定到页面的单向绑定,那么我们怎么才能让页面也绑定到数据,实现双向绑定呢?

在页面的标签上添加v-model属性

<div id="d" :href="msg">        
        <div>{{msg}}</div>
        <input type="text" v-model="msg">
        <button @click="fangfa">反转</button>
</div>

<script>
    var app = new Vue(
    {
        el:"#d",
        data:{
            msg:"balabaaanalsdakdjakkasnckasncasncjksksnkdsnkfsk"
        },
        methods:{
            fangfa:function(){
                this.msg = this.msg.split('').reverse().join('')
            }
        }
    });
</script>

这样文本框就和msg进行了绑定,文本框的值改变msg的值也会随之改变

之前我们有说过{{}}可以放简单的运算,但是也只是简单的,如果我们需要进行复杂的计算时,就要用到计算属性 computed

<div id="d" :href="msg">
        <div>{{jisuan}}</div>
</div>

<script>
    var app = new Vue(
    {
        el:"#d",
        computed:{
            jisuan:function(){
                if(1+1<3){
                    return "小于"
                }else{
                    return "大于"
                }
            }
        }
    });
</script>

在computed中可以声明方法,然后在方法总进行操作,最终把结果返回出来

在{{}}写上方法的名称,就会调用这个方法,然后把返回值作为实际的值显示

计算属性中是可以写get和set的

computed:{
            jisuan:{
                get:function(){
                    
                },
                set:function(){
                    
                }
            }
        }

虽然大部分情况使用计算属性就很合适,但是有时也会需要一个监听器 watch

<input type="text" v-model="zhanghao">
<div>{{answer}}</div>

<script>
    var app = new Vue(
    {
        el:"#d",
        data:{
            zhanghao:"",
            answer:""
        },
        watch:{
            //监视zhanghao属性,如果zhanghao发生改变就会调用此方法
            zhanghao:function(){
                if(this.zhanghao.length<6){
                    this.answer = "账号必须大于6位"

                }else{
                    this.answer = "OK"
                }

            }
        }
    });
</script>

判断和循环

v-if和v-for的作用就不解释了,直接看语法吧

     <div v-if="true">显示</div> 
        <!-- if为false,继续判断else if -->
        <div v-if="false">不显示</div> 
        <!-- else if为true 显示这个标签 -->
        <div v-else-if="true">不显示2</div>
        <!-- else if只会进一个,所以这个为true也不会显示 -->
        <div v-else-if="true">不显示3</div>
        <!-- 如果上边都不进就会显示这个 -->
        <div v-else>else</div>
<div v-for="(item,index) in arr">
       <div>{{item}}</div>
</div>

<script>
    var app = new Vue(
    {
        el:"#d",
        data:{
            arr:[1,2,3,4,5]
        }
    });
</script>

item是值,index是下标,arr是要循环的数组

自定义指令

 我们之前使用了很多vue自身的指令如 v-bing,v-model等等

那么如果我们要自己定义个指令呢

比如

<div v-show="">输出</div>

vue中是没有v-show这个指令的,我们需要通过Vue.directive来创建自定义的指令

Vue.directive是一个全局API

全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,说的简单些就是,在构造器外部用Vue提供给我们的API函数来定义新的功能。

下面讲解Vue.directive的使用

<div id="vue">
        <div v-show="info">输出</div>
</div>

<script>
        Vue.directive('show',function(el,binding,vnode){
            console.info(el);
            console.info(binding);
            console.info(vnode);
        });
        var app = new Vue({
            el:"#vue",
            data:{
                info:10
            }
        })
</script>

这样我们就完成了自定义一个v-show指令,注意定义时不需要加v-,但是使用时别忘了加上v-

我们输出了方法中的三个参数,接下来我们来看一下这三个参数都是什么作用

第一个参数 : el

一看就懂,el这个参数就是代表当前使用这个指令的标签,你可以通过这个参数对这个标签做一些操作,比如获取内容,改变样式等

第二个参数 : binding

这个参数存放的是这个指令的一些属性,如指令的名字,传给指令的值等

我们可以把传给指令的值加入到操作中,然后就可以达到传不同的值出现不同结果的效果

小例子:点击字体变大

  <div id="vue">
        <div v-show="size">字体</div>
        <button @click="change">变大</button>
    </div>
    <script>
        Vue.directive('show',function(el,binding,vnode){
            el.style='font-size:'+binding.value+'px';
            
        });
        var app = new Vue({
            el:"#vue",
            data:{
                size:20
            },
            methods:{
                change:function(){
                    this.size++;
                }
            }
        })
    </script>

第三个参数 : vnode

一样是当前使用这个指令的标签,但是和el不同的是,它是虚拟节点,el是实际的标签,用js去操作页面上的标签做出更改,比较耗费性能,而vnode则是标签的抽象,是一个js对象,操作js对象性能就会大大提升

它的属性和标签的属性是对应的,当属性改变时,页面也会相应改变 (然而我其实并不是很懂这东西怎么用)

   /*当前节点的标签名*/
    this.tag = tag
    /*当前节点对应的对象,包含了具体的一些数据信息,是一个VNodeData类型,可以参考VNodeData类型中的数据信息*/
    this.data = data
    /*当前节点的子节点,是一个数组*/
    this.children = children
    /*当前节点的文本*/
    this.text = text
    /*当前虚拟节点对应的真实dom节点*/
    this.elm = elm
    /*当前节点的名字空间*/
    this.ns = undefined
    /*编译作用域*/
    this.context = context
    /*函数化组件作用域*/
    this.functionalContext = undefined
    /*节点的key属性,被当作节点的标志,用以优化*/
    this.key = data && data.key
    /*组件的option选项*/
    this.componentOptions = componentOptions
    /*当前节点对应的组件的实例*/
    this.componentInstance = undefined
    /*当前节点的父节点*/
    this.parent = undefined
    /*简而言之就是是否为原生HTML或只是普通文本,innerHTML的时候为true,textContent的时候为false*/
    this.raw = false
    /*静态节点标志*/
    this.isStatic = false
    /*是否作为跟节点插入*/
    this.isRootInsert = true
    /*是否为注释节点*/
    this.isComment = false
    /*是否为克隆节点*/
    this.isCloned = false
    /*是否有v-once指令*/
    this.isOnce = false

自定义指令有五个生命周期(也叫钩子函数),分别是 bind,inserted,update,componentUpdated,unbind

  1. bind:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作。
  2. inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)。
  3. update:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
  4. componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
  5. unbind:只调用一次,指令与元素解绑时调用。 
Vue.directive('show',{
            bind:function(){//被绑定时
                console.log('1 - bind');
            },
            inserted:function(){//绑定到节点后
                console.log('2 - inserted');
            },
            update:function(){//组件更新时
                console.log('3 - update');
            },
            componentUpdated:function(){//组件更新完成后
                console.log('4 - componentUpdated');
            },
            unbind:function(){//解绑
                console.log('1 - bind');
            }
        });

Vue.extend构造器

用来把写好的模板挂载到自定义的标签上 (我是真看不出和下面的component有什么区别,但是姑且还是记下来吧)

<link></link> //自定义的标签


 var authorExtend = Vue.extend({ //模板的对象
            template:'<a :href="link">链接</a>',
            data:function(){
            return{
                  link:'http://www.baidu.com'
                  }
            }
});
 new authorExtend().$mount('link'); //将对象挂载到自定义标签上

也可以挂载到普通的标签上,只要填上标签的id就行

<div id="link"></div>

new authorExtend().$mount('#link');

如果不想在创建模板对象时在data中给数据,而是在挂载标签时给

可以使用propsData

propsData三步解决传值:

1、在全局扩展里加入props进行接收。props:[‘a’]

2、传递时用propsData进行传递。propsData:{a:1}

3、用插值的形式写入模板。{{ a }}

<div id="link"></div>

<script>
        var authorExtend = Vue.extend({
            template:'<a :href="link">链接</a>',
            data:function(){
            return{
                  
                  }
            },
            props:['link']
        });
        new authorExtend({propsData:{link:'http://www.baidu.com'}}).$mount('#link');
</script>

自定义组件

自定义组件其实就是自定义一个标签

<com></com>

<script>
    Vue.component('com',{
        template:"<div>这是一个组件</div>"
    });
</script>

第一个参数是自定义的标签,之后的template是模板

现在com标签就等同于''<div>这是一个组件</div>'',当然你也可以在模板里多写点标签,这样一大段标签就变成了一个标签,省了很多事

但是这样写的话,值岂不是都是固定的,这样肯定是不行的,我们要进行一些改进

<com v-for="(item,index) in arr" :items="item"></com>


<script>
    Vue.component('com',{
        props:['items'],
        template:"<div>{{items}}</div>"
    });

    var app = new Vue(
    {
        el:"#d",
        data:{
            arr:[1,2,3,4,5]
        }
    }
</script>

props类似于自定义属性,然后在模板使用这个自定义的属性,并在标签上通过v-bind把自定义属性绑定上去,再给自定义属性赋值

这样模板的值就是动态的了

如果自定义属性带有 - 

我们在写属性时经常会加入’-‘来进行分词,比如:<panda   from-here=”China”></panda>,那这时我们在props里如果写成props:[‘form-here’]是错误的,我们必须用小驼峰式写法props:[‘formHere’]。

局部注册组件

<div id="vue">
        <lianjie :src="a"></lianjie>
</div>

<script>
        var app = new Vue({
            el:"#vue",
            data:{
                a:'http://www.baidu.com'
            },
            components:{
                "lianjie":{
                    template:'<a :href="src">{{src}}</a>',
                    props:['src']
                }
            }
        })
 </script>

可以看出,其实局部注册就是在Vue对象中注册自定义组件,但是要注意局部注册用的components,而上面是component,要多一个s

这样把所有属性全部都写在Vue对象里,如果组件多了会感觉很乱,我们可以把它们的属性设置提出去

var lianjie = {
                    template:'<a :href="src">{{src}}</a>',
                    props:['src']  
                };

var app = new Vue({
            el:"#vue",
            data:{
                a:'http://www.baidu.com'
            },
            components:{
                "lianjie":lianjie
            }
})

组件之间是可以相互嵌套的

<script>
        var son = {
                    template:'<div>子项</div>'
                } 
        var lianjie = {
                    template:'<a :href="src">{{src}} <son></son> </a>',
                    props:['src'],
                    components:{
                        "son":son
                    }
                };
        
       
        
        var app = new Vue({
            el:"#vue",
            data:{
                a:'http://www.baidu.com'
            },
            components:{
                "lianjie":lianjie
            }
        })
    </script>

注意模板只能有一个根标签

Component标签

Component标签是用来动态绑定组件的

小例子:点击切换组件

<div id="vue">
        <component :is="who"></component>
        <button @click="change">切换组件</button>
    </div>
    <script>
       
       var tempA={
            template:'<div>模板A</div>'
       }
       var tempB={
            template:'<div>模板B</div>'
       }
       var tempC={
            template:'<div>模板C</div>'
       }
        
       
        
        var app = new Vue({
            el:"#vue",
            data:{
                who:'tempA' 
            },
            components:{
                "tempA":tempA,
                "tempB":tempB,
                "tempC":tempC
            },
            methods:{
                change:function(){
                    if(this.who=='tempA'){
                        this.who='tempB';
                    }else if(this.who=='tempB'){
                        this.who='tempC';
                    }else{
                        this.who='tempA';
                    }
                }
            }
        })
    </script>
原文地址:https://www.cnblogs.com/nicopoiduang/p/7954701.html