小白的Vue学习笔记

学习地址:https://www.bilibili.com/video/BV1YE411A746
这是我在B站学习写的一些笔记,可能会有些乱,凑合看吧。

Vue

在这里插入图片描述

在这里插入图片描述

MVVM

Vue技术是MVVM开发模式的实现者

MVC——M(Model)、V(View)、C(Controller)

MVVM——M(model)、V(View)、VM (ViewModel),连接视图和数据的中间件

在这里插入图片描述

其他MVVM实现者:

  1. AngularJS
  2. ReactJS
  3. 微信小程序

快速上手

https://cn.vuejs.org/v2/guide/

安装

【概念:CDN:内容分发网络,这是一种加速策略,能够自动从离自己最近的服务器上快速获取所需要的资源】

尝试 Vue.js 最简单的方法是使用 Hello World 例子。你可以在浏览器新标签页中打开它,跟着例子学习一些基础用法。或者你也可以创建一个 .html 文件,然后通过如下方式引入 Vue:

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

或者:

<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

安装教程给出了更多安装 Vue 的方式。请注意我们不推荐新手直接使用 vue-cli,尤其是在你还不熟悉基于 Node.js 的构建工具时。

如果你喜欢交互式的东西,你也可以查阅这个 Scrimba 上的系列教程,它揉合了录屏和代码试验田,并允许你随时暂停和播放。

提示:也可以通过百度 cdn vue获取各种版本的地址:https://cdn.baomitu.com/vue

Hello World

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>vue</title>
<!--    <link rel="shortcut icon" href="" type="">-->
</head>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js" type="text/javascript"></script>

<body>
    <div id="app">
        <span>
            {{ title }}
        </span>
        <input type="text" v-model="title">
    </div>

</body>
</html>

<script>
    const app = new Vue({
        el: "#app",
        data: {
            title: 'hello world'
        }

    });
</script>

运行效果展示:

在这里插入图片描述

当在输入框中输入内容时,左边的span标签内容也跟着改变

在这里插入图片描述

这就是MVVM架构中VM的妙处!(ViewModel能够观察到数据的变化,并对视图对应的内容进行更新)

总结:

  1. html中要有一个div,id为app(当然其他也行)
  2. js中要有一个Vue对象

讲解

<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        欢迎你,{{age}}岁的{{name}}!   <!--{{ }}指的是插值表达式-->
    </div>
</body>
</html>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    new Vue({
        el:"#app",	//el指的是element,里面放元素的解析器,#app就代表id值为app的元素
        data:{			//html中通过差值表达式获取data中存放的数据
            age:18,				//以后,这里的数据都是通过发送ajax请求来获得
            name:"小明"
        }
    });
</script>

插值表达式

插值表达式是用在html中被绑定的元素中的。目的是通过差值表达式来获取Vue对象的属性方法

属性通过data提供,方法通过methods提供。

例如运行下面的代码,会直接弹出一个框。

<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        {{sayHi()}}  <!--可以要括号,可以不要括号-->
    </div>
</body>
</html>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
    new Vue({
        el:"#app",
        methods:{
            sayHi:function (){
                alert("Hello World!");
            }
        }
    });
</script>

除此之外,还可以这么使用

<div id="app">
    {{sayHi()}}<br>
    {{[1,2,3,4,5][1]}}<br> <!--取数组元素-->
    {{{name:"小明",age:18}.name}}<br> <!--取json元素-->
</div>

显示在页面中的内容是


2
小明

Vue中的关键字

这些关键字都是作为html页面中标签中的属性来使用

v-model

【MVVM双向数据绑定】将标签的value值与vue实例中的data属性进行绑定。

这里的代码举例和Hello World 中的一样。

v-on

【事件绑定】通过配合具体的事件名,来绑定vue中定义的函数。

<input type="text" v-on:input="changeTitle" />

v-on叫绑定事件,事件是input,响应行为是changeTitle。也就是说,当input元素发生输入事件时,就会调用vue里定义的changeTitle方法

例子:

<!DOCTYPE html>
<html lang="ch-CN" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        <button v-on:click="show()">Hello World</button>
    </div>
</body>
</html>
<script src="vue.js"></script>
<script>
    new Vue({
        el:"#app",
        methods:{
            show:function (){
                console.log("Hello World");
            }
        }
    });
