vue.js入门上

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id='vue_person'>
    <h1>name:{{name}}</h1>
    <h1>age:{{age}}</h1>    
    <h1>{{SayHi()}}</h1>
    <!-- 在h1标签中的{{}}是用来输出对象属性和函数的返回值的。 -->
</div>
    <script src="vue.min.js"></script>
    <script type="text/javascript">
    //每个Vue应用都需要通过实例化Vue来实现。
        //1、创建Vue实例
        //var MyInfo = { name: "stephen", age: "26"}
        var vm = new Vue({
            el:'#vue_person',    //el通常绑定的是一个选择器。
            data:{                //data用于定义属性,当前存在name和age这两个属性。
                    name:"vichin",
                    age:27,        
                },
            //data:MyInfo,可以使用对象来与vue构造函数中的data进行绑定。
            methods:{            //用于定义函数,可以通过return来返回函数值。
                SayHi:function () {
                    return 'Hello World';
                }
            }
        });
    //当一个Vue实例被创建时,它向Vue的响应式系统中加入其data对象中能够找到的所有属性,当这些属性的值发生变化的时候,html视图将也会产生相应的变化。
    //我们创建的vue对象vm还有一些有用的属性和方法。在使用的时候都以$作为前缀,以便与用户自定义的属性进行区别。
    //例如:当我们需要获取到id为vue_person的这个div标签时,
    //1、使用js手段:
    let jsGetDOM = document.getElementById('vue_person');
    //2、使用vue提供的方法        
    let vueGetDOM = vm.$el;
    jsGetDOM===vueGetDOM;//这里返回的是true!!!
    //更多属性与方法:https://cn.vuejs.org/v2/api/#vm-data
    </script>
</body>
</html>
vue的简单介绍

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>组件的声明周期函数</h1>
    
    <div id="app">
           
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">

    let vm=new Vue({
        el:"#app",
        data:{
            num:0
        },
        beforeCreate: function () {//整个页面创建之前所调用的生命周期函数
                console.log('beforeCreate');
            },
            created: function () {//在Vue实例创建之后所调用的生命周期函数
                console.log('Created');
            },
            beforeMount: function () {//挂载之前所调用的生命周期函数

            },
            mounted: function () {//挂载之后所调用的生命周期函数

            },
            beforeUpdate: function () {//在数据更新之前所调用的生命周期函数

            },
            updated: function () {//在数据更新之后,DOM更新之后所要调用的生命周期函数

            },
            beforeDestroy: function () {

            },
            destroyed: function () {

            },
            watch: {
                num: function () {//监听器
                    console.log('变量num的值发生了变化');
                }
            }
    });

    vm.$watch('num', function (newVal, oldVal) {//观察变量num在修改前后的值
            console.log(newVal, oldVal);
        });

</script>
</body>
</html>
Vue中的声明周期函数

 watch还可以以字符串的形式来绑定对象,假定data里有一个叫obj的对象,该对象有一个属性叫a

watch:{
    'obj.a':function(){
        do something
    },
     '$store.state.currentDate': function () {
      this.changeValue()
    },     
}

 

 

 

 

 vue中的指令:

指令后的(双)引号内的代码,都是JS的表达式。

 

<child v-bind:content="hello world"></child> 写法是错误的,因为不会有变量叫做hello world,如果要想向子组件child中传入字符串,正确的写法是:<child content="hello world"></child>
若是向子组件传递其他类型的参数,可以使用v-bind指令,因为=号后面的(双)引号后跟的是JS表达式。

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<h1>v-model指令的使用。</h1>
    <h2> v-model指令可以使vue实例中的数据与html标签中的文本内容进行关联,当html标签中的文本内容发生变化时,vue实例中的数据也会随之发生变化。当实例中的数据发生变化时,html标签中的文本也会随之发生变化。(适用于 需要以数据驱动 从而生成的页面)
    </h2>
    <h3 style='color: red'>v-model指令用于带有value值的标签,例如:input select textarea</h3>
<div id="app">
    <p>{{msg}}</p>
    <input type="text" v-model='msg' />
</div>

    <script src="vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el:'#app',
            data:{                
                    msg:"Hello World"                        
                }        
            });
    </script>
</body>
</html>
v-model

  

v-if和v-show指令在效果上是一致的,但是具体到细节上的区别是:

1、v-if会将不符合条件的html标签给注释掉,而v-show是使用css样式 dispaly:none。

2、基于上面的性质;v-if有更高的切换消耗,而v-show有更高的初始渲染消耗。若需要频繁的切换,可以使用v-show。如果在运行时条件不大可能改变的,则使用v-if较好

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<h1>v-show指令的使用。</h1>
<!-- v-if指令,常用于添加删除元素 -->

