代码

[高手勿入]vue有几种编写方式?

2016-07-07  本文已影响11783人  懒先森

引子

身在此山 不觉山高峰险

废话我们留到最后说,该篇缘自群里朋友的疑惑,可惜不是女生问的~

群友疑惑

编写方式

1.简单粗暴型

👧:"小哥哥~vue看示例都好复杂呦,又要node又歪脖派克的,搞的人家好烦~都没发学啦~"
👦:“小妹妹你来~我给你看个好东西”

官网示例 中的表格组件

Paste_Image.png

再比如一个实际例子:
html:直接在index.html中使用,挂载点为body,除了根组件 另外做了视频相关的组件

<body>
<section name="ui_focus_time" id="ui_focus_time" class="lb-box clearfjx">
    <div class="lunbobig">
        <div class="lunbobig-wraper">
            <div style="position: absolute;right: 0px;top: 0px;z-index: 3001;">
                <div class="jiathis_style_32x32">
                    <a class="jiathis_button_qzone"></a>
                    <a class="jiathis_button_tsina"></a>
                    <a class="jiathis_button_tqq"></a>
                    <a class="jiathis_button_renren"></a>
                </div>
            </div>
            <video-time-slider :video="curTimesVideo" :container-id="curTimesVideo.container_id"></video-time-slider>
        </div>
    </div>
    <div class="lunbosmall clearfjx">
        <div id="ui_focus_time_swiper" class="swiper-container">
            <div class="swiper-wrapper">
                <div v-for="video in videoTimesPackage" @click="switchTimeVideo(video)" class="swiper-slide video-time-item">
                    <video-time-slider :video="video" :container-id="video.container_id"></video-time-slider>
                </div>
            </div>
        </div>
    </div>
</section>
</body>
<script src="js/vue.min.js"></script>

script:根组件和视频播放器初始化的组件,直接在根组件中的components中声明,如果你有多个组件要用到这个,那就在全局声明;

<script>
var vm = new Vue({
      el: "body",
      data: {
          isLoaded:false,
          isCanShowChance:false,
          switchStatusOption:{
              menuToggle: false,//导航显示
              ruleToggle: false,//规则浮层
              prizeToggle:false,//徽章浮层
              isShowPrizeMask: false,//徽章说明浮层
              isShowAdPopup:false,//广告IFRAME浮层
              isShowLogout:false,//注销登录按钮显示
              isShowGetChancePopup:false,//中奖浮层
              loginRemindToggle:false//中奖浮层
          }
      },
      beforeCompile:function(){
          var ctx = this;
          ctx.videoNewsPackage = videos_news_package;
          ctx.videoTimesPackage = videos_times_package;
          ctx.curTimesVideo = videos_times_package[0];
          ctx.$nextTick(function(){
              var timeSwiper = new Swiper('#ui_focus_time_swiper', {
                  slidesPerView: 3,
                  paginationClickable: true
              })
          })
      },
      ready: function () {
      },
      methods: {
          /**
           * 打开规则浮层 调用遮罩
           */
          openRule: function () {
              this.styleOption.popupTop = window.scrollY + 50;
              this.switchStatusOption.ruleToggle = true;
              mask.show();
          },
          /**
           * 关闭规则浮层 隐藏遮罩
           */
          closeRule: function () {
              this.switchStatusOption.ruleToggle = false;
              mask.hide();
          }
      },
      watch: {
          'switchStatusOption.menuToggle':function(val){
              if(val==true)this._checkToggleStatus('menuToggle');
          },
          'switchStatusOption.ruleToggle':function(val){
              if(val==true)this._checkToggleStatus('ruleToggle');
          },
          'switchStatusOption.prizeToggle':function(val){
              if(val==true)this._checkToggleStatus('prizeToggle');
          },
          'switchStatusOption.isShowPrizeMask':function(val){
              if(val==true)this._checkToggleStatus('isShowPrizeMask');
          },
          'switchStatusOption.isShowAdPopup':function(val){
              if(val==true)this._checkToggleStatus('isShowAdPopup');
          }
      },
      components: {
          'video-news-head': {
              props: ['video','containerId'],
              template: '<div class="video-img">'+
              '                    <div id="{{containerId}}" class="video-player-wrap">'+
              '                    </div>'+
              '                    <p>{{video.video_txt}}</p>'+
              '                </div>',
              attached:function(){
                  var _curComponentContext = this;
                  var _curDomId = _curComponentContext.containerId;
                  var _videoId = _curComponentContext.video.video_id;
                  var _videoPlayOpt = {
                      containerId: _curDomId,
                      vid: _videoId,
                      share: 1,
                      autoplay: 0,
                      ark:0,
                      event: {
                          onPlayerInit: function () {
                              console.info("播放器初始化")
                          },
                          onPlayerVideoPlay: function () {
                              setShare(_curComponentContext.video);
                              _letvPlayer.setFullScreen({
                                  fullScreen: true
                              });
                          }
                      }
                  }
                  var _letvPlayer = new LETV_PLAYER.Player(_videoPlayOpt,LETV_SDK_KEY)
              }
          }
      }
  })