</script>

补充:

  1. methods里面放的函数,可以加一个event参数,event就代表当前事件,然后可以用event.target 来获取当前事件的对象,然后再通过event.target.value来获取当前事件的对象的value属性。

    用法举例:每改变输入框中的内容都将它打印到控制台

    <!DOCTYPE html>
    <html lang="ch-CN" xmlns:v-on="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="shortcut icon" href="" type="">
    </head>
    <body>
        <div id="app">
            <input type="text" v-on:input="show"> <!--踩坑:不能加(),要不然无法传参-->
        </div>
    </body>
    </html>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el:"#app",
            methods:{
                show:function (ev){  //不一定要是event,随便一个名字都行
                    console.log(ev.target.value);
                }
            }
        });
    </script>
    
    
  2. this的用法,主要在methods里面的函数,用this.属性可以直接访问和修改data里的数据。

    //下面2个方法都可以直接获取data里的属性
    this.$data.属性名
    this.属性名
    //下面2种方法可以直接调用methods里的方法
    this.方法名();
    this.$options.methods.方法名();
    
    
  3. v-on还可以简写成@,比如v-on:input可以写成@input

v-bind

【属性绑定】内容才可以用差值表达式,属性不可以,比如下面这行是没有用的。

<a href="{{link}}"></a>

注意:差值表达式不能写在html的标签中,不能作为属性的一部分。

正确做法:v-bind:标签属性="值"

<a v-bind:href="link">链接</a>

扩展:v-bind可以简写成":"

<a :href="link">链接</a>

v-once

加上这个标签之后,里面的差值表达式只获取一次数据。之后的数据变化不影响此插值表达式的值。

v-html和v-text

v-html会将vue中的属性的值作为html的元素来使用
v-text会将vue中属性的值只作为纯文本来使用

例子:

<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        <span v-html="val"></span>  <br>
        <span v-text="val"></span>
    </div>
</body>
</html>
<script src="vue.js"></script>
<script>
    new Vue({
        el:"#app",
        data:{
            val:"<button>按钮</button>"
        }
    });
</script>

效果:

在这里插入图片描述

分支语句

点击查看官方文档

v-if
v-else-if
v-else

示例代码如下:

<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        <div>
            <input type="checkbox"  id="temp1" v-model="temp1"> <label for="temp1">temp1</label>
            <input type="checkbox"  id="temp2" v-model="temp2"> <label for="temp2">temp2</label>
        </div>
        <div>
            <div v-if="temp1">看到v-if的内容</div>  <!--temp1=true时显示-->
            <div v-else-if="temp2">看到v-else-if的内容</div> <!--当temp1=false且temp2=true时显示-->
            <div v-else="">看到v-else的内容</div>	<!--当temp1=false且temp2=false时显示-->
        </div>
    </div>
</body>
</html>

<script src="../vue.js"></script>
<script>
    new Vue({
       el:"#app",
       data:{
           temp1:true,
           temp2:false
       }
    });
</script>

v-show

实现的效果跟v-if是一样的,都是当该属性的值是true时,显示该标签的内容,为false时不显示。

区别是,v-show隐藏内容的原理是直接修改标签的css样式:display:none,而v-if则是直接删除掉那个标签,所以,在效率上,v-show更好一点。

循环语句v-for

遍历普通的数组

举例:

<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="v in nums">{{v}}</li>
        </ul>
    </div>
</body>
</html>

<script src="../vue.js"></script>
<script>
    new Vue({
        el:"#app",
        data:{
            nums:[1,2,3,4,5,6]
        }
    });
</script>

显示效果:

在这里插入图片描述

  1. <li v-for="v in nums">{{v}}</li>,表示遍历数组nums,取得数组里的每一个元素v

  2. <li v-for="(v,i) in nums">{{v}}-->{{i}}</li> ,遍历出得到的v是数组的每一个元素value,而i则是下标index

  3. 第二条,(v,i)得到的v是值i是下标是他自己规定的,第一个参数是值,第二个参数是下标,如果你就是想第一个参数是下标也是可以的,直接在语句后面指定:

    <li v-for="(i,v) in nums":key="i">{{i}}-->{{v}}</li>
    
遍历对象

举例子:

