Vue組件化

Vue.png

前言

在工作中經(jīng)常會(huì)用到Vue,包括也會(huì)用到很多重要的點(diǎn)例如組件化等等仿野,現(xiàn)在也想對(duì)于之前的應(yīng)用和學(xué)習(xí)做一個(gè)小小的總結(jié)~后期也會(huì)不定期的更新

組件化

  • 概念:
    Vue組件系統(tǒng)提供了一種抽象芒率,讓我們可以使用獨(dú)立可復(fù)用的組件來構(gòu)建大型應(yīng)用隆敢,任何類型的應(yīng)用界面都可以抽象為一棵組件樹。
  • 思想:
    高內(nèi)聚低耦合(功能性越單一可復(fù)用性就越強(qiáng))
  • 優(yōu)點(diǎn):
    1. 提高開發(fā)效率
    2. 方便重復(fù)使用
    3. 簡(jiǎn)化調(diào)試步驟
    4. 提升項(xiàng)目可維護(hù)性
    5. 便于多人協(xié)助開發(fā)
      ....

一粘姜、組件通信

組件化的重中之重就是組件之間的通信鞠苟,怎么進(jìn)行傳值可以高效方便的完成功能開發(fā)

  • 常用通信方式:
    1. props (parent -> children)
    // child
    props: { msg: String }
    // parent
    <HelloWorld msg="Welcome to Vue.js" />
    
    2. event (children -> parent)
     // 派發(fā)自定義事件 誰(shuí)派發(fā)誰(shuí)監(jiān)聽
     // child
      this.$event('add',good)
      // parent
      <Cart @add="cartAdd($event)" />
    
    3. 事件總線 (任意兩個(gè)組件)
     // 發(fā)布訂閱模式
     // Bus: 事件派發(fā)乞榨、監(jiān)聽和回調(diào)管理
     class Bus {
        constructor() {
          this.callbacks = {}
        }
        $on(name, fn) {
          this.callbacks[name] = this.callbacks[name] || []
          this.callbacks[name].push(fn)
        }
        $emit(name, args) {
          if(this.callbacks[name]) {
             this.callbacks[name].forEach(cb => cb(args))
          }
        }
     }
     // main.js
     // 工作中通常用Vue代替Bus,因?yàn)閂ue已經(jīng)實(shí)現(xiàn)了相應(yīng)接口
     Vue.proptotype.$bus = new Bus()
    // child1
    this.$bus.$on('foo',handle)
    // child2
    this.$bus.$emit('foo')
    
    
    4. vuex (任意兩個(gè)組件)

    創(chuàng)建唯一的全局?jǐn)?shù)據(jù)管理者store,通過它管理數(shù)據(jù)并通知組件狀態(tài)變更偶妖,具體使用大家可以去vux了解學(xué)習(xí)姜凄。

  • 自定義事件:
    • 邊界情況:
      注:parent、root趾访、children由于高耦合态秧、強(qiáng)依賴的原因在項(xiàng)目里可根據(jù)實(shí)際情況使用
      1. parent / root
       // 兄弟組件之間通信可以通過公共祖輩搭橋,$parent或$root
       // brother1
       this.$parent.$on('foo',handle)
       // brother2
       this.$parent.$emit('foo')
      
      2. $children(自定義組件不包含原始標(biāo)簽)
       // 父組件可以通過$children訪問子組件實(shí)現(xiàn)父子通信
       // parent
       this.$children[0].xx = 'xxxxxx'
       // 注:$children不能保證子元素的順序(異步組件)
      
      3. $refs
       // 獲取子節(jié)點(diǎn)引用
       // parent
       <HelloWorld ref="hw" />
       mounted() {
        this.$refs.hw.xx = 'xxxxxx'
       }
      
      4. provide/inject
       // 能夠?qū)崿F(xiàn)祖先和后代之間傳值
       // 并不是響應(yīng)式的扼鞋,但是可以傳入響應(yīng)式的數(shù)據(jù)
       // 后代組件內(nèi)部聲明的變量名稱和inject傳入的名稱沖突申鱼,后代組件會(huì)覆蓋傳入的值
       // ancestor
       provide() {
         // 隔代傳參愤诱,用法類似于data
         return {
            foo: 'foo',
            app: this // 指的是當(dāng)前組件實(shí)例本身
         }
       }
       // descendant
       <p>{{ app.$options.name }}</p>
       // 當(dāng)命名沖突還想使用傳入的值的時(shí)候,給傳入的數(shù)據(jù)起別名
       // inject: ['foo','app'],
       inject: {
         foo2: 'foo',
         app: 'app'
       },
       data() {
         return {
           foo: 'my-foo'
         }
       }
      
    • 非prop特性
      注:包含父作用域中不作為prop被識(shí)別(且獲染栌选)的特性綁定(classstyle除外)淫半。當(dāng)一個(gè)組件沒有聲明任何prop時(shí),這里會(huì)包含所有父作用域的綁定(classstyle除外)匣砖,并且可以通過v-bind="$attrs"傳入內(nèi)部組件
      1. $attrs(屬性并未在props中聲明)
      // child:并未在props中聲明foo
      <p>{{ $attrs.foo }}</p>
      // parent
      <HelloWorld foo="foo" />
      
      2. $listeners (在子組件中只負(fù)責(zé)觸發(fā)回調(diào)函數(shù)但是在父組件中處理回調(diào)函數(shù)的邏輯)
       // parent
       <HelloWorld  @click="onClick"/>
       // child 使用v-on指令將$listeners展開(如果有多個(gè)事件科吭,是都會(huì)展開的)
       // $listeners (本身是一個(gè)鍵值對(duì)格式的對(duì)象 )
       // key->所有事件監(jiān)聽器的名稱  value->回調(diào)函數(shù)
       // 展開后 <p @click="onClick"></p>
       <p v-on="$listeners"></p>
      