</script>

样式就不用举例了 内联还是外部引入随项目需求
这是最简洁暴力的方式,特别适合你不需要做项目工程化,就写写专题页,你不需要懂gulp,webpack

这种方式特别适合对vue有强烈学习欲望却又对模块加载、工程化还很模糊的小伙伴

2.能优雅点吗?

👧:"上面的写的好简单哦~人家这样写会被骂成菜逼的,有没有再好点的,但是又别用什么require什么的好嘛,人家还没学😳"
👦:"呦呦呦~行 那就给你介绍个更菜逼的写法=_="

目录结构

vendor- //核心脚本
  lib-
    tool.js //编写加载模版的工具
  app.js
components-//组件
  header-//头部组件
    index.html //组件html模版
    index.js //组件脚本
  footer-//尾部组件
    index.html
    index.js
index.html //首页

组件编写示例:

(function(Vue){
  window.Template.getData("./components/header/index.html")
  var Header = Vue.extend({
    template:window.Template.data,
    // 选项...
    data:function(){
      return {
        msg:"i am header"
      }
    }
  })

  Vue.component('ui-header', Header);
})(Vue,window)

由于vue的template选项本身不支持URL获取模版。
所以要自己写一个同步获取html模版的工具,也不难(XMLHttpRequest)。

Paste_Image.png
3.模块加载

👧:“那什么,我刚看了些模块加载的资料,明白amd加载规范,学会使用require.js了,但是别整构建,配置好烦😢”
👦:“amd?也行,来来~这套学习方案很适合你”

结构如图示


Paste_Image.png

index.html:

<body>
  <ui-header></ui-header>
  <div>
    {{msg}}
  </div>
  <ui-footer></ui-footer>
  <script src="//cdn.bootcss.com/require.js/2.2.0/require.min.js"></script>
  <script src="vendor/app.js"></script>
</body>

组件编写代码

define(["Vue","text!components/header/index.html"],function(Vue,template) {
  // 这里是模块的代码
  var footer = Vue.extend({
    template:template,
    data:function(){
      return {
        msg:"我来组成裆部!"
      }
    }
  })
  return footer;
});

👦:"有了模块加载器 编写组件 加载模版 方便了许多 是不是"
👧:"不是-_-#"

4.构建你别怕

👧:“我看同志社区里例子都用node跑了,还用了什么歪脖派克,给我说说嘛,这块总是不懂”
👦:“别怕,这歪脖派克之前还有咕噜破和哥软特,但说白了都是构建工具,为你行方便的,尤大大钟爱歪脖,那咱就以歪脖为例子搞一哈~”

node自身就已经实现了�cmd模块规范~不如咱就用用~多学一种

目录结构
其实我这里如果把编译好的资源扔到dist目录就更好了,更符合工程化的思想

目录结构

注意到我这里两个组件header和footer分别用vue单文件和普通脚本方式编写
组件代码:vue单文件写法

<style>
/*样式*/
</style>
<template>
<!--模版-->
  <div>
    {{msg}}
  </div>
</template>
<script>
  //组件脚本
  module.exports = {
    data:function(){
      return {
        msg:"我来组成头部!"
      }
    }
  }
</script>

组件代码:普通写法

module.exports = {
  template:require("./index.html"),
  data:function(){
    return {
      msg:"我来组成裆部!"
    }
  }
}

可以看到vue单文件写法更能体现组件感~也方便不少,因为最近vue2.0测试版发布,但是vue-loader(用来处理.vue)却还没更新,导致有些新入伙的习惯.vue的懵圈了~

最后演示


成品效果

这是个很简单的原子项目,不包括复杂的东西,也不包括其他必须的处理流程,真正的工程肯定不是这样子的,但是慢慢根据歪脖派克的文档、大家的示例结合你的需求你可以让项目丰满实用起来。
👦:“所以你知道了吧,大家的项目构建都是根据自身的项目需求来的,有时候你down下来的项目不符合你的认知预期也正常的呦~”
👧:“越来越不懂了呢~”

5.vue-cli工程化

使用脚手架工具 vue-cli 可以快速地构建项目:单文件 Vue 组件,热加载,保存时检查代码,单元测试等——from官网构建大型应用

👧:“这~听起来就好高大上的哇~强烈要求壁咚啊~”
👦:“哎呀~瞧你没出息的样子-_-#”
不仅仅是套工具,它还提供几套构建脚手架模版:

总结

回到开头,群里朋友的疑问,目前很多大拿已经开始拥抱ECMAScript 6,网上也有很齐全的资料了,但不必因为不懂es6 而停止探索vue的步伐

👦:“vue作为新晋明星类库,伴随一系列风起云涌的工具、标准、规范,组合起来一时不便于理解,还需要余下时间补足基础才好学懂,再一个关键就是多多加强英文阅读理解能力~第一时间接触先进工具资料,你就可以借着它们的余晖在国内发光发亮~哪怕只是翻译呢~小妹妹你懂了咩~”
👧:“羞羞~你懂的真多~今晚有空么~人家想请你吃个烤面筋~”

上一篇下一篇

猜你喜欢

热点阅读