Vue學(xué)習(xí)筆記——組件化開發(fā)

視頻資源來(lái)自:b站coderwhy王紅元老師——最全最新Vue、Vuejs教程,從入門到精通
文件僅為個(gè)人觀看視頻后的學(xué)習(xí)心得筆記,用于個(gè)人查看和記錄保存。文中定有疏漏錯(cuò)誤之處,懇請(qǐng)指正。

目錄:
邂逅Vuejs
Vue基礎(chǔ)語(yǔ)法
組件化開發(fā)
前端模塊化
webpack詳解
Vue CLI詳解
vue-router
Promise的使用
Vuex詳解
網(wǎng)絡(luò)模塊封裝
項(xiàng)目實(shí)戰(zhàn)

組件化開發(fā)

認(rèn)識(shí)組件化

組件化是Vue.js中的重要思想,提供了一種抽象,讓我們可以開發(fā)出一個(gè)個(gè)獨(dú)立可復(fù)用的小組件來(lái)構(gòu)造我們的應(yīng)用。

注冊(cè)組件

組件的使用分成三個(gè)步驟:

①創(chuàng)建組件構(gòu)造器
②注冊(cè)組件
③使用組件

image-20210725092428867

反單引號(hào)可以自由換行:

a = `asdas
dads`
<div id="app">
  <my-cpn></my-cpn>
  <my-cpn></my-cpn>
</div>
<script src="../js/vue.js"></script>
<script>
  //1.創(chuàng)建組件構(gòu)造器對(duì)象
  const cpnC = Vue.extend({
    template: `
    <div>
      <h2>我是標(biāo)題</h2>
      <p>我是內(nèi)容</p>
      <p>內(nèi)容是我</p>
    </div>
    `
  })

  //2.注冊(cè)組件
  Vue.component('my-cpn',cpnC)
  

必須放在vue實(shí)例中才能實(shí)現(xiàn)

組件其它補(bǔ)充

全局組件和局部組件

全局組件:意味著可以在多個(gè)Vue的實(shí)例下面使用

<script>
  const cpnC = Vue.extend({
    template: `
      <div>
        <h2>我是標(biāo)題</h2>
        <p>我是內(nèi)容</p>
      </div>
    `
  })

  /*全局組件*/
  Vue.component('cpn',cpnC)

  const app=new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    /*局部組件*/
    components: {
      cpn: cpnC
    }
  })
</script>

父組件和子組件

<div id="app">
  <cpn2></cpn2>
</div>
<script src="../js/vue.js"></script>
<script>
  const cpnC1 = Vue.extend({
    template: `
      <div>
        <h2>我是標(biāo)題1</h2>
        <p>我是內(nèi)容1</p>
      </div>
    `
  })
  const cpnC2 = Vue.extend({
    template: `
      <div>
        <h2>我是標(biāo)題2</h2>
        <cpn1></cpn1>
        <p>我是內(nèi)容2</p>
      </div>
    `,
    components: {
      cpn1: cpnC1
    }
  })
  const app=new Vue({
    el: '#app',
    data: {
      message: '你好啊'
    },
    components: {
      cpn2: cpnC2,
    }
  })
</script>

這里,cpn1是子組件,cpn2是父組件

注冊(cè)組件的語(yǔ)法糖寫法

全局組件:

Vue.component('cpn1',{
  template: `
    <div>
      <h2>我是標(biāo)題1</h2>
      <p>我是內(nèi)容1</p>
    </div>
  `
})

局部組件:

const app=new Vue({
  el: '#app',
  data: {
    message: '你好啊'
  },
  components: {
    'cpn2': {
      template: `
        <div>
          <h2>我是標(biāo)題1</h2>
          <p>我是內(nèi)容1</p>
        </div>
      `
    }
  }
})

組件模板的分離寫法

<template id="cpn">
<div>
  <h2>{{title}}</h2>
  <p>我是內(nèi)容</p>
</div>
</template>

<script src="../js/vue.js"></script>
<script>
  Vue.component('cpn',{
    template: '#cpn',
    data(){
      return {
        title: 'abc'
      }
    }
  })

組件數(shù)據(jù)存放

組件中不能直接訪問(wèn)vue實(shí)例中的data

<template id="cpn">
  <div>
    <h2>當(dāng)前計(jì)數(shù):{{counter}}</h2>
    <button @click="add">+</button>
    <button @click="sub">-</button>
  </div>
</template>

<script src="../js/vue.js"></script>
<script>
  Vue.component('cpnc',{
    template: '#cpn',
    data(){
      return {
        counter: 0
      }
    },

組件模板的{{}}必須用自己的data數(shù)據(jù),而不是頂層vue

組件對(duì)象也有data屬性,但必須是一個(gè)函數(shù)。
為什么?

<div id="app">
  <cpnc></cpnc>
  <cpnc></cpnc>
  <cpnc></cpnc>
</div>

<template id="cpn">
  <div>
    <h2>當(dāng)前計(jì)數(shù):{{counter}}</h2>
    <button @click="add">+</button>
    <button @click="sub">-</button>
  </div>
</template>

這個(gè)三個(gè)cpnc數(shù)據(jù)不共享,因?yàn)閐ata是函數(shù)。數(shù)據(jù)獨(dú)立

父子組件通信

父?jìng)髯樱╬rops)

properties屬性

實(shí)際開發(fā)中,一般是服務(wù)器給大組件數(shù)據(jù),小組件不請(qǐng)求(壓力大)

image-20210725102403420
<div id="app">
  <cpn :cmovies="movies" :cmessage="message"></cpn>
</div>