二、插槽

插槽語(yǔ)法是Vue實(shí)現(xiàn)的內(nèi)容分發(fā)API猴鲫,用于復(fù)合組件開發(fā)对人。內(nèi)容分發(fā)簡(jiǎn)單來說就是內(nèi)容要在子組件中使用,但是要通過父組件將內(nèi)容傳遞進(jìn)來拂共。

  • 匿名插槽
 // comp1
 <div>
   <slot></slot>
 </div>
 // parent
 <Comp1>Hello</Comp1>
  • 具名插槽
 // 將內(nèi)容分發(fā)到子組件指定位置
 // comp2
 <div>
   <slot></slot>
   <slot name="content"></slot>
 </div>
 // parent
 <Comp2>
   // 默認(rèn)插槽用default做參數(shù)
   <template v-slot:default>匿名插槽</template>
   // 具名插槽用插槽名做參數(shù)
   <template v-slot:content>內(nèi)容...</template>
 </Comp2>
  • 作用域插槽

數(shù)據(jù)在子組件中牺弄,但是要在插槽中使用

 // comp3
 <div>
   <slot :foo="foo"></slot>
 </div>
 // parent
 <Comp3>
   // 把v-slot的值指定為作用域上下文對(duì)象
   <template v-slot:default="slotProps">
     來自子組件中的數(shù)據(jù){{ slotProps.foo }}
   </template>
   // 解構(gòu)賦值寫法
   <template v-slot:default="{foo}">
     來自子組件中的數(shù)據(jù){{ foo }}
   </template>
 </Comp3>

上面是對(duì)Vue組件化包括組件通信以及插槽的一些介紹,接下來要通過幾個(gè)在工作中常用的實(shí)例來實(shí)踐一下

一宜狐、表單組件

通用表單組件势告,參考element表單分析我們需要實(shí)現(xiàn)哪些組件:

  1. KForm (指定數(shù)據(jù)、校驗(yàn)規(guī)則->便于管理抚恒,統(tǒng)一傳參)
  2. KFormItem (執(zhí)行校驗(yàn)咱台、顯示錯(cuò)誤信息)
  3. KInput (維護(hù)數(shù)據(jù))
  • KInput
    1. 創(chuàng)建components/form/KInput.vue
    <template>
      <div>
        // 實(shí)現(xiàn)雙向數(shù)據(jù)綁定 @input,:value
        // 通過v-bind展開$attrs柑爸,顯示沒有在props里面?zhèn)魅氲闹党郴ぃ纾╬laceholder、type)
        <input :value="value" @input="onInput"  v-bind="$attrs" />
      </div>
    </template>
    
    <script>
    export default {
      inheritAttrs: false, // 將屬性繼承關(guān)閉
      props: {
        value: {
          type: String,
          defaule: ''
        }
      },
      methods: {
        onInput(e) {
          // 派發(fā)事件表鳍,將最新的值傳出去
          this.$emit('input',e.target.value)
        }
      }
    }
    </script>
    
    1. 使用KInput,創(chuàng)建components/form/index.vue
      <template>
        <div>
          <h3>KForm表單</h3>
          <hr />
          <KInput v-model="model.username"></KInput>
          <KInput type="password" v-model="model.password"></KInput>
        </div>
      </template>
    
      <script>
        import KInput from './KInput'
        export default {
          components: {
            KInput
          },
          data() {
            return {
              model: {
                username: 'Cherry',
                password: ''
              }
            }
          }
        }
      <script>
    
  • KFormItem
    1. 創(chuàng)建components/form/KFormItem.vue
    <template>
      <div>
        // label標(biāo)簽
        <label v-if="label">{{ label }}</label>
        // 插槽 input
        <slot></slot>
        // 錯(cuò)誤信息 
        <p v-if="error">{{ error }}</p>
      </div>
    
       <script>
        export default {
          props: {
            label: {
              type: String,
              default: ''
            },
          prop: String  // 校驗(yàn)的字段名稱
          },
         // 這個(gè)值是否涉及當(dāng)前組件的狀態(tài),如果是就放在data里面
          data() {
            return {
              error: ''
            }
          }
        }
      </script>
    </template>
    
    1. 使用KFormItem 在components/form/index.vue添加
    <template>
      <div>
        <h3>KForm表單</h3>
        <KFormItem label="用戶名" prop="username">
          <KInput v-model="model.username"></KInput>
        </KFormItem>
        <KFormItem  label="密碼" prop="password">
          <KInput v-model="model.password" type="password"></KInput>
        </KFormItem>
        <KFormItem>
          <button @click="onLogin">登錄</button>
        </KFormItem>
      </div>
    </template>
    
  • KForm 設(shè)置數(shù)據(jù)模型和校驗(yàn)規(guī)則
    1. 創(chuàng)建components/form/KForm.vue
    <template>
      <div>
        <form>  
          <slot></slot>
        </form>
      </div>
    </template>
    
    <script>
      export default {
        // 隔層傳遞數(shù)據(jù)
       provide() {
        return {
          // 將表單實(shí)例直接傳遞給后代
          form: this
        }
       },
       props: {
        model: {
          type: Object,
          required: true
        },
        rules: Object
       }
      }
    </script>
    
    1. 使用KForm.vue 在components/form/index.vue添加
    <template>
      <div>
        <KForm :model="model" :rules="rules">
          ...
        </KForm>
      </div>
    </template>
    
    <script>
    import KForm from './KForm' 
    export default {
      components: {
        KForm
      },
      data() {
        return {
          rules: {
            username: [{ required: true, message: "請(qǐng)輸入用戶名" }],
            password: [{required: true, message: "請(qǐng)輸入密碼" }]
          },
          model: { username: "Cherry", password: "" },
        }
      }
    }
    </script>
    
    1. 在KFormItem添加
    export default {
      inject: ['form'] // 通過form.rules[prop]可以訪問當(dāng)前表單的校驗(yàn)規(guī)則
    }
    
  • 數(shù)據(jù)校驗(yàn)
    1. 在KInput里面的onIput事件中觸發(fā)校驗(yàn)
    onInput(e) {
      // $parent指向KFormItem
      this.$parent.$emit('validate')
    }
    
    1. KFormItem監(jiān)聽校驗(yàn)通知馅而,獲取規(guī)則并執(zhí)行校驗(yàn)
      // 引入校驗(yàn)庫(kù):npm i -S async-validator
      import Schema from 'async-validator'
      export default {
        inject: ['form'], //注入
        mounted() {
          this.$on('validate',() => { this.validate() })
        },
        methods: {
          validate() {
            // 獲取校驗(yàn)規(guī)則
            const rule = this.form.rules[this.prop]
            // 獲取校驗(yàn)值
            const val = this.form.model[this.prop]
            // 獲取校驗(yàn)器 Schema參數(shù),key: 校驗(yàn)字段名 value: 校驗(yàn)規(guī)則
            const validator = new Schema({ [this.prop] : rule })
            // 執(zhí)行校驗(yàn),參數(shù)1校驗(yàn)?zāi)繕?biāo):校驗(yàn)值,參數(shù)2回調(diào)函數(shù)
            // 返回Promise對(duì)象
            return new Promise((resolve,reject) => {
              validator.validate({ [this.prop] : val },(errors) => {
                 if(errors) {
                  // 校驗(yàn)失敗
                 this.error = errors[0].message
                  reject()
                 } else {
                  // 校驗(yàn)通過 清空error
                  this.error = ''
                  resolve()
                }
              })
            })
          }
        }
      }
    
    1. 在index.vue添加
     <template>
      <div>
        <KForm :model="model" :rules="rules" ref="loginForm">
          ...
          <KFormItem>
            <button @click="onLogin">登錄</button>
          </KFormItem>
        </KForm>
      </div>
      
      <script>
        export default {
          methods: {
            onLogin() {
              // 全局校驗(yàn)
              this.$refs.loginForm.validate(isValid => {
                if(isValid) {
                  console.log('success')
                } else {
                  alert('校驗(yàn)失敗譬圣!')
                }
              })
            }
          }
        }
      </script>
    </template>
    
    1. 在KForm.vue添加
    // 添加全局校驗(yàn)方法
    validate() {
      // 遍歷所有FormItem瓮恭,執(zhí)行他們的validate方法
      // tasks是返回的Promise數(shù)組
      const tasks = this.$children
      .filter(item => item.prop) // 過濾一下沒有prop的FormItem
      .map(item => {})
      Promise.all(tasks)
      .then(() => cb(true)) // 校驗(yàn)通過 返回true
      .catch(() => cb(false)) // 校驗(yàn)失敗 返回false
    }
    