<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="v in student">{{v}}</li>
        </ul>
    </div>
</body>
</html>

<script src="../vue.js"></script>
<script>
    new Vue({
        el:"#app",
        data:{
            student:{
                name:"张三",
                age:18
            }
        }
    });
</script>
  1. <li v-for="v in student">{{v}}</li> 输出的是student里的每一个value
  2. <li v-for="(v,k) in student">{{v}}--{{k}}</li> 输出的时候,vvaluekkey
  3. <li v-for="(v,k,i) in student">{{v}}--{{k}}--{{i}}</li>,输出的时候,vvaluekkeyiindex
遍历对象数组

看例子:

<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="student in students">
                <div v-for="(v,k) in student">{{k}}--{{v}}</div>
            </li>
        </ul>
    </div>
</body>
</html>

<script src="../vue.js"></script>
<script>
    new Vue({
        el:"#app",
        data:{
            students:[{
                name:"张三",
                age:18
            },{
                name:"李四",
                age:19
            },{
                name:"王五",
                age:20
            }
            ]
        }
    });
</script>

事件

范例1

点击按钮,数字加1

<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        <div>
            当前数字:{{count}}
        </div>
        <button type="button" @click="increase()">增加</button>
    </div>
</body>
</html>

<script src="vue.js"></script>
<script>
    new Vue({
        el:"#app",
        data:{
            count:0
        },
        methods:{
            increase:function (){
                this.count+=1;
            }
        }
    });
</script>

范例2

鼠标移动到那里,显示鼠标的X坐标和Y坐标

<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">

        <div style="width: 400px;height: 300px;background-color: blanchedalmond" @mousemove="move"></div>
        X:{{px}}&ensp;&ensp;Y:{{py}}
    </div>
</body>
</html>

<script src="vue.js"></script>
<script>
    new Vue({
        el:"#app",
        data:{
            px:0,
            py:0
        },
        methods:{
            move:function (event) {
                this.px = event.clientX;
                this.py = event.clientY;
            }
        }
    });
</script>

参数绑定

范例1那里,可以传入一个步长,代表每点击一次都增加对应的数字。

<div id="app">
    <div>
    当前数字:{{count}}
    </div>
    <button type="button" @click="increase(2)">增加</button>
</div>
new Vue({
        el:"#app",
        data:{
            count:0
        },
        methods:{
            increase:function (step){
                this.count+=step;
            }
        }
    });

★ 如果想传入事件对象,可以在括号里面输入$event

例如范例2:

<div style="width: 400px;height: 300px;background-color: blanchedalmond" @mousemove="move($event)"></div>

停止鼠标事件

法一:在函数里加一行代码

<span v-on:mousemove="dummy">停止鼠标事件</span>
dummy:function (ev) {
    ev.stopPropagation();
}

法二:直接在标签的参数里面加一个属性(这就叫事件修饰符)

<span v-on:mousemove.stop>停止鼠标事件</span>

事件修饰符

查看官方文档

<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

按键修饰符

查看官方文档

<input v-on:keyup="submit">  <!--这一行表示只要按下任意一个键,都会执行submit函数-->
<!-- 只有在按下回车键的时候才会执行submit -->
<input v-on:keyup.enter="submit">

vue改变内容

常规:使用差值表达式

比如上面的范例1,可以加上{{count>10?"大于10":"不大于10"}}来显示“大于10”/“不大于10”,当count大于10时,将会显示"大于10"

计算属性:computed

在这里插入图片描述

例子:

<!DOCTYPE html>
<html lang="ch-CN" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        {{getDate()}}<br>
        {{getDate1}}
    </div>
</body>
</html>

<script src="vue.js"></script>
<script>
    new Vue({
        el:"#app",
        methods:{
            getDate:function (){
                return new Date();
            }
        },
        computed:{
            getDate1:function (){
                return new Date();
            }
        }
    });
</script>

首先,应该明确,getDate是一个函数,getDate1只是一个属性而已!

所以差值表达式那里{{getDate1}}不能加括号!!

可以理解为:每一次getDate() 都会重新执行那个函数,然后取返回值,而getDate1 只是第一次会执行那个函数取返回值,之后再执行的话就直接取缓存里的数据了!

