Vue.js 官方示例初探(ES6 改写)

假如以为有协助,迎接 star哈~

https://github.com/jiangjiu/blog-md/issues/11

谢谢作者 @尤小右 大大边写的超等带感的 Vue.js 前端框架,赠予的几个小例子都很有代表性,代码逻辑清楚简明,不禁想抄上一抄嗯。

官方的示例都是 ES5直接编写运转,并没有运用ES6以及构建东西,考虑到今后开辟大一些的项目以及官方出品的 vue-cli脚手架,决议此次进修之旅采纳二者连系写写官方的示例。

初探步骤:

  1. 观赏示例的 result

  2. 思索组件模板和逻辑完成思绪

  3. 碰到题目先搜一下 api 和官方教程(彷佛看过一遍照样记不住什么。。。连系实践重要嗯)

  4. 照样不会就看例子的代码吧(不出不测的话都邑走到这步哈哈)

  5. 整顿一下代码和总结

markdown Editor

一个极简的 markdown 编辑器,用了 marked 这个东西。

  • 新建一个 Marked 组件就 ok。看起来很简朴,textarea 标签作为输入编辑器,另一个 div 标签经由过程 marked 这个 markdown东西 转码。

  • npm i marked –save 来安装好 marked,import 后经由过程定义过滤器完成。

  • textarea 设置了 debounce指令。debounce 设置一个最小的延时,在每次敲击以后延时同步输入框的值与数据。假如每次更新都要举行高耗操纵(例如在输入提醒中 Ajax 要求),它较为有效。

<template>
  <div id="marked">
    <textarea v-model="input" debounce=500></textarea>
    <div v-html="input|marked"></div>
  </div>
</template>

<script>
  import marked from 'marked'
  export default {
    data () {
      return {
        // note: changing this line won't causes changes
        // with hot-reload because the reloaded component
        // preserves its current state and we are modifying
        // its initial state.
        input: '# Helzzz World!'
      }
    },
    filters: {
      marked: marked
    }
  }
</script>

github commits

编写一个小组件,异步猎取 github 的两条 branch的数据。

  • created:生命周期的钩子,在实例建立后同步挪用。此时实例已完毕剖析选项,意味着已建立了数据绑定,盘算属性,要领,watcher/事宜回调。然则还没有最先 DOM 编译,$el 还不存在。

  • watch:一个对象,键是视察表达式,值是对应回调。值也可所以要领名,或许是对象,包括选项。在实例化时为每一个键挪用 $watch() 。

  • 碰到的题目:eslint 老是提醒 new XMLHttpRequest() 毛病,not defined,并不晓得为啥会如许,看到了许多代码也并没失足啊,临时在 eslint 的配置文件把 no-undef 设为0疏忽它了,假如有晓得的童鞋能够指导一二。

<template>
  <div id="commits">
    <p>Latest vue.js Commits</p>
    <template v-for="branch in branches">
      <label :for="branch">
        <input type="radio"
               name="branch"
               :id="branch"
               :value="branch"
               v-model="currentBranch">
        {{branch}}</label>
    </template>
    <p>vuejs/vue@{{currentBranch}}</p>
    <ul>
      <li v-for="record in commits">
        <a :href="record.html_url" target="_blank">dd</a>
        - <span>{{record.commit.message}}</span>
        by <span>{{record.commit.author.name}}</span>
        at <span>{{record.commit.author.date}}</span>
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
    data () {
      return {
        branches: ['master', 'dev'],
        currentBranch: 'master',
        commits: null,
        apiURL: 'https://api.github.com/repos/vuejs/vue/commits?per_page=3&sha='
      }
    },
    created () { // 生命周期 created,猎取数据
      this.fetchData()
    },
    watch: {  // 观察变化,可所以值也可所以要领
      currentBranch: 'fetchData'
    },
    methods: {
      fetchData () {
        let xhr = new XMLHttpRequest()
        const self = this  // 下面的 onload事宜中 this 不再指向实例,所以要变量存一下
        xhr.open('GET', this.apiURL + this.currentBranch)
        xhr.onload = function () {
          self.commits = JSON.parse(xhr.responseText)
        }
        xhr.send()
      }
    }
  }
</script>

Validation+Firebase

firebase 及时后端云简朴搂了一眼,号称无后端数据存储加及时通讯照样很带感的,不过本身写的时刻老是报错,只好本身在当地 mock 一下了。今后写能够运用 wilddog,国内的

  • 盘算属性:因为模板中只能够用表达式,相对庞杂的逻辑并不合适放在模板中,所以盘算属性就派上用场了,简朴易用。盘算属性默许只是 getter 函数,不过也能够自定义 getter 和 setter函数。

  • transition 过渡:这个过渡体系听勾股大大说很值得进修,所以临时放下今后看源码先。

  • mock 数据对象今后比较蛋疼,会把 newUser这个对象直接 push 进 userRef 中,致使今后对 newUser 的操纵都邑被双向绑定显现到列表中。。。所以只好深拷贝一下数据 push 进去,这个留坑今后填。

  • !!:双叹号强迫范例转换为布尔值。

