Hand in Hand to Learn VUE: Second-tier Component Development and Common Global api

Keywords: Javascript Vue IE npm Attribute

Video tutorial

Please move because you don't support video links https://www.henrongyi.top

What can you learn?

Of course, the second video is a little more difficult than the first one. If the previous content has not been digested, we suggest that you continue to digest the previous content, and then look at the next part. This part is the core of VUE. It talks about the basic part of component development, learning more and practicing more.

life cycle

Life Cycle Map of Vue Official Website

<img src='https://cn.vuejs.org/images/l...' >
This picture contains the basic life cycle. In fact, there are two other life cycle hook functions that are not included in the graph (activated, deactivated). These two life cycle functions are not mentioned here. If you are interested, you can go to the VUE official website to see the documents on your own. There are few opportunities to use them in your work, which will also disrupt your learning process. Here we explain Vue's life cycle through code

<!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('Execute immediately after page initialization');
            },
            created:function(){
                console.log('After page initialization is complete created,Here the template has not been rendered yet!');
            },
            beforeMount:function(){
                console.log('Before component mounting beforeMount');
            },
            mounted:function(){
                console.log('After component mounts mounted');
            },
            beforeUpdate:function(){
                console.log('Before component updates beforeUpdate');
            },
            updated:function(){
                console.log('Updated components updated');
            },
        //   activated:function(){
        //      console.log('activated');
        //    },
        //    deactivated:function(){
        //        console.log('deactivated');
        //    } You just need to know that these two life cycles are going on in this place. Don't think too much about anything else.
            beforeDestroy:function(){
                console.log('Before Component Destruction beforeDestroy');
            },
            destroyed:function(){
                console.log('Component destroyed destroyed')
            }
        })
    </script>
</body>
</html>

These life cycle functions are generally demonstrated here, the remaining two can not be shown to you, please bear in mind that when we start to learn components, we can understand the use of these two hook functions.

Component creation

Vue.component
Register global components
Vue.component("component name", {various attributes of components (template, data, method, life cycle, etc.) }) There is a slip of the tongue in the video. It should be a small hump. Cover your face by hand.

After looking at the global API, we implemented a component called 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>

The hello world of a global component is complete, but do you think the global component is very unreliable? Any time a change could destroy our project?
That's OK. Next is the registration method of partial organization.

components property of Vue

When registering a local build, we need to mount the local build into the components of the Vue constructor. Note that the global api does not have s, but this property has s. Let's not talk nonsense. Let's construct one first.

<!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>

So we've got a local component that can be hello world, but if we list a bunch of builds like this, we're going to make our project look like nothing else.
So let's take the code away. Become so

<!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>

Are the students who have developed with vue-cli familiar? Then the problem arises again. The html in the component is all written strings. They all play like this. They want to die in disorder. No problem. We continue to pull them out.

Here's the template usage of vue, which will be familiar to 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>

<!-- Above is html The usage of templates is as follows script Use of templates<script>When tagging, type Designated as text/x-templateļ¼ŒThe intention is to tell the browser that this is not a paragraph js The script, the browser is parsing HTML Documentation is ignored<script>The content defined in the label.-->

<!-- Recommend -->
<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>

Did it inexplicably cause extreme comfort after it was taken apart? Of course, when we learn to use vue-cli later, we will also use the new method of writing. Vue files, so let's not talk about it here.

Nested components within components (parent and child components)

Maybe the students asked, can the components be nested? I can tell you very responsibly, no problem at all! How to write it? If you refer to components in the constructor of a Vue instance, you refer to components inside other components, which is actually a way of writing. Here I use our third template to write for you.

<!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>

As you can see, we only refer to shuaiQm as a component in app, and shuaiQm contains its child component, so both father and son are rendered. This is how the parent-child component is written.

Slot slot

At this time, another friend will ask, what if I want to continue writing html in the component? Slot slot slot is a very good thing, here I use the code to show you the use of slot 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">I am a slot. solt1</solt>
        <solt name="solt2">I am a slot. solt2</solt>
        <!-- If the slot is not used, the default text inside will be displayed. -->
    </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>

Is this the only function of the slot? No, then you look down upon the slot too much. Next, I will introduce the usage of the scope slot of the slot.

Scope slot, can not understand skip, will be explained in detail later

When using Child, the child component label should have template scope="scopeName" label, and then the child Prop bound data in the child component template can be invoked by scopeName.childProp. So the scope slot is a way of child-parent parameter transmission, which solves the problem that ordinary slot can not access child data in parent.
That's too complicated. It's obvious from the last example.
If you don't understand it here, you can skip it temporarily. Just use the basic usage of slot slot slot. When I talk about Element project later, I will explain this scope slot with examples.