<div id="app">
    <p v-show='show'>my name is vichin</p>
    <p v-show='hide'>my name is stephen</p>
    <p><label v-if="age < 18"></label><label>成年</label></p>
    <!-- v-if后面可以放一个表达式,因为age是大于18的,所有条件不成立,所有‘未’字不显示出来。 -->
</div>

    <script src="vue.min.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el:'#app',
            data:{                
                    show:true,
                    hide:false,
                    age:27                        
                }        
            });
    </script>
</body>
</html>
v-show
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<h1>v-if指令的使用。</h1>
<!-- v-if指令,常用于添加删除元素 -->

<div id="app">
    <p v-if='show'>my name is vichin</p>
    <p v-if='hide'>my name is stephen</p>
    <p><label v-if="age < 18"></label><label>成年</label></p>
    <!-- v-if后面可以放一个表达式,因为age是大于18的,所有条件不成立,所有‘未’字不显示出来。 -->
</div>

    <script src="vue.min.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el:'#app',
            data:{                
                    show:true,
                    hide:false,
                    age:27                        
                }        
            });
    </script>
</body>
</html>
v-if
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>v-else指令的使用。</h1>
    <!-- v-else指令需要配合v-if或者v-else-if来使用。 -->
    <div id='app'>
        <p>
            <lable>vicin今年的年龄是:{{age}}。</lable>
            <label v-if="age < 18">不属于</label>
            <!-- 如果v-else不是紧跟着v-if来用的,就会报编译错误! -->
            <label v-else>属于</label> <!-- v-else的使用 -->
            <label>成年人</label>
        </p>
    </div>
    <script type="text/javascript" src="vue.min.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el:'#app',
            data:{                
                    show:true,
                    hide:false,
                    age:27                        
                }        
            });
    </script>
</body>
</html>
v-else

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>v-else-if指令的使用。</h1>
    
    <div id='app'>
        <p>输入的成绩对应的等第是:</p>
        <p v-if='score >= 90'>优秀</p>
        <p v-else-if='score >= 75'>良好</p>
        <p v-else-if='score >= 60'>及格</p>
        <p v-else>不及格</p>
        <input type="text" v-model='score' />
    </div>
    <script type="text/javascript" src="vue.min.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el:'#app',
            data:{              
                    score:85                       
                }        
            });
    </script>
</body>
</html>
v-if、v-else-if、v-else综合使用

 

v-for的优先级别高于v-if之类的其他指令。

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <h1>v-for指令的使用。</h1>
    <!-- 适用于基于数据渲染一个列表,类似于JS中的遍历。其数据类型可以是Array、Object、number、string
    该指令必须使用特定的语法(item、index) in items,为当前遍历元素提供别名。 -->
    <div id='app'>
        <!-- 遍历数组 -->
        <p v-for="(score,index) in scores" v-bind:key="index">
            <!--不建议使用index来作为key,因为可能会存在些许性能影响。建议使用后台传过来的数据中的主键来作为key,(硬要用的话,也没问题) -->
            <label>第{{index + 1}}名分数是:</label><label>{{score}}</label>
        </p>
        <!-- 遍历一个对象 -->
        <p v-for="e in employee" v-bind:key="key">
            {{e}}
        </p>

        <!-- 遍历一个string -->
        <p v-for="str in weather">
            {{str}}
        </p>
    </div>


    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el: '#app',
            data: {
                //在vue中,建议使用push pop shift unshift splice sort reverse等方法来操作数组,这样数组产生的变化才会影响DOM。
                //vm.$set(vm.scores,0,80) 或者Vue.set(vm.scores,0,80) 也可以让DOM发生变化。更改scores的引用也可以!            
                scores: [95, 85, 75, 65],

                //当需要往这个对象中添加一个属性的时候,我们直接用employee.address='SZ'是不会影响DOM的,需要将整个employee这个对象所指的那个引用进行更改,
                //即:vm.employee={ name: 'vichin', age: 18, sex: 'M', address:'SZ' }
                //或者使用Vue.set(vm.employee,'address','SZ')//通过set方法,向vm.employee这个对象添加一个属性,值为SZ。
                //vm.$set(vm.employee,'address','SZ')
                employee: { name: 'vichin', age: 18, sex: 'M' },
                weather: 'TodayIsSoCold'
            }
        });
    </script>
</body>

</html>
v-for指令

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>v-for指令的使用。</h1>
    <div id='app'>
            <table>
                <thead>
                    <tr><th>姓名</th><th>年龄</th><th>性别</th></tr>
                </thead>
                <tbody>
                    <tr v-for="p in persons">
                        <td>{{p.name}}</td>
                        <td>{{p.age}}</td>
                        <td>{{p.sex}}</td>
                    </tr>
                </tbody>
            </table>    
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el:'#app',
            data:{              
                    persons:[
                        {name:"vichin",age:18,sex:"M"},
                        {name:"stephen",age:19,sex:"M"},
                        {name:"james",age:20,sex:"M"},
                        {name:"wade",age:21,sex:"M"}
                    ]
                }        
            });
    </script>
</body>
</html>
v-for指令demo

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>v-text、v-html指令的使用。</h1>
    <div id='app'>
            <p v-text="msg">p标签中,原文本</p>
            <!-- 使用v-text指令,会将标签中原文本给替换掉 -->

            <div v-html="htmlContent"></div>
            <!-- 向页面输入html标签 -->
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el:'#app',
            data:{              
                    msg:"Today is so cold",
                    htmlContent:"<input type='date' />"
                }        
            });
    </script>
</body>
</html>
v-text、v-html

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        .active{
            background-color: orangered;
            font-size: 20px;
            color: #fff;
        }
    </style>
</head>
<body>
    <h1>v-bind指令的使用。</h1>
    <h2>动态绑定一个或多个特性、或一个组件prop到表达式,v-bind指令可以再其名称后面带一个参数,中间用一个冒号隔开。这个参数通常是HTML元素的特性。
            例如:
                绑定属性:  v-bind:src='../img/pic.png' 可以缩写成::src="../img/pic.png"
                绑定一个类:v-bind:class="{red:isRed}" 或 :class="[classA,classB]"
                绑定样式    v-bind:style="{font-size:size+'px'}" 或 :style="[styleObjectA,styleObjectB]"
                绑定一个有属性的对象,比如:v-bind="{id:someProp,'other-attr':otherProp}" 
    </h2>
    <div id='app'>
        <!-- 绑定一个属性,imgSrc是一个变量-->
        <img v-bind:src="imgSrc" v-bind:id='fontColor' v-bind:alt="alt"> 

        <!-- 给标签动态绑定类 -->
        <p v-for="(college,index) in colleges" :class="index === activeIndex ? 'active' : ''">
            {{college}}
        </p>

        <!-- <div v-bind:class='[isActive?"active":"",isGreen?"green":""]'>样式绑定(支持多个,当isActive为true的时候,active样式就会生效)</div> -->
        <div v-bind:class='{active:isActive,green:isGreen}'>样式绑定(支持多个,当isActive为true的时候,active样式就会生效)</div>

        <!-- 绑定样式 -->
        <p v-bind:style='{color:fontColor}'>Today is so cold</p>
        <div v-bind:style="{color:fontColor,background:isGreen?'#FF0000':'',fontSize:'50px'}">绑定内联样式</div>
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el:'#app',
            data:{              
                    imgSrc:".../img/pic1.png",
                    alt:"我是天才",
                    colleges:[
                        '清华大学',
                        '北京大学',
                        '南京大学',
                        '浙江大学'
                    ],
                    activeIndex:2,
                    fontColor:"blue",
                    isActive:true,
                    isGreen:false                  
                }        
            });
    </script>
</body>
</html>
v-bind

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        .active{
            background-color: orange;
            font-size: 20px;
            color: #fff;
        }
    </style>
</head>
<body>
    <h1>v-on指令的使用。</h1>
<!--     动态的绑定一个或多个特性,或一个组建prop到表达式;其作用和v-bind类似。注意:如果用在普通元素上时,只能监听原生DOM事件;但是如果用在自定义元素组件上时,也可以监听子组建触发的自定义事件。
    常用修饰符:
        .stop---调用event.stopPropagation()。停止冒泡
        .prevent---调用event.preventDefault()。停止监听原生事件。
        .capture---添加事件侦听器时使用capture模式。
        .self---只当事件是从侦听器绑定的元素本身触发时才触发回调
        .{keyCode|keyAlias}---只当事件是从侦听器绑定的元素本身触发时才触发回调。
        .once---触发一次。 -->

    <p>使用手法:</p>
    <div id='app'>
        <button v-on:click="doThis">方法处理器</button>

        <button v-on:click="doThat('hello',$event)">内联语句</button>

        <button @click="doThis">缩写</button>

        <button @click.stop="doThis">停止冒泡</button>

        <button @click.prevent="doThis">阻止默认行为</button>

        <!-- 阻止默认行为,没有表达式 -->
        <form @submit.prevent></form>

        <!--  -->
        <button @click.stop.prevent="doThis">串联修饰符</button>

        <input @keyup.enter="onEnter" value="键式修饰符,键别名" />

        <input @keyup.13="onEnter" value="键式修饰符,键代码" />

        <button v-on:click.once="doThis">事件只触发一次</button>

    </div>
    
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        var vm = new Vue({
            el:'#app',
            data:{              
                    msg:"Today is so cold",
                    fontColor:'#5CCCFA',
                    fontWeight:"bold",
                    fontSize: 30
                },      
            methods:{
                
                    doThis(){
                        console.log(1);
                    },
                    onEnter(){
                        console.log(2)
                    },
                    doThat:function (para1,para2) {
                        console.log(3);
                    }
                }
            });
    </script>
</body>
</html>
v-on

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        #app{
            margin:50px auto;
            width: 600px;
        }
        fieldset{
            border: 1px solid orangered;
            margin-bottom: 100px;
        }
        fieldset input{
            width:200px;
            height: 20px;
            margin: 10px 0;
        }
        fieldset select{
            margin: 10px 0;
        }
        table{
            width:600px;
            border: 2px solid orangered;
            text-align: center;
        }
        thead{
            background-color: orangered;
        }
    </style>
</head>
<body>
    <div id="app">
    <!-- 第一部分 -->
    <fieldset>
        <legend>员工录入系统</legend>
        <div>
            <span>姓名:</span>
            <input type="text" placeholder="请输入姓名" v-model='newEmp.name'/>
        </div>
        <div>
            <span>年龄:</span>
            <input type="text" placeholder="请输入年龄" v-model='newEmp.age'/>
        </div>
        <div>
            <span>性别:</span>
            <select v-model='newEmp.sex'><option value="M"></option><option value="F"></option></select>
        </div>
                
        <button @click="createNewEmp()">创建新用户</button>
    </fieldset>

    <!-- 第二部分 -->
    <table>
        <thead>
            <tr>
                <td>姓名</td>
                <td>年龄</td>
                <td>性别</td>
                <td>删除</td>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(p,index) in persons">
                <td>{{p.name}}</td>
                <td>{{p.age}}</td>
                <td>{{p.sex}}</td>
                <td><button @click="DelEmp(index)">删除</button></td>
            </tr>
        </tbody>
    </table>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
    let vm=new Vue({
        el:"#app",
        data:{
            persons:[
                {name:"vichin",age:27,sex:"M"},
                {name:"stephen",age:28,sex:"M"},
                {name:"james",age:29,sex:"M"},
                {name:"wade",age:30,sex:"M"}
                ],
            newEmp:{name:"",age:0,sex:"M"}
            },
        methods:{
                createNewEmp(){
                    if(this.newEmp.name===""){
                        alert('姓名不能为空!');
                        return;
                    }
                    if(this.newEmp.age<18){
                        alert('不得录用未成年人!');
                        return;
                    }

                    //往数组中添加一条记录
                    this.persons.unshift(this.newEmp)
                    //清空数据,下次再添加的时候,就没有任何关联了
                    this.newEmp={name:"",age:0,sex:"M"};
                },
                DelEmp(index){
                    this.persons.splice(index, 1);
                }
            }        
    });
</script>
</body>
</html>
指令小demo(用户管理)

 

<!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>v-once指令与动态组件component</title>
</head>

<body>
    <p>component是vue自带的组件,一开始进入页面时,变量type的值是child,这个时候component组件就会去加载child这个组件,当点击按钮将type的值更改为body-content的时候,component组件就会去加载body-content这个组件
    </p>
    <div id="root">
        <component :is="type"></component>
        <button @click="handleBtnClick">change</button>
    </div>
    <script src="vue.js"></script>
    <script>

        //使用v-once指令会有效的提高一些静态内容的展示性能
        Vue.component('child', {
            //template: '<div>child</div>'这里不适用v-once指令,当页面显示的内容切换成body-content时,vue会去销毁掉child这个组件,当处于body-content时,再切换回child时,会销毁body-content组件,再重新创建child组件。
            template: '<div v-once>child</div>'//使用了v-once指令后,当vue创建好这个组件后,会将该组件进行缓存,当页面从body-content切换回child组件时,会去缓存中获取child组件,而非去重新创建。
        });
        Vue.component('body-content', {
            //template: '<div>body-content</div>'
            template: '<div v-once>body-content</div>'
        });
        var vm = new Vue({
            el: '#root',
            data: {
                type: 'child'
            },
            methods: {
                handleBtnClick: function () {
                    this.type = this.type === 'child' ? 'body-content' : 'child';
                }
            },
        });

    </script>
</body>

