Vue.js的组件化编程

Vue.js

Reactive Components for Modern Web Interfaces

数据驱动的组件,为现代化的 Web 界面而生

尤小右 Evan You

@youyuxi

多说  / Google / Meteor

发布于 2014 年 2 月

Vue.js主要是干啥的?

它是一个 MVVM 前端框架

MVVM?

  • Model - View - ViewModel
  • State - UI - ?
    • ViewModel
    • 当数据改变的时候
    • UI 也自动改变
UI = VM(State)

一个前端框架?

  • 基于一定的准则写
  • 写起来更容易
  • 代码更易维护
  • 网站的业务逻辑可以不断扩展
  • 性能可以满足需求

Example

// Object.defineProperty
// getter / setter / watcher object

var a = {}
Object.defineProperty(a, 'b', {
  enumerable: false,
  value: "static",
  get: () => { ... },
  set: () => { ... }
})

Vue.js是怎么实现的?

Vue.js community?

  • vue-loader
  • vue-router
  • vue-resource
  • veux
  • 功能业务

    开发效率

  • vue-devtools
  • vue-cli
  • vux
  • vue-validator
  • Vue.js / Angular.js / React.js

    为什么很多人接触了 Vue.js 后很快就爱上了它?

    1. 它的语法很简单
    2. 它的学习曲线并不陡峭
    3. 比 Angular 快,比 React 轻(实现原理不同)
    4. 它同样性感地结合着新的轮子
    5. 它可以支持较为复杂的大型产品
    6. 它的组件管理很方便(Single File Components)
    7. 它的文档和官网都很好看且易读

    Vue.js 的组件化

    Why - How - What

    这是你搞不定的

    一大堆东西

    Why?

    😼 因为爽 😼

    人同时可以处理的信息是有限的

    这是你搞得定的一堆小东西

    和你能搞得定的一个关系网

    How?

    1. 定义一个组件
    2. 加载一个组件
    3. 使用一个组件
    4. 组建的生命周期
    5. 组件间的数据传输

    What?

    Vue.js Component System

    <!-- HTML -->
    <div id="example">
      <my-component></my-component>
    </div>
    
    <script src="app.js"></script>
    // app.js 创建根实例
    new Vue({
      el: '#example'
    })
    // app.js 定义
    var MyComponent = Vue.extend({
      template: '<div>A custom component!</div>'
    })
    // app.js 注册
    Vue.component('my-component', MyComponent)
    <div id="example">
      <div>A custom component!</div>
    </div>

    vue-loader

    Single File Components

    .vue: 一个文件来管理一个组件

    1. 样式:<style>
    2. 内容:<template>
    3. 行为:<script>
    4. 扩展:lang=" ... "
    5. 合作:彼此间源引
    // comment.vue
    <style lang="sass">
    button {
        border: 1px solid gray;
        &.blue { border-color: blue; }
    }
    </style>
    
    <template lang="jade">
    avatar(:user='user')
    input(type='text', v-model='content')
    button.blue(@click='submitComment')
    </template>
    
    <script>
    import Comment from '../models'
    import avatar  from './components/avatar.vue'
    
    export default {
        props: ['user'],
        components: {
            avatar
        },
        data () {
            return {
                content: ''
            }
        },
        methods: {
            submitComment (e) {
                e.preventDefault();
                var comment = new Comment(this.content)
                comment.save().then(() => {
                    alert('评论成功')
                    this.content = ''
                })
            }
        }
    }
    </script>

    Webpack

    A module bundler

    一个模块打包工具

    • 各种资源都是模块
    • 分开独立请求 js / css / ...
    • 打包合并成一个文件
    • 大型产品按需加载
    • ...
    var path = require('path');
    module.exports = {
      entry: './src/main.js',
      output: {
        path: './dist',
        publicPath:'dist/',
        filename: 'build.js'
      },
      module: {
        loaders: [
          //转化ES6语法
          {
            test: /\.js$/,
            loader: 'babel',
            exclude: /node_modules/
          },
          //解析.vue文件
          {
            test:/\.vue$/,
            loader:'vue'
          },
          //图片转化,小于8K自动转化为base64的编码
          {
            test: /\.(png|jpg|gif)$/,
            loader:'url-loader?limit=8192'
          }
        ]
      },
      vue:{
        loaders:{
          js:'babel'
        }
      },
      resolve: {
            // require时省略的扩展名,如:require('app') 不需要app.js
            extensions: ['', '.js', '.vue'],
            // 别名,可以直接使用别名来代表设定的路径以及其他
            alias: {
                filter: path.join(__dirname, './src/filters'),
                components: path.join(__dirname, './src/components')
            }
        }    
    }

    组件之间的数据交流

    1. props
      • 定义数据传递
      • 可三种绑定方式
      • event
      • 通过事件和回调传递
      • 多种信息传递方式
    
    Vue.component('child', {
      // 声明 props
      props: ['msg'],
      // prop 可以用在模板内
      // 可以用 `this.msg` 设置
      template: '<span>{{ msg }}</span>'
    })
    
    <!-- 默认为单向绑定 -->
    <child :msg="parentMsg"></child>
    
    <!-- 双向绑定 -->
    <child :msg.sync="parentMsg"></child>
    
    <!-- 单次绑定 -->
    <child :msg.once="parentMsg"></child>
    // 监听某一个事件
    $on('create-alert', () => { ... })
    // 在同一个组件里触发事件
    $emit('create-alert', { ... })
    // 向上传递一个事件
    $dispatch('create-alert', { ... })
    // 向下所有的组件传递一个事件
    $broadcast('create-alert', { ... })
    

    What if 我们要做一个更复杂的网站?

    有很多数据需要多个组件访问和调用?

    vuex

    一个基于  Vue.js 的 State Management 工具

    管理那些应用级的共享数据

    Thanks

    Copy of Copy of deck

    By shengbowen

    Copy of Copy of deck

    • 1,282