Vue踩坑实录(一)

现在说到前端框架自然会想到的就是Angular、React、Vue 这三者。Angular虽然买了书,但是没有用过(书还是1.0的……)。React其实原本是在学RN时带上的,跟着慕课网上的教程做了个小练习 React 图片画廊 踩坑笔记
Vue的话毕竟是国人做的框架,一直就想学习一下的。于是就打算把之前React的这个小项目用Vue来重写一遍当作入门练习了。

接触新框架难免要踩坑,其中有几次感觉自己要死在坑里了。不过最后靠着官方文档和谷歌的帮助还是爬了出来。而这篇便是在完成后对所踩过的坑的一个总结。
*当然,本着一篇文章太长会没人看的原则。先列一下踩坑的大致数量,可能会分两篇来写完。

项目地址:

  1. Vue版:画廊应用
  2. React版:画廊应用

项目效果:画廊效果 (React版)


  1. Vue-cli .js?.Vue?
  2. 父组件向子组件传值
  3. eslint format
  4. Vue中使用SCSS
  5. class绑定与顺序
  6. v-for 子组件DOM的取得
  7. 子组件向父组件的传递
  8. 数组的更新方法

Vue-cli .js?.Vue?

在Vue的官方网站的安装教程中,对于Vue-cli有这样的提示。

你可以查看安装教程来了解其他安装 Vue 的选项。请注意我们不推荐新手直接使用 vue-cli
,尤其是对 Node.js 构建工具不够了解的同学。

自然,作为一个玩过Node的人,当然是表示不服气的。想都不想的就作死的敲下了$ npm install --global vue-cli

待全部安装完成、创建项目之后。打开其中的Vue文件,就瞬间傻眼了。
因为在官网中给出的文档是这样的。

var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})

而生成好的Vue文件是这样的。

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
      <li><a href="https://gitter.im/vuejs/vue" target="_blank">Gitter Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
      <br>
      <li><a href="http://vuejs-templates.github.io/webpack/" target="_blank">Docs for This Template</a></li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
      <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
      <li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>

怎么看这两个的差距都是有点大的。

但其实上一个是js文件中的写法,而后一个则是Vue的模板文件的写法。如果采用上一种写法的话,那应该还是和以前一样是HTML+CSS+JS分开管控,对于小项目这种可能会更好。(其实画廊应用应该更适合这一种)而且这一种也与React的写法相类似,从React转的话可能会更方便一些。

Vue的模板文件从后缀名就能看出.vue,对于模板文件浏览器肯定是不认识的,因此Vue的模板文件一定需要经过编译才能使用。仔细看一下其实就能发现,Script的部分其实和上一种是一样的(除了写法上),从大体的结构可以看出,Vue的模板文件中分为了template、script、style三个部分,分别代表了HTML、JS、CSS三个部分,这样一来一个.vue文件就是一个组件。而一个App就是许多个组件组成起来的。这也正符合了组件化的思想。

关于前端以及组件化的一些感想

前端在HTML、CSS、JS上从最初HTML、CSS、JS文件的分离,到现在组件化在小组件内的耦合,感觉整个方向在越来越清晰了。HTML、CSS、JS文件分离是从功能角度上看的,每个文件各司其职。文件结构是很清晰了,但是实际在复用的时候往往不方便。如果只是一个部分的复用,那么从一堆HTML、CSS、JS中截取一小段还是很麻烦的。可能是这样的原因,才有了组件化的想法吧。组件化就是从另一个角度来看了,如同(宏观)物理学中定义原子是不可再分一样,在Web应用中,组件便是不可再分的了。原子中我们知道有中子、质子等,对应的一个组件中自然也有模板、样式和行为(JS)了。而以组件为单位的复用,既可以是最小的原子组件、也可以是由原子组件组成的分子组件。这么一来就提高了复用度,对于复用的场景也很灵活,想必组件化也会是今后的一个主流吧。


父组件向子组件传值

父组件向子组件传值,与React类似,通过props进行传值。不过所传的props的值必须要在子组件中事先定义好。在子组件中可以通过this.$props.value来取得对应传进来的值。