</html>
v-once指令与动态组件component

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <h1>计算属性</h1>
    计算属性顾名思义就是这个属性是通过计算得来的,所以在调用的时,在插值表达式中使用了reserve,而并不是reserver(),这样的一个方法的调用形式。
    当页面重新渲染的时候(不是刷新页面),计算属性所依赖的变量(在这里所依赖的属性是lastname和firstname)没有发生任何改变时,该计算属性的结果不会发生变化,直接读取缓存使用。
    当属性需要较大的计算或改变频率较低的时候,推荐使用计算属性。
    而method是当页面重新渲染的时候(页面元素data变化,页面就会重新渲染),都会调用method
    <div id="app">
        <p>初始值:{{lastname}}</p>
        <p>翻转值:{{reserveStr()}}</p>
        <p>计算属性:{{reserve}}</p>
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        let vm = new Vue({
            el: "#app",
            data: {
                lastname: "vichin",
                firstname: 'wei'
            },
            methods: {
                reserveStr() {
                    return (this.lastname + " " + this.firstname).split("").reverse().join('');
                }
            },
            computed: {
                reserve: function () {
                    return this.lastname + " " + this.firstname;
                }
                // reserve: {
                //     get: function () {
                //         return (this.lastname + " " + this.firstname).split("").reverse().join('');
                //     },
                //     set: function (value) {//当设置这个计算属性的值的时候,set方法就会被执行。在控制台中输入vm.reserve='stephen',会打印出stephen123
                //         console.log(value + "123");
                //     }
                // },
                //计算选项,默认只有get方法。get方法return值  
                // reserve() {
                //     return (this.lastname + " " + this.firstname).split("").reverse().join('');
                // },                
            }
        });
    </script>
</body>

</html>
计算属性

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>全局组件</title>
</head>
<body>
    <h1>全局组件</h1>
    
    <div id="app">
        <my-date v-bind:para='1' >
            <h3>向插槽内写入信息,如果组件中的slot标签去除,那么这段文字将不会显示</h3>
        </my-date>
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
     //1、创建实例
    let vm=new Vue({
        el:"#app"
    });

    //2、创建组件构造器
    let profile=Vue.extend({
        //模板选项
        //使用slot标签声明一个插槽,在使用组件的时候,可以向插槽内输入想要的内容。
        template:`<div><p v-on:click='Clickme'>今天是过了大雪了!</p><slot></slot></div>`,
        props:['para'],//使用props来接收父组件传递的参数。
        methods:{
            Clickme:function () {
                console.log(this.para);
            }
        }

    });
    //3、注册一个组建
    Vue.component('my-date',profile);
   
</script>
</body>
</html>
全局组件

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>组件参数校验</title>
</head>

<body>
    <div id='app'>
        <child :content="'123456'"></child>
        <child content='vichin'></child>   
    </div>

    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        Vue.component('child', {
            //props: ['content'],//最基础的接收参数的方法。
            props: {
                //content: String//定义接受到的参数必须为string类型的。
                // content: [String, Number] 接收到的参数可以是String类型,也可以是Number类型。
                content: {
                    type: String,
                    required: true,//调用子组件时,必须要传递content参数
                    default: 'default value',
                    validator: function (value) {
                        return value.length > 5;
                    }
                }
            },
            template: '<div>{{content}}</div>'
        });

        var vm = new Vue({
            el: '#app'
        });
    </script>
</body>

</html>
组件参数校验

 

使用is属性指定名称来解决模板标签出现的bug。ol标签下必须要写li标签,select标签内必须要写option标签,table标签内必须要写tr标签(H5编码规范)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>document</title>
</head>
<body>
    <div id='app'>
        <table>
            <row></row>
        </table>
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        Vue.component('row', {
            template: "<tr><td>this is a row</td></tr>"
        });
        var vm = new Vue({
            el: '#app'
        });
    </script>
</body>
</html>
不使用is属性

不使用is属性生成的DOM(tr标签并没有在table标签内)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>    
    <div id='app'>
        <table>      
            <tr is='row'></tr>
        </table>
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        Vue.component('row', {
            template: "<tr><td>this is a row</td></tr>"
        });
        var vm = new Vue({
            el: '#app'
        });
    </script>
</body>
</html>
使用is属性来解决这一bug

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父子组件传参</title>
    <script type="text/javascript" src="vue.js"></script>
</head>
<body>
    <div id="root">
        <!-- 父组件通过属性的形式与子组件进行通信 -->
        <!-- 使用v-bind指令声明一个属性叫做count,其值便是父组件要传递给子组件的内容 -->
        <counter v-bind:count='0' @addone='addone'></counter>
        <!-- 定义一个事件addOne,当事件触发时,调用handleAddOne方法。 -->

        <!-- 子组件通过申明props属性来进行接收 -->
        <counter v-bind:count='0' @addone='addone'></counter>

        <!-- 父组件中,定义一个total -->
        <div>{{total}}</div>
    </div>

    <script type="text/javascript">
    // 定义一个局部组件
        var counter={
            props:['count'],//接收一个叫做count的内容。
            template:'<div v-on:click="handleClick">{{number}}</div>',//使用mustache语法调用接收到的内容。
            methods:{
                handleClick:function () {
                    //this.count++;这里子组件不能随意的去修改父组件传递过来的参数。(Vue的单向数据流)
                    this.number+=1;
                    this.$emit('addone', 1);//使用$emit方法让子组件触发一个名叫addOne的事件。并让子组件传递一个参数1,告诉父组件,每次自增为1。(可以传递多个参数,只要以逗号分隔开来即可。)
                }
            },
            data:function(){
                return {
                    number:this.count
                }//因为不能该父组件中的参数,所有可以声明一个参数为number,来接收传递过来的参数。
            }
        }
        var vm=new Vue({
            el:'#root',
            data:{
                total:0
            },
            components:{
                counter:counter//注册局部组件
            },
            methods:{
                addone:function(para){
                    this.total+=para;                    
                }
            }
        })
    </script>