使用计算属性可以提高vue的效率(一些常用的函数,可以缓存起来,下次调用时直接获取缓存里的返回值)!

监控属性:watch

通过watch里给data里的属性绑定一个函数,当属性的值发生变化时,该函数就会调用。

例如:当输入框的内容发生改变时,控制台输出一句话。

<div id="app">
    {{title}}
    <div>
    	<input v-model="title">
    </div>
</div>
new Vue({
    el:"#app",
    data:{
        title:"hello"
    },
    watch:{
        title:function (){ //这里的key值需要和data里的key一样
            console.log("改变了");
        }
    }

});

◆扩展:watch里放的函数可以绑定两个参数newValueoldValue

title:function (newValue,oldValue){
    console.log(oldValue + "-->" + newValue);
}

vue改变样式

通过修改class属性

class的动态绑定

最常规的方法就是通过改变class属性来改变样式。所以我们通过v-bind:class属性来设置class。

奇怪的知识:v-bind:class的值可以是json格式,需要key值为class值valueboolean值的属性。

v-bind:class="{red:true,green:false}"就表示这个元素的class属性包含red而不包含green

通过前面数据绑定的方式,可以在data里加一个temp ,然后标签内属性设置为v-bind:class="{red:temp}"

上代码:

<!DOCTYPE html>
<html lang="ch-CN" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">


    <style>
        .mydiv {
            margin: 20px;
            width: 400px;
            height: 300px;
            background-color: darkgrey;
        }

        .red {
            background-color: red;
        }

        .green {
            background-color: green;
        }

        .blue {
            background-color: blue;
        }

    </style>

</head>


<body>
<div id="app">
    <div class="mydiv" v-bind:class="{red:r,green:g,blue:b}"></div>
    <button @click="cr()">打开/关闭red</button>
    <button @click="cg()">打开/关闭green</button>
    <button @click="cb()">打开/关闭blue</button>
</div>
</body>
</html>


<script src="../vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data: {
            r: false,
            g: false,
            b: false
        },
        methods: {
            cr: function () {
                this.r = !this.r;
            }, cg: function () {
                this.g = !this.g;
            }, cb: function () {
                this.b = !this.b;
            }
        }
    });
</script>
使用computed优化

前面说了,computed里面其实都是属性,所以computed可以直接返回一个json,然后被v-bind:class里直接引用。

例子:(基于上面的代码修改)

<div class="mydiv" v-bind:class="myclass"></div>
computed:{
    myclass:function (){
        return {
            red:this.r,
            green:this.g,
            blue:this.b
        }
    }
}
通过双向数据绑定

这就更有意思了,可以直接在一个input框里通过v-model绑定一个color属性,然后再给div的v-bind:class绑定那个color。

最终的效果是:输入框输入red时,div变红色,输入green时绿色

<!DOCTYPE html>
<html lang="ch-CN" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
    <style>
        .mydiv {
            margin: 20px;
            width: 400px;
            height: 300px;
            background-color: darkgrey;
        }

        .red {
            background-color: red;
        }

        .green {
            background-color: green;
        }

        .blue {
            background-color: blue;
        }
    </style>
</head>
<body>
<div id="app">
    <div class="mydiv" v-bind:class="color"></div>
    <input type="text" v-model="color">
</div>
</body>
</html>
<script src="../vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data: {
            color:""
        },

    });
</script>
v-bind:class的一些细节
  1. 值可以是json格式的数据(正如上面演示的那样),其中key为要使用的class,valueboolean型数据,当为true时时使用这个class
  2. 值也可以是数组类型,如<div class="mydiv" v-bind:class="[color,mywidth]"></div> 表示class同时属性同时绑定data里的colorwidth注意:如果要绑定多个data里的数据,不能写多个v-bind:class,不起作用的。
    不能这么写:<div class="mydiv" v-bind:class="color" v-bind:class="mywidth"></div>

通过修改style属性

修改html的样式,除了外部引入(直接在外部定义了css的样式然后通过修改class属性来改变样式),还有内嵌引入,就是直接在标签里面使用style属性!

<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="shortcut icon" href="" type="">
</head>
<body>
    <div id="app">
        <div style="background-color: aqua;width: 400px;height: 300px">普通的style</div>
        <div v-bind:style="{backgroundColor:color,width:width,height:height}">Vue的style</div>
    </div>
