Vue2 第一天學習


個人小總結:1年多沒有寫博客,感覺很多知識點生疏了,雖然工作上能解決問題,但是當別人問到某個知識點的時候,還是迷迷糊糊的,所以堅持寫博客是硬道理的,因為大腦不可能把所有的知識點記住,有可能某一天忘了,但是我們工作上還是會使用,只是理論忘了,所以寫博客的好處是可以把之前的東西重新看一遍后會在大腦里面重新浮現起來,特別在面試的時候,別人問你的知識點的時候答不上來那種尷尬,但是平時經常使用到,只是說不出所以來的,因此寫博客是最好的思路。

閱讀目錄

1.vue組件注冊步驟

Vue.js 的組件有三個步驟: 創建組件構造器(Vue.extend()方法 ),注冊組件(Vue.component())和實例化組件。
如下demo:

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
    </head>
    <div id="container">
      <component1></component1>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    // 1. 創建一個組件構造器
    var component1 = Vue.extend({
      template: '<div>hello world</div>'
    });
    // 2. 注冊組件,並指定組件的標簽為<component1>
    Vue.component('component1', component1);

    // 3. 實例化組件
    new Vue({
      el: '#container'
    });
  </script>
</html>

瀏覽器編譯后html結構會變為 

<div id="container">
  <div>hello world</div>
</div>

頁面運行顯示為
hello world

2.理解組件的創建和注冊。

2-1 Vue.extend() 是Vue構造器的擴展,調用Vue.extend()創建的是一個組件構造器,該構造器有一個選項對象,選項對象的template屬性用於定義組件要渲染的html。
2-2 Vue.component() 是注冊組件,需要2個參數,第一個參數是自定義組件的標簽,第二個參數是組件的構造器。
2-3 組件需要掛載到某個Vue的實例下,否則不生效。
如下實例:

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
    </head>
    <div id="container1">
      <component1></component1>
    </div>
    <div id="container2">
      <component1></component1>
    </div>

    <div id="container3">
      <component1></component1>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    // 1. 創建一個組件構造器
    var component1 = Vue.extend({
      template: '<div>hello world</div>'
    });
    // 2. 注冊組件,並指定組件的標簽為<component1>
    Vue.component('component1', component1);

    // 3. 實例化組件 container1
    new Vue({
      el: '#container1'
    });
    // 3. 實例化組件 container2
    new Vue({
      el: '#container2'
    });
    // 不實例化 container3 因此第三個自定義標簽是不會生效的
  </script>
</html>

最終代碼被渲染成為如下:

<div id="container1"><div>hello world</div></div>
<div id="container2"><div>hello world</div></div>

3.理解Vue全局注冊和局部注冊

調用Vue.component()注冊組件時,組件的注冊是全局的,如果想要使用組件的局部注冊的話,可以用選項對象的components屬性實現局部注冊。
如下代碼:中間就把第二步注冊組件哪項移到實例化組件里面來了;如下代碼:

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
    </head>
    <div id="container1">
      <component1></component1>
    </div>
    <!-- 不能使用component1組件,因為它是container1里面局部注冊的 -->
    <div id="container2">
      <component1></component1>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    // 1. 創建一個組件構造器
    var component1 = Vue.extend({
      template: '<div>hello world</div>'
    });
    
    // 3. 實例化組件 container1
    new Vue({
      el: '#container1',
      components: {
        'component1': component1
      }
    });
    // 實例化container2 是不生效的
    new Vue({
      el: '#container2'
    })
  </script>
</html>
實例化container2 是不生效的,並且在瀏覽器控制台會報如下錯誤:

4.理解父組件和子組件。

在一個組件中包含另一個組件,那么另一個組件就是該組件的子組件。
如下代碼:

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
    </head>
    <div id="container1">
      <parent-component></parent-component>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    // 1. 創建一個組件構造器
    var Child = Vue.extend({
      template: '<div>hello world</div>'
    });
    
    var Parent = Vue.extend({
      // 在組件內部使用<child-component>組件
      template: '<div>hello world <child-component></child-component></div>',
      components: {
        // 局部注冊Child組件
        'child-component': Child
      }
    });
    // 全局注冊Parent組件
    Vue.component('parent-component', Parent);
    
    // 實例化組件
    new Vue({
      el: '#container1'
    })
  </script>
