[TOC]

1.Vue基础语法

1-1.学习方法

Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

任何一门框架的学习,最好的资料都是官网;能把VUE官网理解,使用Vue.js是游刃有余的。
VUE官网:https://cn.vuejs.org/v2/guide/
初学者建议看基础视频教程,从头到尾代码敲一遍,掌握基础知识点,再完整阅读官网,进行深化理解。

基础知识准备:JS语法、ES6、Webpack、npm。

1-2.使用Vue.js实现Hello World

Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器

1.首先到官网https://cn.vuejs.org/v2/guide/installation.html 找到多版本安装教程,选择【开发版本】; 2.在编辑器创建一个 .js 的文档(如:Vue.js),把【开发版本】的代码复制到 .js 文档并保存; 3.创建一个 index.html ,编写”hello world” 的实例; 4.以 script 标签 src 的形式引入; 5.el :是element 的意思;
6.

{{ msg }}
声明; {{ msg }} 插值表达式; 7.el:”#root”, 绑定。没有DOM的操作,只有数据的编写;

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Vue 入门</title>
  <script src="./vue.js"></script>
</head>
<body>
  <div id="root">{{msg}}</div>
  <script>
//    var dom = document.getElementById('app');//原生js写法
//    dom.innerHTML = 'hello world'
//    setTimeout(function(){
//        dom.innerHTML = 'bye world'
//    }, 2000)  //意思是2秒后hello world 变为bye world

    new Vue({
        el:"#root",
        data:{
          msg:"hello world"
        }
    })
    setTimeout(function(){
        app.$data.msg = 'bye world'
     }, 2000)  //意思是2秒后hello world 变为bye world
  </script>
</body>

1-3.挂载点、模板、实例之间的关系

挂载点:指的是Vue实例里的el属性对应的dom节点 id。
模板:在挂载点内部的所有内容,视频中div里面的内容。也可以在Vue实例中用 template 属性替换。
实例:定义挂载点,把定义的数据与模版结合起来生成要展示的内容,再把这个内容放在挂载点中;Vue实例只会对相应的 el 属性产生作用。

凡是以 $ 开头的,指的都是Vue的实例属性,或者实例方法Vue 基础教程 - 图1

<body>
  <div id="root"></div>
  <script>
    new Vue({
        el:"#root",
        template:'<h1>hello {{msg}}</h1>',
        data:{
          msg:"hello world"
        }
    })
  </script>
</body>

1-4.Vue 实例中的数据,事件和方法

重要的指令:
插值表达式 : {{变量}}
v-text=”变量”:输出一个文本,会进行转义
v-html=”变量”:输出HTML格式,不会进行转义
v-html与v-text的区别在于,前者将html标签里的内容渲染出来,而后者连同标签一同显示
v-on:click=”函数名” 绑定事件, 可以简写为@click=”函数名” 事件执行方法写在 methods:{} 里面。
v-if 控制显示
v-for 循环渲染
v-model可用表单元素

vue不是面向dom编程,而是数据编程

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Vue 入门</title>
  <script src="./vue.js"></script>
</head>
<body>
  <div id="root">
    <div v-on:click="handleClick">{{content}}</div>
  </div>
  <script>
    new Vue({
        el:"#root",
        data:{
          content:"hello"
        },
        methods:{
          handleClick:function(){
            this.content="world"
          }
        }
    })
  </script>
</body>
</html>

1-5.Vue中的属性绑定和双向绑定

1、属性绑定

属性绑定

//可以缩写成:
属性绑定

2、双向数据绑定:

content展示什么是由数据决定的
数据决定页面的显示,但是页面无法决定你数据里面的内容 v-model

<!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>
    <script src="./vue.js"></script>
</head>
<body>
    <div id="root">
        <div :title="'liaozhou '+ title">hello world</div>
        <input v-model="content"/>
        <div>{{content}}</div>
    </div>
    <script>
    new Vue({
        el:"#root",
        data:{
            title:"this is hello world",
            content:"this is content"
        }
    })
    </script>
</body>
</html>

1-6.Vue中的计算属性和侦听器