</body>
</html>
<script src="../vue.js"></script>
<script>
    new Vue({
        el:"#app",
        data:{
            color:"gray",
            width:"400px",
            height:"300px"
        }
    });
</script>

注意:

  1. v-bind:style是json格式的键值对,其中value值是绑定Vue中data里的数据的

  2. key中所有的由-拼接成的单词都改成驼峰式命名,比如style中的background-color,Vue中就写成backgroundColor,这一点和我们DOM中的操作是一样的

    document.getElementById("aa").style.backgroundColor = "blue";
    
  3. 也可以使用computed属性,但computed返回值必须要是json

  4. 可以使用数组将多个json或者computed合并在一起

虚拟DOM和diff算法

Vue高效的核心。

在这里插入图片描述

Vue实例

var v1 = new Vue();

指的就是Vue的实例。

实例属性

属性是指在datacomputed里定义的,而方法是在method里定义的。实例属性是指Vue对象自己的属性,比如之前接触的eldatacomputedwatch … 这些不能直接通过Vue对象.的方式获得的。***如果要访问,必须要加上$***,如v1.$data

v1.$data.title可以写成v1.title

官方文档链接

$refs

给html的标签加上ref属性,那么在Vue中可以直接根据ref属性的值来获取这个标签,和id的用法有点像。

<div id="app">
    <div ref="div1">红红火火恍恍惚惚</div>
    <button @click="change()">点我</button>
</div>
new Vue({
    el:"#app",
    methods:{
        change:function (){
            this.$refs.div1.innerHTML = "哈哈哈哈哈哈哈哈哈哈或或或或或或或或或或或或或或或或或";
        }
    }
});

总结:可以直接通过vue实例.$refs.标签的ref属性值来操作这个标签体。

id的区别:当有多个标签的id值相同时不会报错,而ref会报错。

$mount

实现Vue对象与页面元素的动态绑定,之前都是通过el官方文档

<div id="app">

</div>
<button onclick="bc()">点我</button>
var v1 = new Vue({
    template:"<h1>Hello World</h1>"
});
function bc(){
    v1.$mount("#app");
}

实现效果:点击按钮就显示Hello World,其实template是干嘛用的我也不知道(在下面的组件那里可能会深有体会)

组件

Vue的一大特性:组件化,就是可以将一个Vue对象注册成一个组件,反复使用!

要想实现组件化,必须要注册组件,注册组件有2种方式:全局注册本地注册

全局注册

注册组件时,使用Vue的静态方法:Vue.component("组件名称", 对象)

使用组件时,直接使用标签即可:<组件名称></组件名称>,但是,必须注意:必须要在已经被Vue绑定的标签里面才能使用组件,要不然不起作用!

例子:

<div id="app">
	<model1></model1>
</div>
Vue.component("model1",{
	template: "<h1>Hello World</h1>"
});
new Vue({
	el:"#app"
});

进阶版:既然组件也是一个Vue的实例,所以也可以加上data属性和methods属性。

Vue.component("model1",{
    template: "<div><button @click='cbtn()'>点我</button></div>",
    methods:{
        cbtn:function (){
            alert("哈哈哈哈哈哈哈");
        }
    }
});

在template属性里面用插值表达式来引用data里的内容有点不行,会报错

Vue.component("model1",{
    template: "<div>{{title}}</div>",
    data:{
        title:"哈哈哈哈哈哈哈"
    }
});

在这里插入图片描述

解决方案 是:

Vue.component("model1",{
    template: "<div>{{title}}</div>",
    data:function (){
        return {
            title:"哈哈哈哈哈哈哈"
        }
    }
});

这里需要稍微注意一下!!!!!!!!!

本地(局部)注册

就是直接加一个实例属性component而已,和全局的区别,懂的都懂!

new Vue({
    el: "#app",
    components: {
        model1: {
            template: "<div><div>{{title}}</div><button @click='func()'>点我</button></div>",
            data: function () {
                return {
                    title: "哈哈哈哈哈哈哈"
                }
            },
            methods: {
                func: function () {
                    alert("红红火火恍恍惚惚");
                }
            }
        }
    }
});
Vue作为组件使用的注意事项
  1. data的写法:平时创建Vue实例时的data属性直接是一个json对象,而作为组件时,data属性必须是一个函数,返回值才是json对象。

  2. template是将内容展现在页面上的一个键,值是一个字符串。注意:template里有且只有一个根标签,不能没有或者多个根标签并列!,就比如你不可以这样:

    <div>{{title}}</div><button @click='func()'>点我</button>
    

    但是可以这样(加上了根标签)

    <div><div>{{title}}</div><button @click='func()'>点我</button></div>
    