</html>

簡單理解代碼如下:
1. var Child = Vue.extend(...) 定義一個Child組件構造器。
2. var Parent = Vue.extend(...) 定義一個Parent組件構造器。
3. components: {'child-component': Child}, 將Child組件注冊到Parent組件,並將Child組件的標簽設置為 child-component;
4. template: 渲染html模板,找到template選項,然后使用 child-component組件。
5. 注冊Parent組件 Vue.component('parent-component', Parent);
6. 最后實例化組件,需要到html元素為id='container1'里面去。
Child組件是在Parent組件中注冊的,只能在Parent組件中注冊的。如下幾種情況都不行的。

4-1 以子標簽的形式在父組件中使用;如下代碼:

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
    </head>
    <div id="container1">
      <parent-component>
        <child-component></child-component>
      </parent-component>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    // 1. 創建一個組件構造器
    var Child = Vue.extend({
      template: '<div>hello world</div>'
    });
    
    var Parent = Vue.extend({
      // 在組件內部使用<child-component>組件
      template: '<div>hello world</div>',
      components: {
        // 局部注冊Child組件
        'child-component': Child
      }
    });
    // 全局注冊Parent組件
    Vue.component('parent-component', Parent);

    // 實例化組件
    new Vue({
      el: '#container1'
    })
  </script>
</html>

上面調用子組件的方式是無效的,因為在js里面當父組件要需要的html模板template的內容的時候已經決定了需要渲染什么,所以當parent-component運行的時候,在父組件使用自定義的子標簽。
運行時會當做html的普通標簽來渲染,但是它又不是普通的html標簽,因此會被忽略掉。

4-2. 在父組件標簽外使用子組件。

<div id="container1">
  <parent-component></parent-component>
  <child-component></child-component>
</div>

js代碼還是上面的一樣,運行完成后,在瀏覽器下會報錯如下:

5.理解組件的語法糖。

我們可以使用更簡單的方式來注冊組件。
5-1 使用Vue.component()直接創建和注冊組件。如下代碼:

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
    </head>
    <div id="container1">
      <component1></component1>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    // 全局注冊
    Vue.component('component1', {
      template: '<div>hello world222</div>'
    });
    // 實例化
    var vm1 = new Vue({
      el: '#container1'
    });
  </script>
</html>

Vue.component()的第一個參數是標簽名稱,第二個參數是一個選項對象,使用選項對象的template屬性定義,使用該方式,在Vue源碼中會調用Vue.extend()方法。
注意: 在template元素中需要使用一個標簽容器包圍,比如我們可以把div元素去掉的話,只放內容的話,會報錯如下:

5-2 在選項對象的components屬性中實現局部注冊

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
    </head>
    <div id="container1">
      <component1></component1>
    </div>

    <div id="container2">
      <component2></component2>
      <component3></component3>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    // 全局注冊,my-component1是標簽名稱
    Vue.component('component1',{
      template: '<div>This is the first component!</div>'
    })
    var vm1 = new Vue({
      el: '#container1'
    })
    
    // 實例化 局部注冊
    var vm1 = new Vue({
      el: '#container2',
      components: {
        // 局部注冊, component2 是標簽名稱
        'component2': {
          template: '<div>component2</div>'
        },
        // 局部注冊,component3 是標簽名稱
        'component3': {
          template: '<div>component3</div>'
        }
      }
    });
  </script>
</html>

6.學會使用 script或 template 標簽。

雖然語法糖簡化了組件注冊,但是在template選項中拼接了html元素,這導致View和C層的高耦合性。幸運的是Vue.js 提供了2種方式將javascript中的html模板分離出來。
6-1 使用script標簽, 如下代碼:

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
    </head>
    <div id="container1">
      <component1></component1>
    </div>
    <script type='text/x-template' id="myComponent">
      <div>hello world!!!!!</div>
    </script>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#container1',
      components: {
        'component1': {
          template: '#myComponent'
        }
      }
    })
  </script>
</html>

