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

引子

身在此山 不觉山高峰险

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

群友疑惑

编写方式

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 配置好环境
  • npm install -g 歪脖派克
  • 搞个文件夹init一下~

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

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

推荐阅读更多精彩内容