03、手把手教Vue--組件

PS:轉(zhuǎn)載請注明出處
作者: TigerChain
地址: http://www.itdecent.cn/p/8de7f3ba234a
本文出自 TigerChain 簡書 手把手教 Vue 系列

本節(jié)大綱

教程簡介

  • 1、閱讀對象
    本篇教程適合新手閱讀,老手直接略過
  • 2、教程難度
    初級,本人水平有限,文章內(nèi)容難免會出現(xiàn)問題,如果有問題歡迎指出,謝謝
  • 3、Demo 地址:https://github.com/tigerchain/vue-lesson 請看 02、vue組件 組件這一節(jié)

正文

一、什么是組件

Vue 玩的就是組件,如果看過我 React 文章的朋友對組件肯定不會陌生。其實我們的應(yīng)用界面就是由一個個組件構(gòu)成的。

舉個栗子,我們就以手淘首頁部分界面為例子來說

淘寶組件

從圖中我們可以直觀的看到,這些框出來的就可以開發(fā)成一個個組件,然后把這些組件合并在一起就完成首頁了「淘寶不一定是這樣的做的,這里只是為了讓大家直觀的感受一下什么是組件」

二、Vue 中組件的形式

在 Vue 中有四種組件形式,分別是全局組件、局部組件、嵌套組件和單個組件,下面我們一一來看

1、全局組件

1、全局組件含義和使用方法

全局組件,顧名思義,就是本頁「所有 vue 實例中」都可以使用的組件

注冊全局組件方法如下

Vue.component('組件名稱',{
  模版和方法等
})

我們可以使用 Vue.extend() 函數(shù)「也可以不用,直接使用 Vue.component()」來創(chuàng)建一個 Vue 的構(gòu)造器「注意它不是 Vue 實例」

2、直接擼碼感受一下全局組件「引入 vue.js 這里就不說了,直接上核心代碼」

<body>
  <h2>vue-component</h2>
  <hr>
  <div id="container">
    <h3>愛吃什么水果? app 實例</h3>
      <ol>
        <todolist
        ></todolist>
      </ol>
  </div>

  <div id="container2">
    <h3>愛吃什么水果? app2 實例</h3>
      <ol>
        <todolist
        ></todolist>
      </ol>
  </div>

  <div>
    <h3>愛吃什么水果?</h3>
    組件沒有在任何實例中,所以不顯示 <font color="red">「組件一定要掛載到某個 Vue 實例中,否則不會生效」</font>
      <ol>
        <todolist
        ></todolist>
      </ol>
  </div>

  <script type="text/javascript">
    // 定義一個組件構(gòu)造器,不是實例
    var todolist = Vue.extend({
      template:'<div><li v-for="(item,index) in datas" @click="showName(index)">{{item.text}}</li></div>',
      data() {
        return {
          datas:[
           { id: 0, text: '蘋果' },
           { id: 1, text: '香蕉' },
           { id: 2, text: '只要是水果我都愛吃' }
         ]
        }
      },
      // 組件的方法
      methods:{
        showName(index){
          alert(this.datas[index].text)
        }
      }
    })

    // 全局組件注冊
    Vue.component('todolist',todolist)
    // 定義一個 Vue 實例
    var app = new Vue({
      el:"#container",
      // data:{}
    })
    // 定義另一個 Vue 實例
    var app2 = new Vue({
      el:'#container2'
    })
  </script>
</body>

從上面的代碼中我們可以看出來,我們使用 Vue.extend() 函數(shù)創(chuàng)建了一個 Vue 構(gòu)造器,并且使用全局注冊組件方式注冊了組件,還聲明了三個 div ,兩個 Vue 實例,我們來看看運行結(jié)果吧

Vue 全局組件

從結(jié)果上我們可以看出:

  • 1、 前兩個 Div 都把 todolist 組件渲染出來了,這就說明了 todolist 是一個全局組件,在所有的 Vue 實例中都可以使用,但是在第三個 div 中卻沒有渲染出來,因為組件必須掛載到 Vue 實例中「很明顯組件沒有掛載到第三個 div」中。
  • 2、組件可以看成一個 Vue 實例,里面可以寫 methods ,可以寫 template 模版,并且可以定義數(shù)據(jù)「但是這里 data 一定要寫成函數(shù),并且在 return 中寫數(shù)據(jù)」,當然以后 props 等都可以寫

2、局部組件

1、局部組件和使用方法

我們使用 Vue 對象的 components 屬性來實現(xiàn)局部組件注冊,顧名思義局部組件就是只能在本對象中使用的組件,模版如下:

new Vue({
  el: '#myapp',
  ...
  // 把組件注冊到本 Vue 實例下
  components: {'組件別名': 組件名}
  
})

2、代碼中體驗局部組件

  • 1、我們接著上面的代碼直接修改,修改的地方很簡單,如下所示:
全局組件改造成局部組件
  • 2、運行查看結(jié)果:
Vue 局部組件

可以看到,只有 app 實例下正確的加載了 todolist 組件,別的沒有加載「這就是局部組件」

  • 3、注意

我們?nèi)绻?app2 中使用局組件 todolist 是不會顯示的,我們的 demo 強行使用,是為了演示效果,其實瀏覽器已經(jīng)報錯了,如下:

其它 vue 實例使用局部組件報錯

大概意思就是找不到 todolist 組件,你是否正確注冊的意思

3、嵌套組件「組合組件」

1、嵌套組件「組合組件」的含義和使用方法

我們可以在一個組件中嵌套另一個組件,也就是在組件中定義 components 并且傳入子組件即可,一般使用方法如下:

// 定義一個組件
var customcomponent = Vue.extend({
    template: '<div>。。。。</div>',
    data():{},
    ....
})

var parentcomponent = Vue.extend({
    // 模版中就可以使用子組件了
    template: '<div>你類組件的一些模版 <custom-component></custom-component></div>',
    data():{},
    ....
    // 把子組件注冊到父類組件中
    components: {
        'custom-component':custom component
    }
})

基本使用方法就是如此,當然我們可以加入 methods 等屬性和方法

2、擼碼看效果

我們在上面的代碼的基礎(chǔ)上修改如下三個地方:

嵌套組件

分為三個步驟:

  • 1、定義組件
  • 2、注冊組件
  • 3、使用組件

運行查看結(jié)果:

嵌套組件顯示結(jié)果

我們可以看到,子組件在 todolist 組件中顯示出來了,這樣嵌套組件就完成了

4、單個組件

我們通上以上方式就可以實現(xiàn)組件化 Vue ,但是如果在大型項目中這樣使用會讓人感覺到 T 疼,全部組件寫在一個頁面中,難維護,難查閱。那么有就第 4 種方式--單個組件,什么是單個組件,也就是定義一個后綴為 .vue 的文件,然后把模版、js、style 都寫在這個文件中,這就是單個組件,我們開始吧

1、創(chuàng)建一個單個組件的項目

如果看過第一節(jié)的朋友應(yīng)該知道,我們通過 vue-cli 能快速創(chuàng)建一個 vue 項目,并且里面單個組件等全部都為你生成了,下面我們通過自己手動來模擬一個類似于 vue-cli 創(chuàng)建出來的項目這么一個過程,直接上代碼

  • 1、新建一個文件夾--myvuedemo
// 命令行輸入,無論是 windows 還是 mac 
mkdir myvuedemo
cd myvuedemo 
  • 2、使用 yarn 初始化項目「當然也可以使用 npm ,yarn 和 npm 的安裝以前在 React 教程中說過,不清楚的可以自行百度一下」
yarn init 

一路回車即可,目錄如下:

myvuedemo目錄

我們可以看到使用 yarn init 初始代項目,就多了一個 package.json 文件

  • 3、在 myvuedemo 目錄下新建 src 和 dist 目錄,并且新建 index.html 文件
創(chuàng)建相關(guān)目錄
  • 4、安裝依賴

在前面我們都是使用引信 vue.js 的方式來使用 vue 的,現(xiàn)在我們安裝依賴的方式來使用 vue ,所以我們要安裝一些依賴,在 myvuedemo 目錄下使用如下命令

yarn add vue

安裝 webpack 和 webpack-dev-server,由于我們在開發(fā)環(huán)境中需要,所以在開發(fā)環(huán)境下安裝依賴「生產(chǎn)環(huán)境中是不需要的」

yarn add webpack webpack-dev-server --dev

我們查看 package.json 文件,就會看到依賴安裝上了,如下所示:

安裝部分依賴
  • 5、在 index.html 輸入以下內(nèi)容
<!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="container"></div>

<script src="./dist/bundle.js"></script>
</body>
</html>

我們定義了一個 id 為 container 的 div 并且,引入了打包后的 bundle.js

  • 6、在 src 中新建 main.js
import Vue from 'vue' ;

new Vue({
  el: '#container',
  render:h => h('div','HelloWorld')
})

以上代碼就是把 helloWorld 渲染到 id 為 container 的 div 中

  • 7、在根目錄下新建 webpack.config.js 并配置
var path = require('path')

module.exports = {
  // 入口文件
  entry: './src/main.js',
  // 輸出
  output: {
    path:path.resolve(__dirname,'./dist'),
    publicPath: '/dist/',
    // 名字叫 bundle.js
    filename: 'bundle.js'
  },

  // 導入的時候就可以不添加后綴后了
  resolve:{
    extensions: ['.js', '.vue']
  },

  devServer: {//webpack-dev-server配置
    historyApiFallback: true,//不跳轉(zhuǎn)
    noInfo: true,
    inline: true,//實時刷新
    hot:true
  }
}

好了基本上完成了,下面我們來測試一下

  • 8、查看結(jié)果

在目錄所在的命令行中輸入以下命令

webpack-dev-server --port 8888 --open --hot

輸入上述命令就會自動打開瀏覽器,并且顯示出 HelloWorld 來,我們一個簡單的基于 webpack 的 vue demo 就是跑起來了

webpack 的 vue demo 結(jié)果

這好像跟組件沒有半毛錢關(guān)系呀,不要急,我們接著來「就不休息了」

  • 9、我們在 src 中新建一個 first.vue
<template lang="html">
  <div class="">
    我是一個單個組件
  </div>
</template>

<script>
export default {
}
</script>

<style lang="css" scoped>
</style>

以上是一個標準的 vue 組件,并且把這個組件暴露出來,這就是一個單組件

  • 10 、在 main.js 引入 first.vue 組件,修改 main.js
import Vue from 'vue' ;
import first from './first'

new Vue({
  el: '#container',
  render:h => h(first)
})

我們來運行一下,看結(jié)果

babel-loader 錯誤

掛了,從圖可以看出說我們?nèi)鄙?babel-loader「就是用來轉(zhuǎn)化 es6 語法的」,我們安裝一下 babel-loader 并配置 webpack

安裝 babel-loader「babel 依賴于 babel-core 我們一同安裝」

yarn add babel-loader babel-core --dev

配置 webpack.config.js「配置在 module 的 rules 下面」

{
   test:/\.js$/,
   exclude: /node_modules/,
   loader: 'babel-loader'
 }

再運行結(jié)果

vue-loader 錯誤

靠,又掛了,不過這次說的是 vue-loader 的問題,什么是 vue-loader 呢?先說一下 loader 吧,webpack 里面的 loader 的作用就是資源轉(zhuǎn)化,由于 webpack 默認支持 js ,如果你想轉(zhuǎn)化 vue 為 js 模版,那么就要使用 vue-loader ,如果你想把 css 轉(zhuǎn)化成原生的 css 那么就要使用 style-loader 等

vue-loader 是一個加載器,能把以上的類似于 first.vue 組件轉(zhuǎn)化成 JavaScript 模塊。這里不過多的介紹 vue-loader??勺孕邪俣龋蛘呶页槌鲆黄?webpack 大概說一下

  • 11、安裝 vue-loader