</body>
</html>
使用局部组件和指令,完成一个点击计数的功能

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <input type="text"  v-model='todovalue'/>
        <button v-on:click='Addcontent'>提交</button>
        <ul>
            <!-- 向组件中传入参数,参数名称叫做content,值是从for循环中取出的item -->
            <!-- 向组件中传入参数,参数名称叫做index,值是for循环时的索引 -->
            <!-- 声明一个自定义事件,事件名叫subitem,当该事件被触发时,调用实例中的Subitem方法。 -->
            <todoitem v-bind:content='item' :index='index' v-for='item,index in list' v-on:subitem='Subitem'></todoitem>
        </ul>
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        //创建一个全局组件
        Vue.component('todoitem',{
            props:['content','index'],//接收叫做content的内容
            template:'<li v-on:click="click_item" >{{content}}</li>',
            methods:{
                click_item:function () {
                     this.$emit('subitem',this.i);
                }
            },
            data:function(){
                return {
                    item:this.content,
                    i:this.index
                }
            }

        });
        var vm=new Vue({
            el:'#app',
            data:{
                list:[],
                todovalue:''
            },
            methods:{
                Addcontent:function () {
                    if (this.todovalue) {
                        this.list.push(this.todovalue);
                        this.todovalue='';
                    }                    
                },
                Subitem:function(para){
                    this.list.splice(para,1);
                }
            }
        });
    </script>
</body>
</html>
使用全局组件和指令,完成一个todolist

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>组件的使用</h1>
    
    <div id="app">
        <parent></parent>        
    </div>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
    
    //1、子组件构造器    
    let child=Vue.extend({
        template:`<label>子组件1</label>`
    });
    let child1=Vue.extend({
        template:`<label>子组件2</label>`
    });

    //2、父组件构造器
    Vue.component('parent',{
        components:{
            'my-child':child,
            'my-child1':child1          
        },
        template:
        `
        <div><my-child></my-child><my-child1></my-child1></div>
        `
    });
    let vm=new Vue({
        el:"#app"
    });

</script>
</body>
</html>
父子组件

 

 组件通信:

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<h1>多层组件通信</h1>

<!-- 父组件在div中的实际使用 -->
<div id="app">
    <!-- 调用最外层组件,传递title和img信息给最外层的这个组件(通过vue实例) -->
    <my-parent :imgtitle="title" :imgsrc="img"></my-parent>
</div>




<!-- 声明子组件1,用于存放图片 -->
<template id='my_img'>
    <img :src="imgsrc" width="200">
</template>

<!-- 声明子组件2,用于存放标题 -->
<template id='my_title'>
    <h2>{{title}}</h2>
</template>


<!-- 声明一个父组件 -->
<template id='my_parent'>
    <div>
        <child1 :imgsrc="imgsrc"></child1>
        <child2 :title="imgtitle"></child2>    
    </div>
</template>

    <script src="vue.min.js"></script>
    <script type="text/javascript">
    //1、子组件实例化
    let Child1=Vue.extend({
        template:"#my_img",//将组件与模板相关联
        props:['imgsrc']
    });
    let Child2=Vue.extend({
        template:"#my_title",//将组件与模板相关联
        props:['title']
    });


    //2、注册父组件
    Vue.component('my-parent',{
        props:['imgtitle','imgsrc'],
        components:{
            'child1':Child1,
            'child2':Child2
        },
        template:'#my_parent'
    });

    声明一个Vue实例
    new Vue({
        el:'#app',
        data:{
            title:'葫芦奶娃',
            img:'05.jpeg',
        }    
    });
    </script>
    
</body>
</html>
vue多层组件之间的通信

 

<!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>使用观察者模式(bus总线,发布订阅模式),来解决非父子组件的传值问题</title>
</head>

<body>
    <div id="root">
        <child content='dell'></child>
        <child content='lee'></child>
    </div>
    <script src="vue.js"></script>
    <script>
        // 首先,声明一个Vue的实例,并将值赋值给bus。在后面再次实例化Vue对象的时候,这些对象都会有bus这个属性,并且这些属性都指向了同一个Vue对象。
        Vue.prototype.bus = new Vue();

        Vue.component('child', {
            data:function(){
                return {
                    content_:this.content
                };
            },
            template: '<div @click="handleClick">{{content_}}</div>',
            props: {
                content: String 
            },
            methods: {
                handleClick: function () {
                    this.bus.$emit('change', this.content_);//bus指向了一个Vue的实例,所以是存在$emit这个方法。
                }
            },
            mounted: function () {//生命周期函数,当该组件被挂载的时候,执行。
                var _this = this;//下面的function内,this的作用域会发生变化,所以声明一个实例来指向原先this所指的引用。
                this.bus.$on('change', function (msg) {//与$emit事件一样,this.bus也有on事件,用该事件去监听change事件。
                    _this.content_ = msg;
                });
            },
        });
        var vm = new Vue({
            el: '#root'
        });

    </script>