优化

注册组件的时候甚至可以这样,先把json定义在外面,然后在里面再引用。

var model1 = {
    template: "<div><div>{{title}}</div><button @click='func()'>点我</button></div>",
    data: function () {
        return {
            title: "哈哈哈哈哈哈哈"
        }
    },
    methods: {
        func: function () {
            alert("红红火火恍恍惚惚");
        }
    }

};
new Vue({
    el: "#app",
    components: {
        model1: model1
    }
});

生命周期

官方文档

官方API

Vue 实例生命周期
new Vue({
    el:"#app",
    beforeCreate(){
        console.log("beforeCreate")
    },
    created(){
        console.log("created")
    },
    beforeMount(){
        console.log("beforeMount")
    },
    mounted(){
        console.log("mounted")
    },
    beforeUpdate(){
        console.log("beforeUpdate")
    },
    updated(){
        console.log("updated")
    },
    beforeDestroy(){
        console.log("beforeDestory")
    },
    destroyed(){
        console.log("destory")
    }
});

也可以是这种形式

beforeCreate:function (){
    console.log("beforeCreate")
}

vue-cli

vue-cli骨架

CLI(command line interfaces )命令行接口。在进行Vue项目开发时,可以选择不同的Vue模板进行项目的搭建,比如simplewebpack-simplewebpackbrowserify/browserify-simple等;vue-cli是官方提供的一个脚手架(预先定义好的目录结构及基础代码,咱们在创建 Maven 项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架),用于快速生成一个vue的项目模板。

在这里插入图片描述

要想使用vue-cli,得先安装node.js
node.js是一个快要让前端运行在node.js提供的服务器上的一个工具,换句话说,就是提供了一个服务器。

node.js

下载

官网:https://nodejs.org/zh-cn/download/

安装无脑下一步。

检查是否安装成功:cmd输入node -v

使用node.js安装vue-cli
npm install vue-cli -g

参数解释:

  1. npm:是指使用node.js的命令
  2. install:安装
  3. vue-cli:要安装的工具
  4. -g:全局

如果安装比较慢,可以使用淘宝镜像

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

然后安装

cnpm install vue-cli -g  # 把npm替换成cnpm
使用vue-list下载项目骨架来搭建我们的项目

使用以下命令可以列出当前官方提供的骨架,然后就可以利用官方提供的这些骨架来创建我们的项目

vue list

在这里插入图片描述

搭建项目:

vue init webpack-simple myvuedemo

其中webpack-simple是要使用的模板名称,myvuedemo是要创建的项目名称,完成后,会自动在当前文件夹创建一个文件夹,名称为“项目名称”

在这里插入图片描述

项目生成后,输入cd 项目名称,进入项目文件夹

然后npm install,安装项目所需的依赖

在这里插入图片描述

最后npm run dev,以开发的模式启动项目。

启动后就能在浏览器中输入http://localhost:8080/ 即可访问。

在这里插入图片描述

项目完成后,运行npm run build 来发布项目

webpack-simple

项目内结构
  1. index.html

    无论前端页面有多复杂,index.html都只有11行

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>myvuedemo</title>
      </head>
      <body>
        <div id="app"></div>
        <script src="/dist/build.js"></script>
      </body>
    </html>
    

    实际的内容已经被打包进/dist/build.js里面

  2. vue.js
    整个vue项目的入口函数

    import Vue from 'vue'
    import App from './App.vue' //导入了App.vue组件
    
    new Vue({
      el: '#app', //让当前vue对象绑定页面上id是app的那个div
      render: h => h(App) //让App.vue的内容出现在该div中
    })
    
    
  3. App.vue
    这种以.vue为扩展名的文件,实际上就是一个Vue对象。在这里这种组件也称为Vue组件。

.vue文件的组成结构

idea里可以安装vue.js插件来添加对.vue文件的支持