我們安裝 vue-loader

yarn add vue-loader --dev

運行查看結(jié)果:

vue-template-compiler錯誤

瘋了,還報錯,但是 vue-loader 錯誤沒有了,這是一個新的錯誤,說找不到 vue-template-compiler「它就是一個把 vue2.0 模版預編譯為渲染函數(shù),避免開銷」

好吧,沒有辦法,我們安裝一下

yarn add vue-template-compiler --dev

再次運行查看結(jié)果:

單個組件顯示

不容易呀,終于顯示出來了,不過不要激動,還有一些問題,我們看 chrome 的 cosole 中顯示下面錯誤

css-loader 錯誤

說的是找不到 css-loader,為什么呢?由于我們使用 vue 的單個組件里面使用了 style 標簽,識別不到,就要使用 css-loader,我們安裝一下

yarn add css-loader --dev

我們知道安裝完 loader 一定要配置一下 webpack , 在 webpack.config.js 中的 module 下的 rules 下添加

{
    test: /\.css$/,
    loader: 'style-loader!css-loader'
},

繼續(xù)運行查看結(jié)果:

添加 css-loader 結(jié)果

[圖片上傳失敗...(image-e5a47d-1523543487961)]

完美,調(diào)試窗口也沒有報錯,這樣我們就一步一步搭建了一個 類似于 vue-cli 創(chuàng)建 vue 項目「當然沒有 vue-cli 那樣的完善」

  • 12、我們再建一個組件來豐富一下此 demo 吧

我們定義一個名為 login.vue 的組件

<template lang="html">
<div >
  <h4>我是登錄組件,包含在 first.vue 組件中</h4>
  用戶名:<input type="text" name="" value="" placeholder="用戶名" v-model="username"> <br/>
  密&nbsp;&nbsp;&nbsp;碼:<input type="password" name="" value="" placeholder="密碼" v-model="userpass"><br/>
  <div >
      <button type="button" name="button" class="loginbutton" @click="login()">登錄</button>
      <button type="button" name="button" class="resetbutton" @click="reset()">重置</button>
  </div>
  {{show message}
</div>
</template>

<script>
export default {
  name: 'login',
  data() {
    return {
      // 用戶名
      username:'',
      // 密碼
      userpass: '',
      // 顯示信息
      show message:'
    }
  },
  methods: {
    login() {
      if(this.username.length==0 || this.userpass.length==0){
        this.showmessage = '用戶名或密碼不能為空!'
        return
      }
      this.showmessage = "歡迎 "+this.username+" 登錄"
      this.username = ''
      this.userpass = ''
    },
    reset() {
      this.username = ''
      this.userpass = ''
      this.showmessage = ''
    }
  }
}
</script>

<style lang="css" scoped>
  .loginbutton{
    background: red;
  }
  .resetbutton{
    background-color: green;
  }
</style>

修改 first.vue 組件「引入 login.vue 組件并且使用」

引入 login.vue 組件

運行查看結(jié)果

引入 login.vue 組件結(jié)果

從以上結(jié)果可以看到,我們不僅在 first.vue 中引入了 login.vue 組件,而且 login.vue 組件的方法和事件完美運行

三、總結(jié)

本節(jié)我們著重介紹了 vue 最重要的特性之一 --- 組件,并用知道了 vue 中的組件有四種形式

  • 1、全局組件--在所有的 vue 實例中都可以使用
  • 2、局部組件--只能在指定的 vue 實例中使用
  • 3、嵌套組件--一個組件中可以嵌套另一個組件
  • 4、單個組件--通過手寫類 vue-cli 實現(xiàn)一個 vue demo 并且通過編寫單個組件進行組件之間的組合

PS: 我們在開發(fā)中,盡量使用單個組件的方式進行開發(fā),這樣不僅好維護并且方便閱讀,更便于團隊之間的協(xié)作

到此為止,我們把 vue 的組件就介紹完了,趕緊擼起袖子寫一寫吧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容