<template id="cpn">
  <div>
    <p>{{cmovies}}</p>
    <h2>{{cmessage}}</h2>
  </div>
</template>

↑一定要v-bind,否則就把message當(dāng)成字符串了

props: ['cmovies','cmessage'],

props,數(shù)組寫法↑

props,對(duì)象寫法↓

const cpn ={
  template: '#cpn',
  props: {
    cmessage:{
      type: String,
      default: 'aaaaaa',
      requires: true
    },
    cmovies: {
      type: Array,
      default: []
    }
  }
}

const app=new Vue({
  el: '#app',
  data: {
    message: '你好啊',
    movies: ['海王','海賊王','海爾兄弟']
  },
  components: {
    cpn
  }
})

requires: true ——必傳值
還可以傳對(duì)象(用函數(shù)寫)、自定義驗(yàn)證函數(shù)

image-20210725103708584

props 用駝峰標(biāo)識(shí) iLoveYou
html 類型屬性不區(qū)分大小寫,- - -命名法。cInfo可以寫作c-info

子傳父(自定義事件)

子組件 $emit 發(fā)射事件
父組件 v-on

<div id="app">
  <cpn v-on:item-click="cpnClick"></cpn>
</div>

<template id="cpn">
  <div>
    <button v-for="m in categories"
            v-on:click="btnClick(m)">
      {{m.name}}
    </button>
  </div>
</template>
<script src="../js/vue.js"></script>
<script>
  const cpn={
    template: '#cpn',
    data() {
      return {
        categories: [
          {id:'aaa',name: '熱門推薦'},
          {id:'bbb',name: '手機(jī)數(shù)碼'},
          {id:'ccc',name: '家用家電'},
        ]
      }
    },
    methods: {
      btnClick(item) {
        this.$emit('item-click',item);
      }
    }
  }
  const app=new Vue({
    el: '#app',
    data: {
    },
    components: {
      cpn
    },
    methods: {
      cpnClick(itemm){
        console.log('cpnnn',itemm);
      }
    }
  })
</script>

結(jié)合雙向綁定案例

num = parseInt(value)
num = parseFloat(value)

將數(shù)據(jù)轉(zhuǎn)成number型

props: {
  number1:Number,
},
data(){
  return{
    dnumber1:this.number1,
  }
},

父組件傳過(guò)來(lái)的值不可更改,必須用data把父組件數(shù)據(jù)拷貝一次后才能更改。

若想父組件跟著子組件改,用v-model雙向綁定的例子。@input="函數(shù)"

watch實(shí)現(xiàn)

父子組件的訪問(wèn)

父子組件的訪問(wèn)方式$children、$refs (reference 引用)
子訪問(wèn)父 $parent、$root

<div id="app">
  <cpn></cpn>
  <cpn></cpn>
  <cpn ref="aaa"></cpn>
  <button @click="btnClick">按鈕</button>
</div>

<template id="cpn">
  <div>
    <h2>我是子組件</h2>
  </div>
</template>
console.log(this.$children);
for(let c of this.$children){
  console.log(c.name);
  c.showMessage();
}

↑用$children,當(dāng)有好幾個(gè)子組件的時(shí)候,還可以依次訪問(wèn)。但是數(shù)組只能用1、2、3來(lái)標(biāo)識(shí),可能會(huì)指示不清。可以用$refs

↓在html標(biāo)簽上加上ref="aaa",相當(dāng)于key,aaa是給這個(gè)子組件取的名字。用$refs訪問(wèn)。

console.log(this.$refs.aaa.name)

實(shí)際中,$refs用得多

用$parent,子組件與父組件耦合度太高,復(fù)用性低

而this.$root.message 直接訪問(wèn)vue實(shí)例

slot的使用

基本使用

<div id="app">
  <cpn></cpn>
  <cpn><span>哈哈哈</span></cpn>
  <cpn><i>111</i></cpn>
</div>

<template id="cpn">
  <div>
    <h2>我是標(biāo)題</h2>
    <p>我是組件</p>
    <slot><button>按鈕</button></slot>
  </div>
</template>
image

因?yàn)橹挥幸粋€(gè)插槽,如果寫得多了,就全部替換

<slot></slot>里的是默認(rèn)顯示

具名插槽

<div id="app">
  <cpn>
    <span slot="center">標(biāo)題</span>
    <button slot="right">返回</button>
  </cpn>
</div>

<template id="cpn">
  <div>
    <slot name="left"><span>左邊</span></slot>
    <slot name="center"><span>中間</span></slot>
    <slot name="right"><span>右邊</span></slot>
  </div>
</template>
image

編譯的作用域

<!--vue實(shí)例作用域-->
<div id="app">
  <cpn v-show="isShow"></cpn>
</div>

<!--字組件作用域-->
<template id="cpn">
  <div>
    <h2>我是標(biāo)題</h2>
    <p>我是內(nèi)容</p>
    <button v-show="isShow">按鈕</button>
  </div>
</template>

作用域插槽

父組件替換插槽的標(biāo)簽,但是內(nèi)容由子組件來(lái)提供

<div id="app">
  <cpn></cpn>

  <cpn>
    <template slot-scope="aaa">
      <span v-for="item in aaa.ddd">{{item}} - </span>
    </template>
  </cpn>

  <cpn>
    <template slot-scope="aaa">
      <span>{{aaa.ddd.join(' - ')}}</span>
    </template>
  </cpn>
</div>

<template id="cpn">
  <div>
    <slot :ddd="languages">
      <ul>
        <li v-for="m in languages">{{m}}</li>
      </ul>
    </slot>
  </div>
</template>

this.languages.join('-'):用 - 作為字符串間的連接

image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容