注意: 使用<script>標簽時,type指定為 text/x-template,是告訴瀏覽器這不是一段js腳本,瀏覽器在解析html文檔時會忽略script標簽內定義的內容。
6-2 使用<template>標簽。不需要指定type屬性。
如下代碼:

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
    </head>
    <div id="container1">
      <component1></component1>
    </div>
    <template id="myComponent">
      <div>hello world2222!!!!!</div>
    </template>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#container1',
      components: {
        'component1': {
          template: '#myComponent'
        }
      }
    })
  </script>
</html>

7.理解使用props。

父組件的數據如何傳給子組件呢?可以使用props把數據傳給子組件。
代碼如下:

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
    </head>
    <div id="container1">
      <component1 v-bind:my-name="name" v-bind:my-age="age"></component1>
    </div>
    <template id="myComponent">
      <table>
        <tr>
          <th colspan="2">
            子組件數據
          </th>
        </tr>
        <tr>
          <td>myName</td>
          <td>{{ myName }}</td>
        </tr>
        <tr>
          <td>myAge</td>
          <td>{{ myAge }}</td>
        </tr>
      </table>
    </template>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#container1',
      data: {
        name: 'longen',
        age: 30
      },
      components: {
        'component1': {
          template: '#myComponent',
          props: ['myName', 'myAge']
        }
      }
    })
  </script>
</html>

注意: 在子組件中定義prop時,使用了camelCase命名法。由於HTML特性不區分大小寫,camelCase的prop用於特性時,會轉為短橫線隔開的,比如上面的代碼:
在props中定義的myName,在用作特性時需要轉換為 my-name

理解prop的單向綁定
既然父組件使用props把數據傳給了子組件,那么如果子組件修改了數據,對父組件是否有影響呢?
看下面的代碼如下:

<!DOCTYPE html>
<html>
  <body>
    <head>
      <title>演示Vue</title>
      <style>
        * {
          margin: 0;
          padding: 0;
          box-sizing: border-box
        }
        html {
          font-size: 12px;
          font-family: Ubuntu, simHei, sans-serif;
          font-weight: 400
        }
        body {
          font-size: 1rem
        }

        table,
        td,
        th {
          border-collapse: collapse;
          border-spacing: 0
        }

        table {
          width: 100%;
          margin: 20px;
        }

        td,
        th {
          border: 1px solid #bcbcbc;
          padding: 5px 10px
        }

        th {
          background: #42b983;
          font-size: 1.2rem;
          font-weight: 400;
          color: #fff;
          cursor: pointer
        }

        tr:nth-of-type(odd) {
          background: #fff
        }

        tr:nth-of-type(even) {
          background: #eee
        }

        fieldset {
          border: 1px solid #BCBCBC;
          padding: 15px;
        }

        input {
          outline: none
        }

        input[type=text] {
          border: 1px solid #ccc;
          padding: .5rem .3rem;
        }

        input[type=text]:focus {
          border-color: #42b983;
        }

        button {
          outline: none;
          padding: 5px 8px;
          color: #fff;
          border: 1px solid #BCBCBC;
          border-radius: 3px;
          background-color: #009A61;
          cursor: pointer;
        }
        button:hover{
          opacity: 0.8;
        }

        #container1 {
          margin: 0 auto;
          max-width: 480px;
        }
      </style>
    </head>
    <div id="container1">
      <table>
        <tr>
          <th colspan="3">
            父組件數據
          </th>
        </tr>
        <tr>
          <td>name</td>
          <td>{{ name }}</td>
          <td><input type='text' v-model = "name" /></td>
        </tr>
        <tr>
          <td>age</td>
          <td>{{ age }}</td>
          <td><input type="text" v-model="age" /></td>
        </tr>
      </table>
      <component1 v-bind:my-name="name" v-bind:my-age="age"></component1>
    </div>
    <template id="myComponent">
      <table>
        <tr>
          <th colspan="3">
            子組件數據
          </th>
        </tr>
        <tr>
          <td>myName</td>
          <td>{{ myName }}</td>
          <td><input type="text" v-model="myName" /></td>
        </tr>
        <tr>
          <td>myAge</td>
          <td>{{ myAge }}</td>
          <td><input type="text" v-model="myAge" /></td>
        </tr>
      </table>
    </template>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#container1',
      data: {
        name: 'longen',
        age: 30
      },
      components: {
        'component1': {
          template: '#myComponent',
          props: ['myName', 'myAge']
        }
      }
    })
  </script>
</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM