Vue前端Js框架

简单来说,Vue是针对Javascript提供的一套MVVM框架,该框架可以让我们布局与视图分离,减少数据泥团,同时也是组件开发较实用的一套框架,如果你之前学习过Android的DataBinding框架,可以尝试将思维进行沿用。话不多说,接下来介绍该框架如何使用:

1.下载源代码

首先可以在github上找到托管的代码,也可以通过官网进行了解,建议读者先学习本套课程,再通过官网继续深入学习。

1.打开官网,点击导航上的教程
2.点击tab页面左边的 安装
3.这里介绍了如果安装,你可以将vue.js直接另存为保存起来,也可以通过mpn命令下载

npm install vue 

4.下载成功后,会出现一个 node_modules文件夹,将/vue/dist/vue.js(和vue.min.js)复制到我们的项目中。

2.新建项目引入开发包

这里我使用的是WebStorm进行开发的。我的项目目录如下:
这里写图片描述

3.vue的原理

vue最的核心是ViewModel,他的示意图如下:
这里写图片描述

上面的示意图主要分为三部分:
DOM:它指代的是Html标签形成的Dom树。也就是每次标签都是Dom的一个环节,操作Dom即是操作Html的视图区。
JavaScript Objects:代表的是data数据。
Vue:也是我们的核心,称之为ViewModel。一般视图区与数据直接混合很容易造成数据混乱,所以你可以认为ViewModel相当于两者的桥梁。数据的变化会导致视图的变化,视图的操作也可以直接操作数据。

4.一个简单的示例

既然已经了解了其原理,接下来我们来写一个h5页面,代码如下:

<body>
        <script src="../js/vue.js"></script>
    <!-- 1.创建一个需要被操作的视图盒子 -->
    <div id="box1">
        <!-- 6.引用字符串message -->
        <p>{{message}}</p>
        <!-- 7.v-model指定输入框引用字符串message -->
        <input v-model="message">
    </div>

    <script>
        /*2.创建一个ViewModel实例*/
        var vm=new Vue({
            /*3.关联视图区*/
            el:"#box1",
            /*4.关联数据区 数据区内可以指定多个数据*/
            data:{
                /*5.声明了一个字符串message*/
                message:"hello world !"
            }
        });
    </script>

</body>

5.vue的指令学习

下面介绍了一些简单的指令集,如果还想学习更多,可以查看官网Api.

v-text指令

还记得上面代码引用一个字符串吗?

<p>{{message}}</p>

我们可以通过v-text指令这么写:

<p v-text='message'/>


v-once指令

<!-- 6.引用字符串message -->
<p>{{message}}</p>
<!-- 7.v-model指定输入框引用字符串message -->
<input v-model="message">

在上面的例子中,因为p标签和input标签都引用了同一个字符串message,只要输入框的文本改变了,那么p标签对应的数据也会跟着改变。而如果添加了v-once指令,那么p标签只会显示第一次赋值时的字符串:

<p v-once>{{message}}</p>
<input v-model="message" />


v-if指令

v-if指令表示一个条件,也就是js的布尔值可以决定实现某些操作,比如下面我们可以根据js的boolean值决定显示用户的身份:

<body>
    <div id="box1">
        <p v-if="isVip">Vip尊贵会员</p>
        <p v-if="!isVip">普通会员</p>
    </div>
    <script>
        var vm=new Vue({
            el:"#box1",
            data:{
                isVip:true
            }
        })
    </script>
</body>

v-show指令

v-show指令的操作与v-if指令相似,都可以根据boolean值决定是否显示某个标签,上面的代码经过改造之后效果一样,代码如下:

<div id="box1">
    <p v-show="isVip">Vip尊贵会员</p>
    <p v-show="!isVip">普通会员</p>
</div>

那么他们的区别在哪里啊?

使用了v-if指令的渲染效果是这样的,也就是他是根据条件来决定显示哪个标签的,只显示一个:
这里写图片描述



使用了v-show指令,通过源码可以看出他实际上将多个标签渲染出来了,再根据css来决定是否隐藏:
这里写图片描述


v-else-if 和 v-else指令

<div id="box1">
    <p v-if="userLevel==0">普通用户</p>
    <p v-else-if="userLevel==1">铜牌会员</p>
    <p v-else-if="userLevel==2">银牌会员</p>
    <p v-else>金牌会员</p>
