手挽手带你学VUE:二档 组件开辟以及经常使用全局api

视频教程

由于思否不支撑视频链接 视频请移步 http://www.henrongyi.top

你能学到什么

二档视频固然要比一档视频难一点,假如前面的内容还没有消化终了的话,照样发起人人继承消化前面的内容,然后再看接下来的部份。这一部份是VUE的中心,讲到组件化开辟的基础部份,多学,多练。

性命周期

Vue官网给出的性命周期图

<img src=’https://cn.vuejs.org/images/l…‘ >
这张图里包括了基础的性命周期,实际上性命周期钩子函数另有两个不在图内(activated,deactivated),这两个性命周期函数这里不给人人讲,假如人人有兴致可以自行到VUE官网看文档,工作中用到他们的时机不多,这边讲也会骚动扰攘侵犯人人的进修历程。这里我们经由过程代码来解说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>Document</title>
    <style>
        .active{
            color:red
        }
    </style>
</head>
<body>
    <div id="app">
        <button v-on:click="add">+</button>{{num}}<button @click="minus">-</button>
    </div>


    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var app = new Vue({
            el:"#app",
            data:{
               num:1
            },
            methods:{
                add(){
                    this.num++
                },
                minus(){
                     this.num--
                }
            },
            beforeCreate:function(){
                console.log('页面初始化今后立时实行');
            },
            created:function(){
                console.log('页面初始化完成今后created,这里模板还没有衬着呢!');
            },
            beforeMount:function(){
                console.log('组件挂载之前beforeMount');
            },
            mounted:function(){
                console.log('组件挂载今后mounted');
            },
            beforeUpdate:function(){
                console.log('组件更新前beforeUpdate');
            },
            updated:function(){
                console.log('组件更新后updated');
            },
        //   activated:function(){
        //      console.log('activated');
        //    },
        //    deactivated:function(){
        //        console.log('deactivated');
        //    },    你只须要知道这两个性命周期是在这个位置举行就好了,别的可以不要想太多。
            beforeDestroy:function(){
                console.log('组件烧毁之前beforeDestroy');
            },
            destroyed:function(){
                console.log('组件烧毁后destroyed')
            }
        })
    </script>
</body>
</html>

这些性命周期函数大致就演示到这里,剩下的两个没能给人人展现的请人人切记,我们最先学组件的时刻,就可以体会到这两个钩子函数的用法了。

组件建立

Vue.component
注册全局组件
Vue.component(“组件名”,{ 组件的种种属性(模板啊,data啊,要领啊,性命周期啊之类的。) }), (视频里有一句口误,应该是小驼峰。手动捂脸)

这个全局API看过今后,我们来完成一个组件的hello world

<!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>Document</title>
</head>
<body>
    <div id="app">
       <shuai-qm></shuai-qm>
    </div>


    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.component("shuai-qm",{
            data(){
                return{
                    hello:'hello world'
                }
            },
            template:'<h1>{{hello}}</h1>'
        })
        
        var app = new Vue({
            el:"#app",
            data:{
                message:'Hello Word',
                isTrue:true,
            },
        })
    </script>
</body>
</html>

一个全局组件的hello world就完成了,然则人人是不是是以为全局组件异常不扎实?随时可以一个更改摧毁我们的项目?
那没紧要,接下来是部分组建的注册要领。

Vue的components属性

我们在注册部分组建的时刻,须要把部分组建挂载到Vue组织器的components内,注重:全局api不带s,而这个属性带s。不说空话,我们先来组织一个。

<!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>Document</title>
</head>
<body>
    <div id="app">
    {{message}}
       <shuai-qm></shuai-qm>
    </div>


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

        var app = new Vue({
            el:"#app",
            data:{
                message:'Hello World',
                isTrue:true,
            },
              components:{
                   "shuaiQm":{
                       data(){
                           return{
                               hello:"hello world"
                           }
                       },
                       template:'<h1>{{hello}}</h1>'
                       }
                }
            
        })
    </script>
</body>
</html>

如许我们就得到了一个可以hello world的部分组件,然则,一堆组定都这个模样排列出来的话,会将我们的项目弄得遍体鳞伤?
所以我们抽离一下代码。变成如许

<!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>Document</title>
</head>
<body>
    <div id="app">
    {{message}}
      <shuai-qm></shuai-qm>
    </div>


    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var shuaiQm = {
            data(){
                return{
                    hello:"hello world"
                }
            },
            template:'<h1>{{hello}}</h1>'
            }


        var app = new Vue({
            el:"#app",
            data:{
                message:'Hello World',
                isTrue:true,
            },
            components:{
                   "shuaiQm":shuaiQm,
            }
        })
    </script>
</body>
</html>

是不是是用vue-cli开辟过的同砚就比较眼熟了?那末题目又来了,组件内里的html全都是写的字符串,都这么玩下去,要乱死啊,没题目,我们继承抽离。