四、彈窗組件

  • 彈窗這一類組件的特點(diǎn):
    1. 在當(dāng)前vue實(shí)例之外是獨(dú)立存在的厘熟,通常掛載在body上
    2. 通過js動(dòng)態(tài)創(chuàng)建屯蹦,不需要在任何組件中聲明
  • 創(chuàng)建utils文件夾,并創(chuàng)建create.js
    import Vue from 'vue'
    // 創(chuàng)建create函數(shù)绳姨,可以動(dòng)態(tài)生成組件實(shí)例登澜,并且掛載至body上
    // Component:組件配置對(duì)象 
    function create(Component,props) {
      // 第一種實(shí)現(xiàn)方式:通過Vue實(shí)例實(shí)現(xiàn)
      // 借助Vue的構(gòu)造函數(shù)來動(dòng)態(tài)生成組件實(shí)例
      const vm = new Vue({
        render(h) {
          // h createElement別名,可以返回一個(gè)虛擬dom飘庄,VNode
          return h(Component,{props})
        }
      })
      vm.$mount() // 不指定宿主元素脑蠕,則會(huì)創(chuàng)建真實(shí)dom,但是不會(huì)追加操作
      // 通過$el屬性獲取真實(shí)dom,并在body后面做追加操作
      document.body.appendChild(vm.$el)
      // 返回組件實(shí)例
      const comp = vm.children[0]
      // 銷毀方法
      comp.remove = () => {
        document.body.removeChild(vm.$el)
        vm.destroy()
      }
      // 第二種實(shí)現(xiàn)方式:通過Vue.extend()實(shí)現(xiàn)
      const Ctor = Vue.extend(Component) // 構(gòu)造函數(shù)  
       // 創(chuàng)建組件實(shí)例
      const comp = new Ctor({propsData:props})
      // 掛載
      comp.$mount()
      document.body.appendChild(comp.$el)
      comp.remove = () => {
        document.body.removeChild(comp.$el)
        comp.$destroy()
      }
      return comp
    }
    // 暴露調(diào)用接口
    export default create
    
    • 創(chuàng)建通知組件:Notice.vue
      <template>
        <div class="box" v-if="isShow">
          <h3>{{ title }}</h3>
          <p class="box-content">{{ message} }</p>
        </div>
      </template>
      
      <script>
        export default {
           props: {
            title: { // 標(biāo)題
              type: String,
              default: ""
            }, 
            message: {  // 信息
              type: String,
              default: ""
            },
            duration: { // 時(shí)間
              type: Number,
              default: 1000
            } 
          },
          data() {
            return {
              isShow: false
            }
          },
          methods: {
            show() { // 顯示
              this.isShow = true
              // 自動(dòng)隱藏
              setTimeout(this.hide,this.duration)
            },
           hide() { // 隱藏
              this.isShow = false
              // 銷毀
              this.remove()
            }
          }
        }
      </script>
      
      <style>
      .box {
        position: fixed;
        width: 100%;
        top: 16px;
        left: 0;
        text-align: center;
        pointer-events: none;
        background-color: #fff;
        border: grey 3px solid;
        box-sizing: border-box;
      }
      .box-content {
        width: 200px;
        margin: 10px auto;
        font-size: 14px;
        padding: 8px 16px;
        background: #fff;
        border-radius: 3px;
        margin-bottom: 8px;
      }
      </style>
    
  • 使用create.js在index.vue中
    // 引入
    import create from "@/utils/create"
    import Notice from "@/components/Notice"
    export default {
      onLogin() {
        // 全局校驗(yàn)
        this.$refs.loginForm.validate(isValid => {
          if(isValid) {
             console.log('success')
          } else {
            // 傳入值第一個(gè)參數(shù)組件谴仙,第二個(gè)參數(shù)是配置項(xiàng)
            this.$create(Notice,{
              title: '校驗(yàn)失敗'迂求,
              message: '校驗(yàn)錯(cuò)誤,請(qǐng)重試',
              duration: 3000  
            }).show()
          }
        })
      }
    }
    