</div>
<script>
    var vm=new Vue({
        el:"#box1",
        data:{
            /*
            * 0:普通用户
            * 1:铜牌会员
            * 2:银牌会员
            * 3:金牌会员
            * */
            userLevel:1
        }
    })
</script>


v-for指令

与java里面的增强性for循环类型,下面的引用中 创建了socre变量,那么后面的标签就可以使用了:

<div id="box1">
    <p v-for="socre in scores">身高:{{socre}}</p>
</div>
<script>
    var vm=new Vue({
        el:"#box1",
        data:{
           scores:[
                   99,85,40,66,78
           ]
        }
    })
</script>

下面贴出效果图:
这里写图片描述

我们甚至可以通过后台返回的一系列数据,将其组装成一个表,代码如下:

<head>
    <meta charset="UTF-8">
    <title>07_Vue常见指令v-for</title>
    <script src="../js/vue.js"></script>
    <style type="text/css">
        *{
            margin:0px;
            padding:0px;
        }
        table{
            width:600px;
            border:solid 2px pink;
            text-align: center;
        }
        thead{
            font-weight:bold;
            background-color: red;
        }
    </style>
</head>
<body>
    <div id="box1">
        <table >
            <thead>
                <tr>
                    <td>姓名</td>
                    <td>年龄</td>
                    <td>身高</td>
                </tr>
            </thead>
            <tbody>
                <tr v-for="person in persons">
                    <td>{{person.name}}</td>
                    <td>{{person.age}}</td>
                    <td>{{person.height}}</td>
                </tr>
            </tbody>
        </table>
    </div>
    <script>
        var vm=new Vue({
            el:"#box1",
            data:{
               persons:[
                   {name:"张三",age:20,height:17.5},
                   {name:"李四",age:22,height:18},
                   {name:"王五",age:24,height:1.63},
               ]
            }
        })
    </script>
</body>

这里写图片描述

v-bind指令

上面的过程中,我们将的是将简单的文本数据进行赋值,对于除了文本数据的其他属性的操作是不成功的,比如下面的代码将图片的地址写在vue里面,进行赋值是不成功的:

<div class="box1">
    <img src="imgSrc" alt="tupian" />
</div>

<script>
    var vm=new Vue({
        el:".box1",
        data:{
            imgSrc:"../img/logo.png",
        }
    })
</script>

解决方案A:

<img v-bind:src="imgSrc" alt="tupian" />

这样设置后就可以直接显示了。如果你发现v-bind在编辑器中报红,你可以下载一个叫vue的插件。

解决方案B:

<img :src="imgSrc" alt="tupian" />

上面的代码v-bind是可以忽略的,如上这么写默认就是v-bind。

v-on指令

v-on指令是针对点击事件的一个指令,与v-bind指令一样,有2种写法(注释/非注释的):

<div class="box1">
    <!--
    <p v-text="tip"
       v-on:click="clickImg('提示被点击了!')" />
    -->
    <p v-text="tip"
       @click="clickImg('提示被点击了!')" />
</div>

<script>
    var vm=new Vue({
        el:".box1",
        data:{
            imgSrc:"../img/logo.png",
            tip:"提示", 
        },
        methods:{
            clickImg(str){
                alert(str);
            }
        }
    })
</script>

6.组件化

组件化可以将我们的界面组件进行重复利用,Vue的另一大优势就是组件化,其使用的方式又分为2种:全局组件&局部组件,全局组件是整个页面都能使用的组件,局部组件会关联每一个ViewModel实例。下面分别介绍这2种创建方式。

打开JD界面,可以看到如下图,这里的界面模块差不多,我们可以创建统一的模板来进行处理。
这里写图片描述

1.全局组件化

全局组件化分为3个步骤:创建构造器,注册组件,使用组件,如下代码:

<body>
    <div id="box1">
        <!-- 3.使用组件 -->
        <st></st>
    </div>
    <script>
        //1.创建构造器
        var Profile=Vue.extend({
           template:'<h1>这是一个简单的标题!</h1>'
        });
        //2.注册组件
        Vue.component("st",Profile);
        new Vue({
            el:"#box1"
        })

    </script>
</body>

你也可以简化如下写法:

<body>
    <div class="box1">
        <!-- 3.使用组件 -->
        <st></st>
    </div>
    <script>

        //1.创建构造器
        //2.注册组件
        Vue.component("st",{
            template:'<h1>Hello Simple Title</h1>'
        })
        new Vue({
            el:'.box1'
        })
    </script>