这里引见的就是vue的template用法了,立时又是一个cli党眼熟的东西

<!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>Document</title>
</head>

<template id="shuaiQm">
    <h1>{{hello}}</h1>
</template>

<!-- 上面是html模板的用法,下面是script模板的用法,运用<script>标签时,type指定为text/x-template,意在通知浏览器这不是一段js剧本,浏览器在剖析HTML文档时会疏忽<script>标签内定义的内容。-->

<!-- 引荐 -->
<script type="x-template" id="shuaiQm2">
    <h2 style="color:blue">{{hello}}</h2>
</script>

<body>
    <div id="app">
    {{message}}
       <shuai-qm></shuai-qm>
    </div>


    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var shuaiQm = {
            data(){
                return{
                    hello:"hello world"
                }
            },
            template:"#shuaiQm2"
            }


        var app = new Vue({
            el:"#app",
            data:{
                message:'Hello World',
                isTrue:true,
            },
            components:{
                   "shuaiQm":shuaiQm,
            }
        })
    </script>
</body>
</html>

拆出来今后是不是是稀里糊涂引起了极端温馨?固然背面我们学到运用vue-cli的时刻 我们还会用到新的誊写要领 .vue 文件的要领,这里就先不给人人多说了。

组件内里套组件(父子组件)

可以由同砚会问了,组件内里还可以嵌套组件吗?我可以很负责任地通知你,完整没题目!怎样写呢?你假如会在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>Document</title>
</head>

<script type="x-template" id="father">
  <div>
    <h2 style="color:blue">{{hello}}</h2>
    <childer  />
  </div>
</script>

<script type="x-template" id="childer">
    <h2 style="color:blue">{{hello}}</h2>
</script>

<body>
    <div id="app">
    {{message}}
    <shuai-qm></shuai-qm>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var childer = {
            data(){
                return{
                    hello:"hello i'm dawangraoming"
                }
            },
            template:"#childer"
        }


        var father = {
            data(){
                return{
                    hello:"hello world"
                }
            },
            template:"#father",
            components:{
                "childer":childer
            }
            }




        var app = new Vue({
            el:"#app",
            data:{
                message:'Hello World',
                isTrue:true,
            },
            components:{
                   "shuaiQm":father,
            }
        })
    </script>
</body>
</html>

这里人人也可以看到,我们在 app内部只援用了 shuaiQm这一个组件, shuaiQm又包括他的子组件 childer,因而父子都被衬着出来了。这就是父子组件的写法。

插槽slot

这时刻又有朋侪要问了,假如我想在组件内里继承誊写html怎样办呢? slot插槽就是个很好的东西了,这里我用代码给人人演示一下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>Document</title>
</head>

<script type="x-template" id="shuaiQm2">
    <div style="color:blue">
        <h2>{{hello}}</h2>
        <solt name="solt1">我是插槽solt1</solt>
        <solt name="solt2">我是插槽solt2</solt>
        <!-- 假如插槽不运用的话,内部的默许笔墨就会展现出来 -->
    </div>
</script>

<body>
    <div id="app">
    {{message}}
       <shuai-qm>
           <span slot="solt1">hello world</span>
       </shuai-qm>
    </div>


    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var shuaiQm = {
            data(){
                return{
                    hello:"hello world"
                }
            },
            template:"#shuaiQm2"
            }


        var app = new Vue({
            el:"#app",
            data:{
                message:'Hello World',
                isTrue:true,
            },
            components:{
                   "shuaiQm":shuaiQm,
            }
        })
    </script>
</body>
</html>

插槽只要这一个作用吗?不,那你就太小视插槽了,接下来要引见一下插槽的作用域插槽用法。

作用域插槽,听不懂可跳过,背面还会细致解说

运用时刻子组件标签Child中要有 template scope=”scopeName” 标签,再经由过程scopeName.childProp就可以挪用子组件模板中的childProp绑定的数据,所以作用域插槽是一种子传父传参的体式格局,处置惩罚了一般slot在parent中没法访问child数据的去题目;
这么说太庞杂了,直接上个例子不言而喻。
假如这里听不懂可以临时跳过,只须要会用slot插槽的基础用法即可,在背面讲Element项目的时刻,我会连系实例给人人解说这个作用域插槽。

<!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>Document</title>
</head>

<script type="x-template" id="shuaiQm2">
    <div style="color:blue">
        <h2>{{hello}}</h2>
        <slot name="item" v-for="item in items" :text="item.text" :myname="item.myname" >
            slot的默许内容
        </slot>
    </div>
</script>