五晃跺、遞歸組件

遞歸組件是可以在它們自己模板中調(diào)用自身的組件,主要是針對(duì)樹形結(jié)構(gòu)的數(shù)據(jù)進(jìn)行展示揩局,在工作中的應(yīng)用場(chǎng)景也是很多的

  • 創(chuàng)建Node.vue
<template>
  <div>
    <div @click="toggle" :style="{ paddingLeft: (level-1)+'em' }">
      <label>
        {{ model.name }}
      </label>
      <span v-if="isFolder">[{{ open ?  '-' : '+' }}]</span>
    </div>
    <div v-show="open" v-if="isFolder">
      <Node 
        class="item" 
        v-for="model in model.children" 
        :model="model"
        :key="model.name"
        :level="level + 1"
      ></Node>
    </div>
  </div>
</template>

<script>
  export default {
    name: 'Node',
    props: {
      model: Object,
      level: {
        type: Number,
        default: 0
      }
    },
    data() {
      return {
        open: false
      }
    },
    computed: {
      isFolder: function() {
          return this.model.children && this.model.children.length
      }
    },
    methods: {
      toggle: function() { 
        if(this.isFolder) {
            this.open = !this.open
        }
      }
    }

  }
</script>
  • 創(chuàng)建Tree.vue
<template>
  <div class="tree">
    <Node v-for="item in date" :key="item.name" :model="item"></Node>
  </div>
