Vue.js组件化开发实践

什么是Vue.js

Vue.js 是一套构建用户界面的 渐进式框架。它非常容易与其它库或已有项目整合,而无须从头开始重构整个项目;另一方面,Vue 完全有能力驱动采用单文件组件来开发的更为复杂的单页应用。

目前在我参与开发维护的项目中已经使用上了Vue.js的一些基本功能,下面两幅图来自项目截图。


vue-in-cur-poj.png
vue-in-cur-poj-2.png

Vue.js基本功能

  • 视图元素响应式
  • 数据双向绑定,解放DOM操作
  • 只关注视图层,渐进式插件

视图元素响应式

//视图
<div id="app">{{msg}}</div>
//JS逻辑
var vm = new Vue({
  el: '#app',
  data: {
    msg: 'hello world'
  }
})

上图中,我们在视图里声明一个变量msg,它被包在一个双花括号"{{}}"中,以此表明它是一个Vue所管理的视图变量元素。同时,我们在JS中新建一个Vue对象,其中的el对应"#app",表示改Vue对象管辖的视图范围为id是app所对应的区域;data中有一个msg属性,对应视图中的双花括号变量msg。一旦我们新建好这个Vue对象,所有对于该对象data属性中的msg进行操作,会同步反应在视图中的{{msg}}上,这个视图变量元素即具有响应式。

数据双向绑定,解放DOM操作

  • 双向绑定:可以理解为JS逻辑中的数据的更改会实时的反映在视图上;同时任何从视图中过来的数据或者事件,能够实时的反映在逻辑中。
  • 一旦视图和逻辑之间规定好需要绑定的数据和事件,那么业务逻辑就能专注数据处理,而无需手动管理DOM,这样就实现了视图和逻辑各司其职。

一个例子:

输入框中的输入的字符串实时显示在视图上;同时当用户点击视图中的一个按钮时,视图中的字符串反向之后在输出到视图上。

DOM操作

//视图
<div id="app">
    <p id="msg"></p><input id="inputMsg" type="text">
    <p id="gsm"></p><button id="reverseMsg">Reverse</button>
</div>
//逻辑
document.getElementById('inputMsg').addEventListener('input', function({
  document.getElementById('msg').innerText = this.value
}), false)

document.getElementById('reverseMsg').addEventListener('click', function({
  var msg = document.getElementById('msg').innerText
  document.getElementById('gsm').innerText = msg.split('').reverse().join('')
}), false)

Vue处理

//视图
<div id="app">
    <p>{{msg}}</p><input v-model="msg" type="text">
    <p>{{gsm}}</p><button v-on:click="reverseMsg">Reverse</button>
</div>
//逻辑
var vm = new Vue({
    el: '#app',
    data: {
        msg: "",
        gsm: ''
    },
    methods: {
        reverseMsg: function(){
            this.gsm = this.msg.split('').reverse().join('')
        }
    }
})

Vue.js组件

  • 易维护
  • 易复用

组件系统是 Vue.js 另一个重要概念,因为它提供了一种抽象,让我们可以用独立可复用的小组件来构建大型应用。如果我们考虑到这点,几乎任意类型的应用的界面都可以抽象为一个组件树。

components-concept.png

一个自定义的按钮

<div id='app'>
  <wds-button></wds-button>
</div>

<template id='template-wds-button'>
  <button class="wds-button">默认按钮</button>
</template>
var wdsButton = {
  template: '#template-wds-button'
}

var vm = new Vue({
  el: '#app',
  components: {
    'wds-button': wdsButton
  }
})
父组件传递数据到子组件: props
<div id='app'>
  <wds-button></wds-button>
  <wds-button type="success" btn-name="成功按钮"></wds-button>
</div>

<template id='template-wds-button'>
  <button v-bind:class="['wds-button', type ? 'wds-button--' + type: '']">{{btnName}}</button>
</template>
var wdsButton = {
    props: {
        btnName: {
            type: String,
            default: '默认按钮'
        },
        type: {
            type: String,
            default: ''
        }
    },
    template: '#template-wds-button'
}

var vm = new Vue({
  el: '#app',
  components: {
    'wds-button': wdsButton
  }
})
was-button 组件描述

Props

参数 说明 类型 可选值 默认值
btnName 按钮名字 String 默认按钮
type 按钮类型 String success/warning/danger
子组件将数据传回父组件:自定义Event
<div id='app'>
  <wds-button v-on:wds-button-click-event="alertButtonName" type="warning" btn-name="警告按钮"></wds-button>
</div>

<template id='template-wds-button'>
  <button class="wds-button" v-bind:class="['wds-button', type ? 'wds-button--' + type: '']" v-on:click="wdsButtonClick">{{btnName}}</button>
</template>
var wdsButton = {
    props: {
        btnName: {
            type: String,
            default: '默认按钮'
        },
        type: {
            type: String,
            default: ''
        }
    },
    methods: {
      wdsButtonClick: function(){
        this.$emit('wds-button-click-event', this.btnName, this.type)
      }
    },
    template: '#template-wds-button'
}

var vm = new Vue({
  el: '#app',
  components: {
    'wds-button': wdsButton
  },
  methods: {
    alertButtonName: function(btnName, type){
      alert(btnName)
    }
  }
})
was-button 组件描述

Props

参数 说明 类型 可选值 默认值
btnName 按钮名字 String 默认按钮
type 按钮类型 String success/warning/danger

events

事件名称 说明 回调参数
wds-button-click-event 点击按钮回调事件 btnName, type

Vue.js单文件组件

  • 组件应该内聚自己的样式(HTML/CSS)和逻辑(JS)
  • 一个组件对应一个文件

文件和组件一一对应:.vue文件

vue-file-sample.png

.vue文件无法直接运行在浏览器上,通过webpack + vue-loader的方式来将Vue组件转化为JS模块。

  • webpack: 前端资源模块化管理打包工具。
  • vue-loader: webpack下处理.vue文件的的插件。

一个例子:

一个页面中有多个按钮,每点击一个按钮弹出toast信息,按钮toast都自定义。代码可以下载这里

vue-webpack-demo-directory.png

小结

前端技术日新月异,如果你今年还没开始学某门技能,明年就可以用不学它了。

end-emoji.jpeg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容