<body>
    <div id="app">
    {{message}}
       <shuai-qm>
          <template slot="item" scope="props">
            <li>{{props.myname}}</li>
            <li>{{props.text}}</li>
          </template>
       </shuai-qm>
    </div>


    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var shuaiQm = {
            data(){
                return{
                    hello:"hello world",
                    items:[{
                      text:"我在子组件内,经由过程插槽展如今父组件",
                      myname:"Qm",
                    },{
                      text:"我在子组件内,经由过程插槽展如今父组件",
                      myname:"奇淼",
                    }]
                }
            },
            template:"#shuaiQm2"
            }


        var app = new Vue({
            el:"#app",
            data:{
                message:'Hello World',
                isTrue:true,
            },
            components:{
                   "shuaiQm":shuaiQm,
            }
        })
    </script>
</body>
</html>

prop 通报参数给组件(父传值给子)

讲到这里,已到了VUE一个须要明白的处所了,父子传值,我们先解说一下,如何将值通报给子组件,这个团体来讲照样比较简朴。援用我们的组件的标签上写上属性,而且把参数传入,如许我们在组件内部运用props就可以取得传过来的值了,我们照样以上面的代码为例。

<!DOCTYPE html>
<html lang="zh-cn">
<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>Document</title>
</head>

<script type="x-template" id="father">
  <div>
    <h2 style="color:blue">{{hello}}</h2>
    {{apptoshuaiqm}}
    <childer :shuai-qmtochilder="shuaiQmGiveMe" />
  </div>
</script>

<script type="x-template" id="childer">
    <div>
        <h2 style="color:blue">{{hello}}</h2>
        {{shuaiQmtochilder}}
    </div>
</script>

<body>
    <div id="app">
    <shuai-qm apptoshuaiqm="我是app传过来的值" ></shuai-qm>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var childer = {
          props:['shuaiQmtochilder'],
            data(){
                return{
                    hello:"hello i'm dawangraoming",
                }
            },
            template:"#childer"
        }


        var father = {
            props:["apptoshuaiqm"],// 这里人人肯定要注重,请完整运用小写传参
            data(){
                return{
                    hello:"hello world",
                    shuaiQmGiveMe:"我是从shuaiQm传过来的值"
                }
            },
            template:"#father",
            components:{
                "childer":childer
            }
            }




        var app = new Vue({
            el:"#app",
            data:{
                message:'Hello World',
                isTrue:true,
            },
            components:{
                   "shuaiQm":father,
            }
        })
    </script>
</body>
</html>

这一段代码注重,再给html上面增加属性的时刻,我们是不可以直接增加驼峰定名的,由于html不会辨别大小写,所以我们发起属性的定名体式格局是完整小写或许横线定名的体式格局。假如我们运用横线定名来通报参数的话,在吸收的时刻,横线背面的首字母大写,变成小驼峰来接收,不然运用的时刻它会被衬着成NaN,这是为何呢?别忘了我们一档讲过的,在插值表达式内,是支撑简朴盘算的,- 会被看成减号处置惩罚,这里我会在视频中给人人细致解说。

子组件传值给父组件

学到这里,假如人人已有些渺茫,如今请先停下,喘口吻,这里难度已逐步加大。我也会放慢解说的速率。
假如我们想要获取到子组件内部的值,该怎样办呢?有什么方法可以让我们回去到内部的值呢?在这里,先给人人插播一个JS写法,我以为这有助于明白子传父值。

function thief (gold) {
    console.log(gold)
}

function richMan (){
    var money = 1000086
    thief(money)
}

richMan()

我们想要在vue中做到子传参给父,那我们的父组件就要像子组件伸出小偷之手。我在代码中为人人誊写一下

<!DOCTYPE html>
<html lang="zh-cn">
<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>Document</title>
</head>

<script type="x-template" id="shuaiQm">
  <div>
   
  </div>
</script>

<body>
    <div id="app">
      {{qmGold}}
    <shuai-qm :father="thief"></shuai-qm>
    </div>

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

        var shuaiQm = {
            props:["father"],
            data(){
                return{
                    money:"10000",
                }
            },
            template:"#shuaiQm",
            created() {
              this.father(this.money)
            },
            }



        var app = new Vue({
            el:"#app",
            data:{
              qmGold:0,
            },
            components:{
                   "shuaiQm":shuaiQm,
            },
            methods:{
              thief(gold){
                this.qmGold = gold
              }
            }
        })
    </script>
</body>
</html>

如许 你明白子传参给父了吗?

其他会用到的全局API

Vue.directivet
Vue.directive 我们用来编写全局指令,它也有本身的性命周期

// 注册
Vue.directive('my-directive', {
  bind: function () {},
  inserted: function () {},
  update: function () {},
  componentUpdated: function () {},
  unbind: function () {}
})

