Vue学习-1

作为一个java后端开发,最近有时候会用到Vue进行前端开发,特地来补课. 此篇博客作为我学习Vue的一个记录,以及知识汇总.不会把知识点罗列到很细,仅供自己之后参考.

基础

Vue 中文官网https://cn.vuejs.org/

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

开始使用

入门开始,官网下载Vue.js,导入到我们的html页面中.
在html的body中定义一个div,设置id为app(可以自定义),在script脚本中,new 一个Vue对象,其中el属性根据id取刚才定义的app对象。代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
    {{name}}
</div>
</body>
<script>
    let app = new Vue({
        el:'#app',
        data:{
            name:"张三"
        }
    })
</script>
</html>

基本语法

会发现我们定义的div中显示的是我们定义的vue对象中的属性。这就是一个Vue的入门语法,双大括号,官方称做mustache语法。
最开始的定义Vue对象方法,其实跟java中创建对象比较相似。我认为可以将其看作一个构造函数,该构造函数需要传入一个对象,格式是json格式。这样就好理解了。

vue对象内容:

vue对象中,包含一些属性。
el:指定对应标签id
data:当前vue对象的数据
methods:当前对象的方法
computed:当前对象的计算属性。可以当做属性用,但是是通过方法得出来的属性
component:当前vue对象的组件
created:初始化vue时执行的方法(钩子函数)1。类似于java中的构造方法

基本命令

v-on:

标识给对应组件添加对应的事件。 v-on:[event].[des] 表示给当前组件添加对应事件,并且被对应修饰符2修饰。示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
   <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
   <button v-on:click="alert">点我</button>
</div>
</body>
<script>
   let app = new Vue({
       el:'#app',
       methods:{
           alert:function (){
               alert("你点击了我!")
           }
       }
   })
</script>
</html>

就是给一个按钮添加了点击事件,里面传入方法名,对应方法需要在vue对象中定义好.同样的可以定义别的事件,来触发自定义逻辑
语法糖:@[event],

v-bind:

可以给当前标签添加各种属性。例如class,style,key等等。我目前用的也不是很熟练,可以参考这里,当然,这个

v-for:

循环遍历某个指定元素,并且生成若干当前标签。共有三种写法。示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
   <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
   遍历集合
   <div v-for="book in books">{{book}}</div>
   ---------------------------
   遍历集合,并取出下标
   <div v-for="(book,index) in books">{{book}}--{{index}}</div>
   -----------------------------
   遍历对象,取出对象中的键值对以及下标
   <div v-for="(key,value,index) in job">{{key}}--{{value}}--{{index}}</div>
</div>
</body>
<script>
   let app = new Vue({
       el:'#app',
       data:{
           job:{
               place:"上海",
               work:"上班",
               des:"赚钱"
           },
           books:[
               {
                   name:"十万个为什么",
                   price:10
               },
               {
                   name:"二十万个为什么",
                   price:20
               },
               {
                   name:"三十万个为什么",
                   price:30
               },
           ]
       }
   })
</script>
</html>

语法糖::[data]

v-model

绑定vue对象的值到某个标签上。这个指令会自带双向绑定效果。相当于v-on+v-bind结合。示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
    <input v-model="text">
    {{text}}
</div>
</body>
<script>
    let app = new Vue({
        el:'#app',
        data:{
            text:"阳光明媚"
        }
    })
</script>
</html>

这里会发现,当我在输入框中修改text字符串内容时,下面展示的text也会随之改变。这就是双向绑定.

v-if,v-else-if,v-else

根据条件来选择展示哪一个标签.示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
    <div v-if="happy">我开心</div>
    <div v-else="happy">我不开心</div>
    <button @click="change">心情</button>
</div>
</body>
<script>
    let app = new Vue({
        el:'#app',
        data:{
            happy:true
        },
        methods:{
            change:function (){
                this.happy = !this.happy
            }
        }
    })
</script>
</html>

组件化开发

组件化开发是vue比较重要的一部分。组件化可以把某部分代码实现可重复使用的目的。简化开发流程
组件化开发大致分为三步,1. 构造组件,2注册组件,3使用组件。
其中,全局组件和部分组件的区别在于作用域不一样。可以类比于Java中的静态属性(方法)以及非静态属性(方法)
其中,组件也有自己的data,methods等等。但是需要注意,组件自己的data是一个方法,返回一个对象,这个对象中可以自己定义属性

全局组件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
    <link rel="stylesheet" type="text/css" href="../css/main.css">
</head>
<body>

<div id="app">
    {{message}}
    <cpn></cpn>
</div>

</body>
<script>
    // 组件创建
    let CPN = Vue.extend({
        template: `<div>
<input v-model="childm" placeholder="填写!">
        <button @click="alert">点击我</button>
        </div>`,
        data(){
            return {
                childm:"今天天气不错!"
            }
        },
        methods:{
            alert:function (){
                alert(this.childm)
            }
        }
    })

    //组件注册
    Vue.component('cpn',CPN);

    let app = new Vue({
        el: '#app',
        data: {
            message: "This is Massage"
        }
    })
</script>
</html>