</body>

2.局部组件化

局部变量绑定到的是某一个ViewModel实例中,代码如下:

<body>
    <div id="box">
        <haha></haha>
    </div>
    <script>
        var Profile=Vue.extend({
            template:"<h1>这是一个简单的局部标题</h1>"
        });
        new Vue({
            el:"#box",
            components:{
                "haha":Profile
            }
        })
    </script>
</body>

简化写法如下:

<body>
    <div id="box">
        <haha></haha>
    </div>
    <script>
        new Vue({
            el:"#box",
            components:{
                "haha":{
                    template:"<h1>简单创建的方式</h1>"
                }
            }
        })
    </script>
</body>

3.子组件化

一个组件可以由很多的子组件组合而成,相信学习过移动开发端的同学都比较清晰,下面介绍如何使用子组件:

<body>
    <div id="box1">
        <haha></haha>
    </div>
    <script>
        var childProfile=Vue.extend({
            template:'<img src="../img/logo.png"/>'
        });
        var parentProfile=Vue.extend({
            components:{
                "childT":childProfile
            },
            template:'<div><childT></childT><p>模糊的照片</p></div>'
        })

        Vue.component("haha",parentProfile);

        new Vue({
            el:"#box1"
        })

    </script>
</body>

4.采用template和script标签进行模板化

前面我们创建的组件中都有一套统一的模板代码,但模板代码的可读性很差,如下介绍模板新的写法:

<div id="box">
    <my-component></my-component>
    <script-component></script-component>
</div>

<template id="component_id">
    <h1>这是一个简单的template标题</h1>
</template>

<script type="text/template" id="script_id">
    <h1>这是一个简单的script标题</h1>
</script>

<script>

    //注册一个组件
    Vue.component("my-component",{
        template:'#component_id'
    });

    //注册一个组件
    Vue.component("script-component",{
        template:'#script_id'
    });

    new Vue({
        el:'#box'
    });

</script>

5.获取组件内部数据

如果我们想获取Vue内部实例的数据,我们可以在Vue内部的data代码块中声明,但在组件构造器中,如果想对外提供数据,使用的不是代码块而是函数,我们可以将需要返回的数据以JSON的方式将需要提供的数据进行返回。

如下我们的组件对外提供了一个叫做message的数据,如下:

  <div id="box">
    <my-component></my-component>
  </div>

  <template id="cp_template">
    <h1>{{message}}</h1>
  </template>

  <script>
    var Profile=Vue.extend({
      template:'#cp_template',
      //组件中提供的数据需要通过函数返回
      data(){
        return {
          message:'这是函数里面的数据'
        }
      }
    });
    Vue.component("my-component",Profile);

    new Vue({
      el:"#box"
    });
  </script>

6.组件对外提供了属性配置

为了让我们创建的组件更加通用,我们可以通过属性的方式对客户端提供相关的配置,如下我们让客户端设置对应的argument属性值,并在该组件中打印该值的内容:

<div id="box">
    <my-component argument="hello参数"></my-component>
</div>
<template id="cp_tmp" >
    <h1>这是组件模板中的一个简单的标题 {{argument}}</h1>
</template>
<script>
    Vue.component("my-component",{
        props:["argument"],
        template:'#cp_tmp'
    });
    new Vue({
        el:'#box'
    });
</script>

props可以指定声明一个或者多个属性名称,当然组件也存在相互嵌套的时候,以下介绍嵌套的组件是如何对外提供属性的,注意,对于不是文本的属性,需要动态绑定使用。

<div id="box">
    <parent-component :imgsrc="imgSrc" title="title"></parent-component>
</div>

<template id="child_id">
    <img :src="imgsrc" />
</template>

<template id="parent_id">
    <div>
        <my-child :imgsrc="imgsrc"></my-child>
        <br>
        <h1>{{title}}</h1>
    </div>
</template>
<script>

    var child =Vue.extend({
        props:["imgsrc"],
        template:'#child_id'
    });

    var parent =Vue.extend({
        props:["imgsrc","title"],
        template:'#parent_id',
        components:{
            "my-child":child
        }
    });

    Vue.component("parent-component",parent);

    new Vue({
        el:"#box",
        data:{
            imgSrc:"../img/logo.png",
            title:"这是一个标题"
        }
    });
</script>

7.组件嵌套下的点击事件