/*
bind:只挪用一次,指令第一次绑定到元素时挪用。在这里可以举行一次性的初始化设置。

inserted:被绑定元素插进去父节点时挪用 (仅保证父节点存在,但不肯定已被插进去文档中)。

update:地点组件的 VNode 更新时挪用,然则可以发生在其子 VNode 更新之前。指令的值可以发生了转变,也可以没有。然则你可以经由过程比较更新前后的值来疏忽不必要的模板更新 (细致的钩子函数参数见下)。

componentUpdated:指令地点组件的 VNode 及其子 VNode 悉数更新后挪用。

unbind:只挪用一次,指令与元素解绑时挪用。

接下来我们来看一下钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。

在这些钩子函数内部,都可以接收三个参数,我们来看看文档中的写法。
el:指令所绑定的元素,可以用来直接操纵 DOM 。

binding:一个对象,包括以下属性:
    name:指令名,不包括 v- 前缀。
    value:指令的绑定值,比方:v-my-directive="1 + 1" 中,绑定值为 2。
    oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。不管值是不是转变都可用。
    expression:字符串情势的指令表达式。比方 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
    arg:传给指令的参数,可选。比方 v-my-directive:foo 中,参数为 "foo"。
    modifiers:一个包括修饰符的对象。比方:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode:Vue 编译天生的假造节点。
oldVnode:上一个假造节点,仅在 update 和 componentUpdated 钩子中可用。

这里我会在视频中连系官方样例解说
*/

上面我们排列了这么多它的特征,不过真正开辟中,我们最经常使用的只要 bind 和 update 这两个时代
我们可以简写为

    Vue.directive('color', function (el, binding) {
        el.style.backgroundColor = binding.value
    })

下面我们来举个例子

<!DOCTYPE html>
<html lang="zh-cn">
<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>Document</title>
</head>

<script type="x-template" id="shuaiQm">
  <div>
   
  </div>
</script>

<body>
    <div id="app">
      <div v-color="color">
          我来测试测试directive
      </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.directive("color",function(el,binding){
            el.style.color = binding.value
        })

        var app = new Vue({
            el:"#app",
            data:{
                color:"red"
            }
        })
    </script>
</body>
</html>

好了我们可以看到加上v-color的这个div内部的笔墨变红了

Vue.set

Vue.set官网给出的用法是 Vue.set( target, key, value ) 向相应式对象中增加一个属性,并确保这个新属性同样是相应式的,且触发视图更新。它必需用于向相应式对象上增加新属性,由于 Vue 没法探测一般的新增属性
这么听起来是有些笼统的,我给人人用代码展现一下它在我们一样平常开辟中经常出现的场景。

<!DOCTYPE html>
<html lang="zh-cn">
<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>Document</title>
</head>

<body>
    <div id="app">
      <ul>
        <li v-for="(item,ket) in list" :key="key">{{item.hello}}</li>
      </ul>
      <button @click="addList">+</button>
    </div>

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

        var app = new Vue({
            el:"#app",
            data:{
                list:[{hello:"hello world"},{hello:"hello two"}]
            },
            methods:{
                addList(){
                   this.list[0] = {hello:"ttt"}
                    console.log(this.list)
                }
            }
        })
    </script>
</body>
</html>

在上述代码中,我们经由过程this.list[0]直接修改了数组中的第0项目对象,那末视图是没有更新的,然则数据确切变动了,这是为何呢?由于Vue是经由过程Object.defineProperty()来举行数据的监听,它的机制致使了它没法直接检测出数组中这类状况的变化。这时刻我们就须要运用Vue.set了

<!DOCTYPE html>
<html lang="zh-cn">
<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>Document</title>
</head>

<body>
    <div id="app">
      <ul>
        <li v-for="(item,ket) in list" :key="key">{{item.hello}}</li>
      </ul>
      <button @click="addList">+</button>
    </div>

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

        var app = new Vue({
            el:"#app",
            data:{
                list:[{hello:"hello world"},{hello:"hello two"}]
            },
            methods:{
                addList(){
                   this.list[0] = {hello:"ttt"}
                    console.log(this.list)
                }
            }
        })
    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-cn">
<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>Document</title>
</head>

<body>
    <div id="app">
      <ul>
        <li v-for="(item,ket) in list" :key="key">{{item.hello}}</li>
      </ul>
      <button @click="addList">+</button>
    </div>

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

        var app = new Vue({
            el:"#app",
            data:{
                list:[{hello:"hello world"},{hello:"hello two"}]
            },
            methods:{
                addList(){
                //    this.list[0] = {hello:"ttt"}
                    Vue.set(this.list,0, {hello:"我强迫转变了!"})
                    // this.$set(this.list,0,{hello:"我强迫转变了!"})  在methods 中可以写成 this.$set 
                    console.log(this.list)
                }
            }
        })
    </script>
</body>
</html>

看 是不是是强迫将它转变了呢? 有了Vue.set 数据就都不再得瑟了

    原文作者:蒋吉兆
    原文地址: https://segmentfault.com/a/1190000017750018
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