<template>
  <ul>
    <li class="user" v-for="user in userRef" transition>
      <span>{{user.name}} - {{user.email}}</span>
      <button @click="removeUser(user)">X</button>
    </li>
  </ul>
  <form @submit.prevent="addUser">
    <input type="text" v-model="newUser.name">
    <input type="text" v-model="newUser.email">
    <input type="submit" value="Add User">
  </form>
  <p v-show="!validation.name">Name can not be empty</p>
  <p v-show="!validation.email">email is not validated</p>
</template>
<script type="text/babel">
  const emailRE = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

  export default {
    data () {
      return {
        newUser: {
          name: '',
          email: ''
        },
        userRef: [
          {
            name: 'hh',
            email: '10218085@qq.com'
          },
          {
            name: 'heheihe',
            email: 'weirweoi@qq.com'
          }
        ]
      }
    },
    computed: {
      validation () {
        return {
          name: !!this.newUser.name.trim(),
          email: emailRE.test(this.newUser.email)
        }
      },
      isValid () {
        const validation = this.validation
        return Object.keys(validation).every(key => validation[key])
      }
    },
    methods: {
      addUser () {
        if (this.isValid) {
          let temp = JSON.parse(JSON.stringify(this.newUser))
          this.userRef.push(temp)
          this.newUser.name = ''
          this.newUser.email = ''
        }
      },
      removeUser (user) {
        
      }
    }
  }
</script>

树状视图

这个例子完成了树状视图,重要演示怎样递归挪用组件。

  • 递归组件:组件在本身的模板内能够递归挪用本身,然则要有 name 选项才能够,在这上面花了好长时间又去查了教程才发明。。。官方示例代码用 Vue.component()注册了全局组件,会把 id 自动注册为name 属性,所以没有手动写 name 属性。我在 cli 里写的时刻一向没注重,致使递归老是不显现嗯。

  • Vue.set:全局 API,设置对象的属性。假如对象是相应的,将触发视图更新。这个要领重要用于处理不能检测到属性增加的限定。

  • open = !open:这是用来 toggle 布尔值,又学了一招~

  • @click和@dblclick离别代表单击和双击事宜绑定。后一个还真是没注重过。

  • 动态 props:能够绑定 props,如许父组件数据变化后,也会通报给子组件。

<template>
  <li>
    <div @click="toggle" @dblclick="changeType">
      {{model.name}}
      <span v-if="isFolder">[ {{open ? '-' : '+'}} ]</span>
    </div>
    <ul v-show="open">
      <Item :model="model" v-for="model in model.children">
      </Item>
      <li @click="addChild">+</li>
    </ul>
  </li>
</template>
<script type="text/babel">
  import Vue from 'vue'
  export default {
    name: 'item',
    data () {
      return {
        open: false
      }
    },
    props: {
      model: Object
    },
    computed: {
      isFolder () {
        return this.model.children && this.model.children.length
      }
    },
    methods: {
      toggle () {
        if (this.isFolder) {
          this.open = !this.open
        }
      },
      changeType () {
        if (!this.isFolder) {
          Vue.set(this.model, 'children', [])
          this.addChild()
          this.open = true
        }
      },
      addChild () {
        this.model.children.push({name: 'new staff'})
      }

    }
  }

模态组件

一个弹出层,用到了组件、props、slot内容分发、过渡。

  • slot:内容分发的一个东东,个人明白彷佛电脑主机的 pci 插槽,接口标准一致,能够插进去差别的板子,比方 pci 网卡或许 pci声卡,依据 name 差别能够完成签字 slot,有需求的话别忘了设置 default的默许 slot嗯。

  • Props:写 react 的时刻就打仗过了,父组件能够经由过程 props 向下通报数据,这里又踩了坑,子组件肯定要显式声明 props 属性!!!!折腾了良久才去查 api 和教程,真是浪费时间。。

<template>    // 父组件
  <div id="app">
    <button @click="showModal = true">show modal</button>
    <modal :show.sync="showModal">
      <h3 slot="header">heaaaaaader</h3>  签字 slot 传入
    </modal>
  </div>
</template>

<template> // 子组件
  <div v-show="show" class="modal-mask" transition="modal">
    <div class="modal-wrapper">
      <div class="modal-container" transition="modal">

        <div class="modal-header">
          <slot name="header">default header</slot>
        </div>

        <div class="modal-body">
          <slot name="body">default body {{show}}</slot>
        </div>

        <div class="modal-footer">
          <slot name="footer">default footer</slot>
          <button @click="show = false" class="modal-default-button">OK</button>
        </div>

      </div>
    </div>
  </div>
</template>
<script type="text/babel">
  export default {
    props: {        //子组件肯定别忘了声明 props
      show: Boolean
    }
  }
</script>
    原文作者:将就
    原文地址: https://segmentfault.com/a/1190000005858817
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