<!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 Default content of
        </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:"I show it in the parent component through the slot in the child component",
                      myname:"Qm",
                    },{
                      text:"I show it in the parent component through the slot in the child component",
                      myname:"Qi Miao",
                    }]
                }
            },
            template:"#shuaiQm2"
            }


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

prop passes parameters to components (parent to child)

Speaking of this, we have come to a point where we need to understand VUE. Father and son pass values. Let's first explain how to pass values to child components, which is relatively simple as a whole. Write the attributes on the tags that refer to our components and pass in the parameters so that we can use props inside the components to get the passed values. Let's take the above code as an example.

<!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="I am app The value passed in" ></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"],// Here we must pay attention to, please use all lowercase reference
            data(){
                return{
                    hello:"hello world",
                    shuaiQmGiveMe:"I am from shuaiQm The value passed in"
                }
            },
            template:"#father",
            components:{
                "childer":childer
            }
            }




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

Note that when adding attributes to html, we can't add hump naming directly, because HTML can't distinguish between case and case, so we suggest that the naming of attributes should be completely lowercase or horizontal. If we use horizon names to pass parameters, when receiving, the initials behind the horizon capitalize and become small humps to accept, otherwise it will be rendered NaN when using, why? Don't forget what we mentioned in our first paper. In interpolation expressions, it supports simple calculation. - It will be treated as minus sign. Here I will explain it in detail in the video.

Subcomponents pass values to parent components

Learn here, if you already have some confusion, please stop now, take a breath, here the difficulty has slowly increased. I will also slow down my presentation.
What if we want to get the values inside the subcomponents? What can we do to get back to our internal values? Here, let's first insert a JS script for you, which I think will help you understand the value of the descendant father.

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

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

richMan()

If we want to pass the child to the parent in vue, our parent component will be like the child component reaching out to the thieves. I'll write it for you in the code.

<!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>

So do you understand that the Son passed on to the Father?

The rest of the global API s will be used

Vue.directivet
Vue.directive, which we use to write global instructions, also has its own life cycle

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

/*
bind: Called only once, when the instruction is first bound to the element. One-time initialization settings are available here.

inserted: Called when the bound element is inserted into the parent node (only the parent node is guaranteed to exist, but not necessarily inserted into the document).

update: The VNode of the component in question is called when it is updated, but may occur before its sub-VNode is updated. The value of the instruction may or may not change. But you can ignore unnecessary template updates by comparing the values before and after updates (see the hook function parameters below).

componentUpdated: The VNode of the component in which the instruction resides and its sub-VNode are all updated and invoked.

unbind: Called only once, when the instruction is unbound to the element.

Next, let's look at the parameters of the hook function (el, binding, vnode, and oldVnode).

Within these hook functions, you can accept three parameters. Let's look at the writing in the document.
el: The elements bound by instructions can be used to manipulate DOM directly.

binding: An object that contains the following properties:
    name: Instruction name, excluding v-prefix.
    value: The binding value of the instruction, for example, in v-my-directive="1 + 1", is 2.
    oldValue: The previous value of the instruction binding is available only in the update and component Update hooks. Whether the value changes or not is available.
    expression: An instruction expression in the form of a string. For example, in v-my-directive="1 + 1", the expression is "1 + 1".
    arg: The parameters passed to the instruction are optional. For example, in v-my-directive:foo, the parameter is "foo".
    modifiers: An object containing modifiers. For example, in v-my-directive.foo.bar, the modifier object is {foo: true, bar: true}.
vnode: Vue Compile the generated virtual nodes.
oldVnode: The last virtual node is available only in the update and component Update hooks.

Here I'll show you some official examples in the video.
*/

So many of its features are listed above, but in real development, only bind and update are the two most commonly used periods.
We can abbreviate it as

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

Let's take an example.

<!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">
          //Let me test 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>

Well, we can see that the text inside the div with v-color has turned red.

Vue.set

The Vue.set official website gives the use of Vue.set (target, key, value) to add an attribute to the responding object and ensure that the new attribute is also responsive and triggers view updates. It must be used to add new attributes to responding objects because Vue cannot detect common new attributes
That sounds a bit general. I'll show you some scenarios in our daily development with code.

<!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>

In the above code, we modify the 0 item object in the array directly through this.list[0], so the view is not updated, but the data does change. Why? Because Vue monitors data through Object.defineProperty(), its mechanism prevents it from directly detecting changes in this situation in arrays. At this point, we need to use 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:"I forced a change!"})
                    // this.$set(this.list,0,{hello:"I forced a change! "}" can be written as this.$set in methods. 
                    console.log(this.list)
                }
            }
        })
    </script>
</body>
</html>

See if it's mandatory to change it? With Vue.set data, it's not going to work anymore.

Posted by greatstar00 on Tue, 07 May 2019 17:35:39 -0700