上面的属性开发中我们发现 属性是由父组件层层往里面传递的,而点击事件则是由子组件传递给父组件的。这里我们通过v-on指令和vue.$emit()来实现。

下面我们通过一个子组件点击事件来控制父组件内部的数据,效果图如下:
这里写图片描述

代码如下:

<div id="box">
    <parent></parent>
</div>
<template id="child_id">
    <button @click="countData">{{counter}}</button>
</template>
<template id="parent_id">
    <div>
        <p>{{totalCounter}}</p>
        <child @countevent="calculate()"></child>
        <child @countevent="calculate()"></child>
        <child @countevent="calculate()"></child>
    </div>
</template>
<script>

    Vue.component("child",{
        data(){
            return {
                counter:0
            }
        },
        template:"#child_id",
        methods:{
            countData(){
                this.counter+=1;

                //触发某个事件
                this.$emit('countevent');
            }
        }
    });

    Vue.component("parent",{
        data(){
            return {
                totalCounter:0
            }
        },
        template:"#parent_id",
        methods:{
            calculate(){
                this.totalCounter+=1;
            }
        }
    });

    new Vue({
       el:"#box"
    });
</script>

7.样式的使用

样式的操作有2种,一种是操作style标签,一种的操作class标签。使用如下:

style标签

<body>
    <div id="box1">
        <p :style="pstyle">Style样式</p>
    </div>
    <script>
        new Vue({
            el:"#box1",
            data:{
                pstyle:{
                    backgroundColor: 'red',
                    textAlign: 'center',
                    fontSize: '22px'
                }
            }
        })
    </script>
</body>

class标签

<head>
    <meta charset="UTF-8">
    <title>15_子组件的应用</title>
    <script src="../js/vue.js"></script>
    <style>
        .normal{
            background-color: red;
        }
        .active{
            background-color: blue;
        }
    </style>
</head>
<body>
    <div id="box1">
        <p :class="isActive?'active':'normal'">class样式</p>
        <button @click="changeColor">改变颜色</button>
    </div>
    <script>
        new Vue({
            el:"#box1",
            data:{
                isActive:true
            },
            methods:{
                changeColor(){
                    this.isActive=!this.isActive;
                }
            }
        })
    </script>
</body>

8.插槽

在一个组件模板中,我们希望有些布局应该由客户端来实现,此时我们可以使用Vue提供给我们的插槽来实现。

插槽:就像我们电脑主板一样,整个框架的固定的,但是我们可以根据需要插入不同型号的子组件。

插槽分为2种,匿名插槽和实名插槽。

匿名插槽

比如我想实现一个小界面,该界面的由上中下三部分组件,而中间的部分是可以替换的,此时我们的代码如下:

<div id="box1">
    <my-component>
        <!--客户端决定中间部分的内容 注意这里应该只有一个根标签-->
        <div>
            <img src="../img/logo.png" alt="">
        </div>
    </my-component>
</div>
<br>
<div id="box2">
    <my-component>
        <h1>Box2的内容</h1>
    </my-component>
</div>

<template id="my_component">
    <!--定义模板-->
    <div id="container">
        <h1 id="header">这是一个头部</h1>
        <slot>中间这部分由使用该组件的客户端决定显示需要的内容</slot>
        <h1 id="footer">这是一个底部</h1>
    </div>
</template>

<script>
    Vue.component("my-component",{
        template:"#my_component"
    });
    new Vue({
       el:"#box1"
    });

    new Vue({
        el:"#box2"
    });
</script>

实名插槽

匿名插槽比较符合一个模板中只需要一个插槽的需求。而如果一个模板需要多个插槽,就需要为每一个插槽设置名称,代码如下:

<div id="box">
    <my-component>
        <div slot="cpu">inter core i7</div>
        <div slot="gpu">xxx gpu</div>
        <div slot="memory">xxx 内存条</div>
        <div slot="storage">xxx 硬盘</div>
    </my-component>
</div>
<template id="component">
    <div id="container">
        <slot name="cpu">这是插入CPU</slot>
        <slot name="gpu">这是插入GPU</slot>
        <slot name="memory">这是插入MOMORY</slot>
        <slot name="storage">这是插入STORAGE</slot>
    </div>
</template>
<script>
    Vue.component("my-component",{
        template:'#component'
    });
    new Vue({
        el:"#box"
    });
</script>

猜你喜欢

转载自blog.csdn.net/qq285016127/article/details/74611069