构造组件就是Vue.extend()方法,需要传入一个参数,就是一个对象。核心属性为template
注册组件时,方法:Vue.component(‘cpn’,CPN);,需要传入两个参数,一个组件标签名称,一个组件对象.这种方式注册的组件,在当前所有vue对象中均可以使用
使用组件时候,在vue对象管理的标签内部直接使用注册的标签名称即可.

局部组件

直接看代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
    <link rel="stylesheet" type="text/css" href="../css/main.css">
</head>
<body>

<div id="app">
    {{message}}
    <cpn></cpn>
</div>

</body>
<script>
    // 组件创建
    let CPN = Vue.extend({
        template: `<div>
<input v-model="childm" placeholder="填写!">
        <button @click="alert">点击我</button>
        </div>`,
        data(){
            return {
                childm:"今天天气不错!"
            }
        },
        methods:{
            alert:function (){
                alert(this.childm)
            }
        }
    })

    //组件注册
    // Vue.component('cpn',CPN);

    let app = new Vue({
        el: '#app',
        data: {
            message: "This is Massage"
        },
        components:{
            cpn:CPN
        }
    })
</script>
</html>

可以看到仅仅是注册方法不一样了,局部组件注册方法就是在vue内部声明这个组件。然后使用这个组件。需要注意的是,这种方法注册的组件,只能在当前vue对象中使用,在别的vue对象中是无法识别的

组件语法糖

可以将构造组件的步骤,以及注册组件的步骤合并。直接在注册组件的时候传入构造组件的参数.示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
    <link rel="stylesheet" type="text/css" href="../css/main.css">
</head>
<body>

<div id="app">
    {{message}}
    <cpn></cpn>
</div>

</body>
<script>


    //组件注册
    // Vue.component('cpn',CPN);

    let app = new Vue({
        el: '#app',
        data: {
            message: "This is Massage"
        },
        components:{
            cpn:{
                template: `<div>
<input v-model="childm" placeholder="填写!">
        <button @click="alert">点击我</button>
        </div>`,
                data(){
                    return {
                        childm:"今天天气不错!"
                    }
                },
                methods:{
                    alert:function (){
                        alert(this.childm)
                    }
                }
            }
        }
    })
</script>
</html>
组件模板抽离

将html语句与方法语句写在一起显然不是一个优雅的方法。幸好vue提供了相应的解决方法。就是模板抽离。我可以在html区域定义模板,在vue中使用模板作为组件.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
    <link rel="stylesheet" type="text/css" href="../css/main.css">
</head>
<body>

<div id="app">
    {{message}}
    <cpn></cpn>
</div>

<template id="test01">
    <div>
        <input v-model="childm" placeholder="填写!">
        <button @click="alert">点击我</button>
    </div>
</template>

</body>
<script>


    //组件注册
    // Vue.component('cpn',CPN);

    let app = new Vue({
        el: '#app',
        data: {
            message: "This is Massage"
        },
        components:{
            cpn:{
                template: `#test01`,
                data(){
                    return {
                        childm:"今天天气不错!"
                    }
                },
                methods:{
                    alert:function (){
                        alert(this.childm)
                    }
                }
            }
        }
    })
</script>
</html>

上面就是把cpn组件的模板拆到了html中,下面直接使用id获取模板.

父子组件

父子组件,顾名思义,就是组件之间的上下级关系。在vue中这个关系表示为注册区域。
比如A组件在B组件中使用component注册,那么A组件就是B组件的子组件.

父子组件之间的通信 - 父传子

需要在子组件中定义一个props属性来接收父组件传入的数据。可以定义为集合,里面装有接收父组件数据的key值字符串集合。
子组件,在props中定义了一个father属性,来代表其父组件是哪个:

// 组件创建
    let CPN1 = Vue.extend({
        template: `<div>
        <span>我是子组件</span>
        <br>
        子组件获取到的父组件data:{{father}}
        <br>
<input v-model="childm" placeholder="填写!">
        <button @click="alert">点击我</button>
        </div>`,
        props:["father"],
        data(){
            return {
                childm:"我是子组件!"
            }
        },
        methods:{
            alert:function (){
                alert(this.childm)
            }
        }
    })

父组件,注册子组件。引用子组件时,使用v-bind给子组件添加属性,属性名称即为子组件中props中的属性名称,来将其传递给子组件:

let CPN2 = Vue.extend({
        template: `<div>
        <span>我是父组件</span>
        <br>
        <child1 v-bind:father="name"></child1>
        <br>
<input v-model="childm" placeholder="填写!">
        <button @click="alert">点击我</button>
        </div>`,

        data(){
            return {
                childm:"我是父组件!",
                name:"父组件01"
            }
        },
        methods:{
            alert:function (){
                alert(this.childm)
            }
        },
        components:{
            child1:CPN1
        }
    })

总结:父子组件之间的通信-父传子有点类似于java中面向对象的思想,从当前对象中,将属性传递给另外的对象.
其中,这个props还有很多种写法:
在这里插入图片描述

父子组件之间的通信 - 子传父

子组件传跟父组件通信,是通过事件来通信的。
主要方法如下:

this.$emit('trans-cli',message)

子组件中调用$emit,来发射一个事件。其中可以有两个参数,第一个参数就是事件名称,第二个就是事件参数。示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
    <input v-model="message">
    <ch1 @trans-cli="alert"></ch1>

</div>

<template id="ch1">
    <div>
       子组件
        <input v-model="cmessage">
        <button @click="trans(cmessage)">给父组件发送消息!!!</button>
    </div>
</template>
</body>
<script>
    var v =  new Vue({
        el:'#app',
        data:{
            message:'我是父组件,你好'
        },
        methods: {
            alert:function (m){
                alert("收到了来自子组件的事件!"+m)
            }
        },
        components:{
            ch1:{
                template:'#ch1',
                data(){
                    return{
                        cmessage:"子组件消息!"
                    }
                },
                methods:{
                    trans:function (message){
                        this.$emit('trans-cli',message)
                    }
                }
            }
        }
    })
</script>
</html>
父子组件之间的通信 - 父组件找子组件对象

在开发的时候,有时候需要再父组件中,找到所有子组件对象。有如下几种方法:

  1. 在父组件中,调用this.$children,获取当前vue对象的所有子组件集合。获得的是一个数组,可以通过遍历该数组来获取每一个子组件.但是缺点很明显,只能通过下标来获取组件。
  2. 在父组件中,通过this.$refs获取所有标有ref属性的子组件。返回一个对象(map),标签中ref的值为key,该对象为值得map。获取指定子组件的话,指定ref值即可。并且经过实测,若有多个相同ref的组件,那么后面的组件会顶替掉前面的
this.$refs.[refName] //其中,refName 就是组件上明明的ref名称
父子组件之间的通信 - 子组件找父组件对象

因为一个子组件只可能有一个父组件,所以这个还是比较简单的,直接使用$parent即可获取父组件的vue实例。

父子组件之间的通信 - 寻找根组件

直接使用$root,获取根节点的vue对象。

插槽

在模板中,有些时候,我并不需要事先定义好模板中的标签具体的内容,我是想让父组件来决定如何显示这一块,那么就可以用到模板了。直接用slot在模板内定义插槽,在使用时,在标签内放入自定义内容

<template>
<!--    这是一个插槽,可以使用该模板时,定义其内容,也可以内置一个默认样式-->
    <slot>我是默认样式</slot>
</template>

<!-- 使用插槽-->
<tmp1>
    <div >父组件样式</div>
</tmp1>
具名插槽

当然,一个模板可以拥有多个插槽。但是如果不设置每个插槽的名字(默认名字default),那么使用起来就会及其不方便。比如,我有两个插槽,A插槽和B插槽。我想在A插槽显示一个按钮,B插槽显示一段话,如下面

<template>
<!--    这是一个插槽,可以使用该模板时,定义其内容,也可以内置一个默认样式-->
    <slot>A插槽</slot>
    <slot>B插槽</slot>
</template>
<!-- 使用插槽-->
<tmp1>
    <div ><button>A插槽放按钮</button></div>
    <div >B插槽放文字</div>
</tmp1>

就会出现这种情况:在这里插入图片描述
将两个标签同时放在了A插槽和B插槽.
这时就需要给每个插槽来一个name属性。然后,在父组件中,插入插槽的时候,根据name属性选择插在哪里,如下:

    <tem1>
        <template v-slot:a>
            <div>
                <button>A插槽放按钮</button>
            </div>
        </template>
        <template v-slot:b>
            <div>B插槽放文字</div>
        </template>

    </tem1>

需要给每一个单独插入插槽的元素定义template标签,使用v-slot属性,定义插槽名称指定插入位置

插槽中使用子组件属性

在插入插槽时,本质上是在父组件内操作的。所以使用双大括号获取的数据,也都是父组件的。但是此时想要获取子组件数据,就需要在子组件内,通过v-bind来将子组件属性绑定到一个自定义标签属性中,然后在父组件获取.

<template id="tmp1">
    <!--    slot 标签内,用name,外部想要插入插槽就需要使用slot-->
    <!--    slot标签内用 v-slot:name 外部想要插入插槽就需要使用name-->

<!--   slot 标签内,用name,外部想要插入插槽,需要用v-slot:[name] 后面根name名称,来表示对应插槽.然后也可以更改插槽内容,可以用v-slot:[name]=''
来将子组件这个插槽抽出来当做一个对象,用这个对象获取该插槽通过bind属性绑定的值-->
<!--    作用域插槽:给插槽命名,然后bind绑定属性 -->
    <div>
        <!--        具名插槽-->
        <slot name="s"  :pbooks="books">
            <div v-for="book in books">{{book}}</div>
        </slot>
    </div>
</template>
    <tmp1>
        <template v-slot:s="m1">
            <div v-for="(book,index) in m1.pbooks">{{book}}!!!!{{index}}</div>
        </template>
    </tmp1>

  1. 这里建议自行百度 vue 生命周期和钩子函数,有更加详细的介绍。这里只是满足我自己使用,故不作详细阐述 ↩︎

  2. 修饰符可参考这里 ↩︎

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值