<template>
  <figure class="picture-continer"
          :style="{top: imgPos.position.top + 'px', left: imgPos.position.left + 'px',  transform:'rotate(' + this.imgPos.rotate + 'deg)'}"
          :class="{'is-center':imgPos.isCenter,'is-inverse':imgPos.isInverse}"
          @click.stop="pictureAction">
    <img :src="picture.src"
         :alt="picture.title" />
    <h2 class="img-title">{{picture.title}}</h2>
    <div class="img-back">
      <p>{{picture.desc}}</p>
    </div>
  </figure>
</template>
<script>
// 引入event bus 作为组件间事件传递的中间件
import bus from '../assets/eventBus.js';

export default {
  name: 'picture',
  props: ['picture', 'img-pos', 'index'],  // 在这里使用中划线命名,但在上面template中采用驼峰式
  methods: {
    pictureAction: function () {
      if (this.$props.imgPos.isCenter) {
        // this.$props.imgPos.isInverse = !this.$props.imgPos.isInverse;
        bus.$emit('refresh-pic', this.$props.index);
      } else {
        bus.$emit('do-rearrange', this.$props.index);
      }
    }
  },
  data() {
    return {
      // imgPos: this.$props
    }
  },
  mounted() {

  },
  updated() {
    this.$nextTick(function () {
      if (this.$props.imgPos.isCenter) {
        // 由于roate 是内联样式,对于center的图片需要消除后才能让class的样式起作用
        this.$el.style.transform = '';
      }
    });
  }
}
</script>
<style lang="scss">
.picture-continer {
  width: 320px;
  height: 360px;
  margin: auto;
  padding: 40px 40px 0px 40px;
  box-sizing: border-box;
  border-radius: 1px;
  background-color: #fff;
  position: absolute;
  cursor: pointer;
  transform-style: preserve-3d;
  transform-origin: 0 50% 0; // 改变变化的原点为x轴原点
  transition: left .8s ease-in-out, top .8s ease-in-out, transform .5s;
  perspective: 1800px;
  h2 {
    height: 80px;
    margin: 0;
    line-height: 80px;
    color: #727272;
    text-align: center;
    font-size: 16px;
  }
}

.img-back {
  width: 320px;
  height: 360px;
  overflow: auto;
  position: absolute;
  left: 0;
  top: 0;
  background-color: #fff;
  transform: rotateY(-180deg);
  p {
    padding: 40px;
    color: #727272;
    font-size: 16px;
  }
}

.is-center {
  transform: rotate(0deg);
  z-index: 11;
}

.is-inverse {
  transform: translate(320px) rotateY(180deg);
}
</style>


eslint format

由于Vue-cli中是会开启eslint来检查javascript的语法的。但是,对于添加分号、方法名与括号之间必须有空格这种规定还是很讨厌的。然而如果不通过eslint的话,网页又是无法显示的。
所以可以通过在.eslintrc.js中添加一些规则把eslint中的一些检测给关了。
具体如何修改可以参考官方网站(是有中文版的哦~)

// http://eslint.org/docs/user-guide/configuring

module.exports = {
  root: true,
  parser: 'babel-eslint',
  parserOptions: {
    sourceType: 'module'
  },
  env: {
    browser: true,
  },
  // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
  extends: 'standard',
  // required to lint *.vue files
  plugins: [
    'html'
  ],
  // add your custom rules here
  'rules': {
    // 在rules中可以添加对应的规则,0是关闭、1或者其他的数值是开启
    // allow paren-less arrow functions
    'arrow-parens': 0,
    // allow async-await
    'generator-star-spacing': 0,
    // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,

    // 函数名后不需要空格
    'space-before-function-paren': 0,
    // 禁止不需要的分号
    'no-extra-semi': 0,
    // 永远需要分号
    'semi': 0,
    'no-new':0,
    'eol-last':0
  }
}

感觉篇幅已经很长了,所以第一篇就先到此打住。剩下的5个就在下一篇中记录吧。

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

推荐阅读更多精彩内容