一个Vue文件由<template>,<script>,<style>组成。

在这里插入图片描述

注:<style>可以加上scoped属性,表示样式只作用在当前组件,否则,会作用在整个页面!

vue组件的全局注册

我在src目录下创建一个components/myvue.vue文件

<template>
    <div>
        我的组件
    </div>
</template>

<style>

</style>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
    
})
</script>

现在我要全局注册这个组件,就要修改main.js

import myvue from './components/myvue.vue'

Vue.component("myvue",myvue); //和之前学的一样
本地注册

在组件的内部注册,比如我只在App.vue里注册一个组件

<script>
import myvue from "./components/myvue.vue";//导入

export default {
  
  name: 'app',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  components:{ //和上面学过的一样
    "mmvue":myvue
  }
}
</script>
组件之间的参数传递
父传子

在组件内部的Vue对象里定义一个props参数,值为一个数组对象,数组的每一个元素就是属性名。然后在使用这个组件的时候,在标签里加上这个属性就可以了!

比如,myvue.vue里,

<template>
    <div>
        {{myTitle}}  <!--插值表达式使用myTitle属性-->
    </div>
</template>

<style>

</style>

<script>
import Vue from 'vue'
export default Vue.extend({
    props:["myTitle"]  // 这里表示定义一个myTitle的属性
})
</script>

在App.vue里,这样子传入参数

<template>
  <div id="app">
    <myvue myTitle="你好"></myvue>
  </div>
</template>

总结:Vue 的插值表达式获取vue对象的属性,可以通过3种方式:

  1. data
  2. computed
  3. props

props的写法:

  1. 数组:
    和上面一样,props:["args1",args2]"就表示接受2个参数

  2. json对象,稍微复杂些:

    props:{
        myTitle:{
            type:String,
            required:true,
            default:"hello"
        }
    }
    
子传父

原理就是父组件传入一个函数作为参数,然后子组件调用这个函数,就可以传数据了!

<!--子组件-->
<template>
    <div>
        <button v-on:click="func(msg)">点我</button>
    </div>
</template>

<style>

</style>

<script>
import Vue from 'vue'
export default Vue.extend({
    props:{
        func:{
            type:Function,
            required:true
        }
    },
    data:function(){
        return{
            msg:"hello world!"
        }
    }
})
</script>
<!--App.vue-->
<template>

  <div id="app">
      {{msg}}

      <myvue1 :func="func"></myvue1>


  </div>

</template>

<script>

export default {
  
  name: 'app',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },methods:{
    func:function(data){
        this.msg = data;
    }
  }
}
</script>

<style lang="scss">

</style>

发送ajax请求

安装Axios模块
npm install --save axios vue-axios
使用Axios

main.js中加上

import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)   //顺序不颠倒
发送ajax
this.axios({
    method:'get',
    url:'http://bit.ly/2mTM3nY',
    data:{}
})
.then(function (response) {
    console.log(response.data)
});
服务器端(springmvc)解决跨域问题

发送请求会发生下面的错误(不允许跨服务器访问):

在这里插入图片描述

在springmvc.xml中加入以下代码

<mvc:cors>
<mvc:mapping path="/**"
allowed-origins="*"
allowed-methods="POST, GET, OPTIONS, DELETE, PUT,PATCH"
allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-RequestedWith"
allow-credentials="true" />
</mvc:cors>

其中,allowed-origins指的是允许的访问源的域名,"*"表示任何人都可以访问,也可以指明具体的域名 。

跨域问题解释:
跨域,指的是浏览器不能执行其他网站的脚本。他是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。

所谓同源,是指:域名,协议,端口均相同!

比如:http://www.qf.com/ -> http://admin.qf.com/
http://www.qf.com/ -> http://www.qf.com:8080/
http://www.qf.com/ -> https://www.qf.com/ 均是跨域!

跨域的解决方案:CORS

路由(组件之间的跳转)

路由器:在数据通信时,帮你选择通信的路线

Vue中的路由,能够帮助我们在一个Vue组件中实现其他组件的相互切换。也就是说,可以通过路由模块,再创建路由表,将指定的组件显示在路由视图<router-view>中。

安装路由模块
npm install vue-router -s
设计路由界面