</body>

</html>
非父子组件的传值

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<h1>使用自定义事件,让子组件的信息传递给父组件</h1>
每个Vue实例都实现了时间接口;
使用$on(eventName)监听事件。
使用$emit(eventName)触发事件。
父组件可以在使用了子组件的地方直接使用v-on(或者是@)来监听子组件的触发。

<!-- 父组件在div中的实际使用 -->
<div id="app">
    <my-btn @total="allcounter()"></my-btn><!-- 这里使用@total来监听total方法,没执行一下total方法后就执行一下alcounter方法 -->
    <my-btn @total="allcounter()"></my-btn>
    <my-btn @total="allcounter()"></my-btn>

    <p>一共点击了{{totalcounter}}次</p>
</div>




<!-- 声明子组件 -->
<template id='my_btn'>
    <button @click="total()">点击{{counter}}次</button>
</template>




    <script src="vue.min.js"></script>
    <script type="text/javascript">


    //注册按钮
    Vue.component('my-btn',{
        template:'#my_btn',
        data(){
            return {
                counter:0
            }
        },
        methods:{
            total(){
                this.counter++;
                // 通知外界,此方法被调用了
                this.$emit('total');
            }
        }
    });

    // 声明一个Vue实例
    new Vue({
        el:'#app',
        data:{
            totalcounter:0            
        },
        methods:{
            allcounter(){
                this.totalcounter ++;
            }
        }    
    });
    </script>
    
</body>
</html>
使用自定义事件,让子组件的信息传递给父组件

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<h1>匿名slot(插槽————感觉有点想占位符)</h1>


<!-- 父组件在div中的实际使用 -->
<div id="app">
    <my-slot>
        <img src="05.jpeg" width="200" />
    </my-slot>    
</div>
<template id='my_slot'>
    <div id='panel'>
        <h2 class="panel-header">插槽头部</h2>
        <!-- 预留一个插槽 -->
        <slot>插槽默认显示</slot><!-- 这里的slot可以代替任何一个标签,我们在使用的时候,传入div,它就会变成div标签。传一个label就会变成lable标签,如果我们什么都不传,默认显示显示slot标签内的内容 -->
        <footer>插槽尾部</footer>
    </div>
</template>
    <script src="vue.min.js"></script>
    <script type="text/javascript">
    Vue.component("my-slot",{
        template:'#my_slot'
    });

    // 声明一个Vue实例
    new Vue({
        el:'#app',
        data:{
            totalcounter:0            
        },
        methods:{
            allcounter(){
                this.totalcounter ++;
            }
        }    
    });
    </script>
    
</body>
</html>
匿名slot

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<h1>实名slot(插槽————感觉有点想占位符)</h1>


<div id="app">
    <my-student>
        <span slot='user_name'>vichin</span>
        <span slot='user_age'>27</span>
        <div slot='user_sex'>male</div>
    </my-student>    
</div>
<template id='my_student'>
    <div id='main'>
        <slot name='user_name'>姓名插槽</slot>
        <slot name='user_age'>年龄插槽</slot>
        <slot name='user_sex'>性别插槽</slot>
    </div>
</template>
    <script src="vue.min.js"></script>
    <script type="text/javascript">
    Vue.component("my-student",{
        template:'#my_student'
    });

    // 声明一个Vue实例
    new Vue({
        el:'#app',
        data:{
            totalcounter:0            
        },
        methods:{
            allcounter(){
                this.totalcounter ++;
            }
        }    
    });
    </script>
    
</body>
</html>
具名插槽slot

 

<!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>具名插槽</title>
</head>

<body>
    <div id="root">
        <child>
            <h3>vichin</h3>
        </child>
        <hr>
        <body-content>
            <div slot='header'>header</div>
            <div slot='footer'>footer</div>
        </body-content>
    </div>
    <script src="vue.js"></script>
    <script>


        Vue.component('child', {
            template: '<div><p>hello</p><slot>default value</slot></div>'
        });
        Vue.component('body-content', {
            template: '<div><slot name="header"></slot><div>content</div><slot name="footer"></slot></div>'
        });
        var vm = new Vue({
            el: '#root'
        });

    </script>
</body>