computed:根据其他数据计算出来的新的结果,其他数据变化的时候进行计算,其他数据没有变化的时候直接读取缓存中的值
watch:侦听器指的是监测某一个数据或者计算属性是否发生变化,,一旦这个数据发生了变化,就可以在watch里面做业务逻辑

<!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>
    <script src="./vue.js"></script>
</head>
<body>
    <div id="root">
        姓:<input v-model="firstName"/>
        名:<input v-model="lastName"/>
        <div>{{fullName}}</div>
        <div>{{count}}</div>
    </div>
    <script>
        new Vue({
            el:"#root",
            data: {
                firstName:'',
                lastName:'',
                count:0
            },
            computed:{
                fullName:function(){
                    return this.firstName +'' + this.lastName
                }
            },
            watch:{
                fullName:function(){
                    this.count ++
                }
            }
        })
    </script>
</body>
</html>

1-7.v-if,v-shou与v-for指令

v-if控制DOM的存在与否

v-show控件DOM的显示与否

v-for控制一组数据,来循环显示数据 (v-for=“item of list”:循环展示一组数据)

v-if 当值为false时,直接将该标签元素从DOM元素中移除,是摧毁与重建过程;

v-show 当值为false时,改变css属性为display:none,只是视觉上的隐藏;如果显示隐藏的频率较高的话,用v-show更好,性能高一些

  • {{item}}

  • 用index序号来保证每一个key值是不一样
    key:每一项的key值都不能相同, 一般可以用 v-for=”(item,index) in list” :key=”index”
    但是如果需要频繁排序的话,key值不适合用index,(为什么不能使用 index,自己去研究) 会有问题。

    v-for=’(item,index) of list’ item 是变量
    this.$emit(“delete”,this.index) 子元素和父元素之间通信

    <!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-if,v-shou,v-for指令</title>
        <script src="./vue.js"></script>
    </head>
    <body>
        <div id="root">
            <div v-if="show">hello world</div>
            <button @click="handleClick">toggle</button>
            <ul>
                <li v-for="(item,index) of list" :key="index">{{item}}</li>
            </ul>
        </div>
        <script>
            new Vue({
                el:"#root",
                data:{
                    show:true,
                    list:[1,2,3]
                },
                methods:{
                    handleClick:function(){
                        this.show=!this.show;
                    }
                }
            })
        </script>
    </body>
    </html>
    

    1-8.Vue中的样式绑定

    1-8-1.class 的对象绑定,利用style 和class 来实现

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Vue中的样式绑定</title>
        <script src="./vue.js"></script>
        <style>
        .activated {
            color:red;
        }
        </style>
    </head>
    <body>
        <div id="app">
            <div @click="handleDivClick"
                :class="{activated: isActivated}"
            >  
                hello world
            </div>
        </div>
        <script>
            var vm = new Vue ({
                el: "#app",
                data:{
                    isActivated:false
                },
                methods:{
                    handleDivClick:function(){
                        this.isActivated= !this.isActivated
                    }
                }
            })
        </script>
    </body>
    </html>
    

    1-8-2.class 的数组绑定,可绑定多个变量,变量定义样式,利用style 和class 来实现

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Vue中的样式绑定</title>
        <script src="./vue.js"></script>
        <style>
        .activated {
            color:red;
        }
        </style>
    </head>
    <body>
        <div id="app">
            <div @click="handleDivClick"
                :class="[activated,activatedOne]"
            >  
                hello world
            </div>
        </div>
        <script>
            var vm = new Vue ({
                el: "#app",
                data:{
                    activated:"",
                    activatedOne:"activated-one"
                },
                methods:{
                    handleDivClick:function(){
                        //三元表达式
                        this.activated=this.activated==="activated"?"":"activated"
                    }
                }
            })
        </script>
    </body>
    </html>
    

    1-8-3.style 的数据绑定

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>Vue中的样式绑定</title>
        <script src="./vue.js"></script>
    </head>
    
    <body>
        <div id="app">
            <div :style="styleObj" @click="handleDivClick">
                hello world
            </div>
        </div>
        <script>
            var vm = new Vue({
                el: "#app",
                data:{
                    styleObj:{
                        color:"black"
                    }
                },
                methods: {
                    handleDivClick:function(){
                        this.styleObj.color=this.styleObj.color === 
                        "black"?"red":"black";
                    }
                }
            })
        </script>
    </body>
    
    </html>
    

    1-8-4.style 的数组绑定

    2.Vue中的组件

    2-1.todolist功能开发

    1. input双向绑定
    2. 循环列表
    3. 绑定提交事件:把value插入数组内 this.list.push(this.dataValue)
    4. 提交后,input为空this.dataValue=””
    5. 向列表中添加数据用 push( ) 如:this.list.pust(this.inputValue)
    6. 写JQ是操作DOM ;vue是在操作数据、
    7. 点击提交,将input的内容放进数组中
    8. 数组有内容,列标签会自动循环,将数据输出
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>Document</title>
            <script src="vue.js"></script>
        </head>
        <body>
            <div id = "root">
                <div>
                <input v-model="inputValue" />
                <button @click="handlerSubmit">提交</button>
                </div>
            <ul>
                <li v-for="(item,index) of list" :key="index">{{item}}</li>
            </ul>
        </div>
        <script>
        new Vue({
            el:"#root",
            data: {
                inputValue:'',
                list:[]
            },
                methods: {
                    handlerSubmit: function() {
                        this.list.push(this.inputValue)
                        this.inputValue=''
                        }
                    }
                })
        </script>
        </body>
    </html>
    

    2-2.todolist 组件拆分

    页面内容过于复杂,可将组件拆分,可定义全局组件或局部组件:

    2-2-1.全局组件:在页面任何地方都能使用

    //定义全局组件<br />    Vue.component("todo-item", {<br />props:['content'],<br />        template: "<label>我是全局组件</label>"<br />    });<br />    new Vue({<br />        el: "#root",<br />    });<br />  //使用全局组件<br /> <div id="root"><br />        <todo-item></todo-item><br />    </div>
    

    Vue.component(‘’) Vue提供的创建组件的方法;
    template 创建组件的模板
    直接在html中有个标签

    组件拆分之后的传参问题:外部(html页面)可以通过自定义属性的形式传参,组件要定义props[]接收属性
    //父组件向子组件传递数据:通过props属性接收传来的参数;props可以是数组。
    Vue.component(“todo-item-2”, {
    props: [“content”, “index”],//接收从外部传进来的属性content、index
    template: “

  • {{index+1}}、{{content}}

  • });

    2-2-2.局部组件:要在外层Vue实例里进行注册

    //定义局部组件<br />    var todoItem = {<br />        template: "<label>我是局部组件</label>"<br />    }
    
    new Vue({<br />        el: "#root1",<br />        components: { //局部组件:要在挂载点(它的外层Vue实例,即此处的root1)进行注册<br />            "todo-item-1": todoItem<br />        }<br />    });
    
    //使用局部组件<br /><div id="root1"><br />        <todo-item-1></todo-item-1><!--局部组件:只能在挂载点底下使用--><br />        <todo-item></todo-item><!--全局组件:在页面任何地方都能使用--><br />    </div>
    
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>Document</title>
            <script src="vue.js"></script>
        </head>
        <body>
            <div id = "root">
                <div>
                <input v-model="inputValue" />
                <button @click="handlerSubmit">提交</button>
                </div>
            <ul>
                <todo-item
                    v-for="(item,index) of list"
                    :key="index"
                    :content="item"
                    >
                </todo-item>
            </ul>
        </div>
        <script>
            Vue.component('todo-item',{
                props:['content'],
                template:'<li>{{content}}</li>'
            })//这是全局组件
                // var TodoItem = {
                //     template:'<li>item</li>'
                // }//这是局部组件
    
    
        new Vue({
            el:"#root",
            // components:{
            //     'todo-item':TodoItem
            // },
            data: {
                inputValue:'',
                list:[]
            },
                methods: {
                    handlerSubmit: function() {
                        this.list.push(this.inputValue)
                        this.inputValue=''
                        }
                    }
                })
        </script>
        </body>
    </html>
    

    2-3.组件与实例的关系

    1. Vue中的每个组件都是vue的实例,每个Vue实例就是由多个组件组成的;在Vue项目中,是由千千万万个vue实例组成的
    2. 如果vue的实例没有模板,找到挂载点(root),把挂载点的div标签下的所有内容当做实例的模板来使用。如果不定义模板,他会使用dom标签的的内容作为实例的模板。
    3. 组件由template(模板),props(接受数据),methods(方法);组件中也可以加计算属性;;data;compute,
    <script>
            Vue.component('todo-item',{
                props:['content'],
                template:'<li @click="handleClick">{{content}}</li>',
                methods:{
                    handleClick:function(){
                        alert('clicked')
                    }
                }
            })//这是全局组件
    
                // var TodoItem = {
                //     template:'<li>item</li>'
                // }//这是局部组件
    
    
        new Vue({
            el:"#root",
            // components:{
            //     'todo-item':TodoItem
            // },
            data: {
                inputValue:'',
                list:[]
            },
                methods: {
                    handlerSubmit: function() {
                        this.list.push(this.inputValue)
                        this.inputValue=''
                        }
                    }
                })
        </script>
    

    2-4.实现 todolist 的删除功能

    父组件通过属性的形式向子组件传递数据
    子组件向父组件传递值是通过发布订阅模式的形式传递的,当子组件发布一个事件,父组件订阅了这个事件,这时父组件就接受到了子组件传递的数据;

    2-4-1.发布订阅模式

    $emit(‘delete’,this.index )
    $emit(‘funA’),emit是动词,意思是发行,发表,在这里可以理解为发布携带的事件funA。子主件使用$emit(‘funA’)发布的事件可以被父组件 v:on (即@funA=’funB’)侦听,随即触发父组件绑定的事件funB。

    父子组件数据传递:想删除子组件中的数据:
    1,子组件的handleClick方法,该组件会用 this.$emit 方法通知给父组件,触发一个叫 delete 的自定义事件,通知的值为 this.index。这里的 this.index 是前面从父组件中递过来的。
    2,父组件用 @delete(v-on:delete)=”handleDelete” 来监听子组件的事件。

    <!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>todoList</title>
        <script src="./vue.js"></script>
    </head>
    <body>
        <div id="box">
            <input type="text" v-model="txtValue">
            <input type="button" @click='handleClick' value="提交">
            <ul>
                <todo-item 
                v-for="(item,index) of list" 
                :key="index" 
                :content="item" 
                :index="index" 
                @delete="handleDelete">
                </todo-item>
            </ul>
        </div>
        <script>
            //创建一个全局组件
            Vue.component('todo-item', {
                props: ['content', 'index'],
                template: '<li @click="handleClick">{{content}}</li>',
                methods: {
                    handleClick: function () {
                        this.$emit('delete', this.index)
                    }
                }
            })
    
            new Vue({
                el: "#box",
                data: {
                    txtValue: '',
                    list: []
                },
                methods: {
                    handleClick: function () {
                        this.list.push(this.txtValue),
                            this.txtValue = ''
                    },
                    handleDelete: function (index) {
                        this.list.splice(index, 1)
                    }
                }
            })
        </script>
    </body>
    </html>
    

    如果用普通的由子传父的方式,很麻烦。如图功能有没有简单的方法实现呢。
    Vue 基础教程 - 图2
    props:[‘item’,’index’],
    template:’

  • {{item}}
  • ‘,
    methods:{
    deleteItem:function(){
    this.$root.list.splice(this.index,1)//子组件这样写就好了,通过$root访问到父组件,然后直接操作父组件的数据,就不用采用老师讲的发布订阅模式了,但是老师讲的这个知识点还是必须掌握的,老师也说了这是vue的重点

    2-5.Vue-cli的简介与使用

    Vue介绍:
    数据驱动的组件,为现代化的Web界面而生
    Vuejs不是一个框架,它只是一个提供MVVM风格的双向数据绑定的库,专注于UI层面。

    Vue安装:
    1)独立版本:
    ①下载并用