在src下创建components文件夹,文件夹内创建user, Home组件

  • user.vue

    <template>
    	<div>user</div>
    </template>
    
  • Home.vue

    <template>
    	<div>Home</div>
    </template>
    
创建静态路由表

在src目录下创建routes.js

import Home from './components/Home.vue'
import User from './components/user.vue'

export const routes = [
    {path:'/',component:Home},
    {path:'/user',component:User}
]
引入路由模块并使用

在main.js中引入路由模块(当然这部分可以放在vue组件的<script>里,类似组件的本地注册)

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router' //1.引入路由模块
import {routes} from './routes.js' //2.引入静态路由表,地址是第一步创建的那个文件的路径
Vue.use(VueRouter); //3.使用路由模块
//4.创建一个VueRouter模块的实例
const router = new VueRouter({
	routes:routes
});

new Vue({
    el: '#app',
    router,//5.把router实例放入到vue实例中
    render: h => h(App)
})
体验

App.vue:(不一定是App.vue,可以是一个组件,然后在App.vue里面引入就好了!)

<template>
    <div class="container">
        <div class="row">
            <div class="col-xs-12 col-sm-8">
                <h1>Routing</h1>
                <router-view></router-view>  <!--记得要加上这一行,要不然不显示-->
            </div>
        </div>
    </div>
</template>

改变url,发现中的内容发生改变

  • http://localhost:8080/#/ 显示home
  • http://localhost:8080/#/user 显示user

向router实例中添加mode属性:

  • 值"hash": url带# 适用于调试模式
  • 值"history" url不带#

注意:一定要加上<router-view></router-view>,要不然显示不了!

链接路由的实现
<template>
    <div>
        <span><router-link to="/">Home</router-link></span>
        <span><router-link to="/user">user</router-link></span>
        <router-view></router-view>
    </div>
    
</template>

在这里插入图片描述

实现的是导航条的效果:当点击Home时,显示home.vue的内容,当点击user时,显示user.vue的内容。

另外也可以通过JS的方式实现跳转:

this.$router.push("/user")
路由之间的参数传递
设参

在routes.js中,修改路径表

{path:'/user/:id',component:User}

在路径后面加上:id,表示接受一个id参数。

传参

就是在地址后面加上/再接上参数而已。

<span><router-link to="/user/10086">user</router-link></span>
接参

this.$route.params.参数名称

data:function(){
    return {
        id:this.$route.params.id
    }
}
嵌套路由(子路由)

在路由显示的组件内部,又嵌套着路由,称为子路由

嵌套路由的实现:

  1. 配置路由表,要称为哪个路由的子路由,就在哪个路由就上children

    export const routes = [
        {
            path:'/home',
         	component:Home,
            children:[{
                path:"/productList",   //使用嵌套路由,直接地址是/productList,而不是/path/productList
                component:productList
            },{
                path:"/productInfo",
                component:productInfo
            }]
        },
        
        {path:'/user',component:User}
    ]
    

静态资源打包问题

在这里插入图片描述
在这里插入图片描述

webpack-Vue 工程项目

创建工程

  1. 创建工程

    # 使用 webpack 打包工具初始化一个名为 hello-vue 的工程
    vue init webpack hello-vue
    
  2. 安装依赖

    # 我们需要安装 vue-router 、 element-ui 、 sass-loader 和 node-sass 四个插件
    # 进入工程目录
    cd hello-vue
    # 安装 vue-router
    npm install vue-router --save-dev
    # 安装 element-ui
    npm i element-ui -S
    # 安装 SASS 加载器
    npm install sass-loader node-sass --save-dev
    

    安装完后安装依赖:npm install

  3. 启动

    npm run dev
    

附:npm命令

npm install moduleName # 安装模块到项目目录下
npm install -g moduleName # -g 的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看 npm configprefix 的位置
npm install -save moduleName #--save 的意思是将模块安装到项目目录下,并在 package 文件的dependencies节点写入依赖, -S 为该命令的缩写
npm install -save-dev moduleName #--save-dev 的意思是将模块安装到项目目录下,并在 package 文件的devDependencies节点写入依赖,-D 为该命令的缩写

引入element-ui

main.js

// 导入 ElementUI
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

// 安装 ElementUI
Vue.use(ElementUI);

有关他的使用,详情见官网

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值