</html>
具名插槽slot1

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue-router(用于组件之间的过渡、切换)</title>
    <link rel="stylesheet" type="text/css" href="bootstrap.min.css">
    <style>
        body{
            background-color: #e8e8e8;
        }
    </style>
</head>
<body>
<div id="app">
    <div class="row">
        <div class="col-xs-8 col-xs-offset-2">
            <div class="page-header">
                <h1>
                    IT666
                </h1>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-xs-2 col-xs-offset-2">
            <div class="list-group">
            <!-- 使用router-link来导航
            通过传入to属性来指定链接
            router-link默认会被渲染成一个a标签 -->
                <router-link class='list-group-item' to='/h5'>HTML5</router-link>    
                <router-link class='list-group-item' to='/php'>php</router-link>    
                <router-link class='list-group-item' to='/java'>java</router-link>    
            </div>
        </div>
        <div class="col-xs-6">
            <div class="panel">
                <div class="panel-body">
                    <!-- 路由出口 -->
                    <!-- 将路由匹配到的组件渲染在这里 -->
                    <router-view></router-view>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- 创建模块 -->
<template id='h5'>
    <div><h2>HTML5</h2>
    <p>新热点</p>
    <div>
        <ul class="nav nav-tabs">
            <router-link to='/h51'>基础班</router-link>    
            <router-link to='/h52'>进阶版</router-link>    
        </ul>
        <div class="tab-content">
            <router-view></router-view>
        </div>
    </div>
    </div>
</template>

<template id='h51'>
    <div><h3>HTML5基础</h3>
    <p>这是会讲解基础的一些信息</p>
    </div>

</template><template id='h52'>
    <div><h3>HTML5进阶</h3>
    <p>这里会阐述进阶的一些信息</p>
    </div>
</template>

<template id='php'>
    <div><h2>php</h2>
    <p>拍黄片</p>
    </div>
</template>

<template id='java'>
    <div><h2>java</h2>
    <p>扎哇</p>
    </div>
</template>
    <script src="vue.min.js"></script>
    <script type="text/javascript" src="Vue-router.js"></script>
    <script type="text/javascript">
    //1、创建组件
    const HTML5=Vue.extend({
        template:'#h5'
    });
    const HTML51=Vue.extend({
        template:'#h51'
    });
    const HTML52=Vue.extend({
        template:'#h52'
    });
    const php=Vue.extend({
        template:'#php'
    });
    const java=Vue.extend({
        template:'#java'
    });

    //2、定义路由
    const routes=[
    // 一级路由的配置
        {
            path:'/h5',
            component:HTML5,
            children:[//配置二级路由
            {path:'/h51',component:HTML51},
            {path:'/h52',component:HTML52},
            {path:'/',redirect:'/h51'}
            ]
        },

        {path:'/php',component:php},
        {path:'/java',component:java},
    // 配置根路由
        {path:'/',redirect:'/h5'}
    ]
    //3、创建路由实例
    const router=new VueRouter({
        routes//使用ES6语法(对象结构)
    });
    //4、创建Vue实例,并与元素进行绑定
    new Vue({
        router    
    }).$mount('#app')
    </script>
    
</body>
</html>
Vue-router

菜鸟教程上的demo

 

class和style的高级用法,其中showWarning和mix是vue实例下的一个方法,warning是vue实例下的一个对象。

 

以vue结尾的文件叫做单文件组件。
模板放在template标签内,行为放在script标签内,样式放在style标签内。
首次运行项目,先进入到文件夹 cd travel。然后再使用命令 npm run dev
启动一个项目使用npm run start
停止一个服务npm travel clear

打包发布:npm run build

在vue项目中进行页面跳转不适用a标签,而是使用<router-link to='/list'>标签。to后面表示要跳转的页面。项目中是跳转到list这个页面。
npm install fastclick --save 将fastclick这个包安装到项目的依赖之中,不管是在开发环境之中,还是在打包生成线上版本的代码都需要使用fastclick(会将版本信息写道package.json文件里的dependencies节点)
在style标签中使用scoped属性,可以让style标签中的样式只能应用于本组件中<style lang='stylus' scoped></style>
安装axios: npm install axios --save

 

 在使用:style="{font-weight:fontWeight(实际这的值是一个bold)}"给标签增加样式时,发现运行不了,后来将font-weight改写成fontWeight之后,就可以正常运行了。是不是在vue中,不支持横杠的出现?

在使用父子组件的时候,<div><my-child></my-child><my-child1></my-child1></div>,如果将my-child和my-child1这两个组件分别放在两个div中,那么就会只显示第一个组件,第二个组件并不显示。(<div><my-child></my-child></div><div><my-child1></my-child1></div>

父组件标签中,不能单独使用子组件的标签,如若想用,必须重新在外部注册成另外一个组件

 

posted @ 2018-12-06 22:04  水墨晨诗  阅读(280)  评论(0编辑  收藏  举报