</template>

<script>
import Node from './Node'
export default {
  name: 'Tree',
  props: {
    data: {
      type: Array,
      required: true
    }
  },
  components: {
    Node
  }
}
</script>

<style>
.tree {
  text-align: left;
}
</style>
  • 使用Tree.vue在Index.vue
<template>
  <div>
    <Node :data="treeData"></Node>
  </div>
</template>

<script>
  import Node from '@/components/Tree'
  export default {
    components: {
      Node
    },
    data() {
      return {
        treeData: [
          {
            name: '水果',
            children:[
              {
                name: '南方水果',
                children: [
                  ...
                ]
              },
              {
                name: '北方水果'
              }掀虎,
            ]
          },
          {
            name: '蔬菜'
          }
        ]
      }
    }
  }
</script>
以上是對(duì)組件化小小的總結(jié)凌盯,后期也會(huì)不斷的更新,其中可能有紕漏或者有寫錯(cuò)單詞的情況涩盾,大家也可以幫忙指出來十气,共同學(xué)習(xí)共同進(jìn)步~
蘇大強(qiáng)上線
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市春霍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌叶眉,老刑警劉巖址儒,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異衅疙,居然都是意外死亡莲趣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門饱溢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喧伞,“玉大人,你說我怎么就攤上這事绩郎∨琐辏” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵肋杖,是天一觀的道長(zhǎng)溉仑。 經(jīng)常有香客問我,道長(zhǎng)状植,這世上最難降的妖魔是什么浊竟? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮津畸,結(jié)果婚禮上振定,老公的妹妹穿的比我還像新娘。我一直安慰自己肉拓,他們只是感情好后频,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著帝簇,像睡著了一般徘郭。 火紅的嫁衣襯著肌膚如雪靠益。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天残揉,我揣著相機(jī)與錄音胧后,去河邊找鬼。 笑死抱环,一個(gè)胖子當(dāng)著我的面吹牛壳快,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播镇草,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼眶痰,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了梯啤?” 一聲冷哼從身側(cè)響起竖伯,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎因宇,沒想到半個(gè)月后七婴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡察滑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年打厘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贺辰。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡户盯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出饲化,到底是詐尸還是另有隱情莽鸭,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布滓侍,位于F島的核電站蒋川,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏撩笆。R本人自食惡果不足惜捺球,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望夕冲。 院中可真熱鬧氮兵,春花似錦、人聲如沸歹鱼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至南片,卻和暖如春掺涛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疼进。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工薪缆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伞广。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓拣帽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親嚼锄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子减拭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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

  • Vue 組件官網(wǎng):https://cn.vuejs.org/v2/guide/components.html 組件...
    瓔珞紈瀾閱讀 453評(píng)論 0 1
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,204評(píng)論 0 6
  • Vue組件化通訊 1. Vue的組成文件(.vue) 分為三部分,分別對(duì)應(yīng)html,js,css <templat...
    sunny519111閱讀 600評(píng)論 0 7
  • 認(rèn)識(shí)組件 組件化開發(fā): ? 將一個(gè)完成的頁(yè)面区丑,劃分成一個(gè)個(gè)的組件拧粪,最終由一個(gè)個(gè)組件來完成整個(gè)頁(yè)面你的開發(fā),這個(gè)...
    cj_jax閱讀 185評(píng)論 0 1
  • 組件效果演示 多項(xiàng)選擇器是移動(dòng)端常見的通用組件沧侥,比如多級(jí)分類既们、多級(jí)菜單的展示都離不開它,它還可以進(jìn)一步擴(kuò)展為時(shí)間選...
    Automn閱讀 1,860評(píng)論 1 4