zoukankan      html  css  js  c++  java
  • (译文)开始学习Vue——构建你的第一个Vue应用

    我们要构建如下组件:(最终代码在这里:https://codesandbox.io/s/38k1y8x375
    Vue.js Star Rating Component

    开始

    Vue是支持单文件组件的,但是我们不准备这么做。你也可以构建一个全局的组件,通过Vue.component,但是我们也不准备这么做。
    我们希望跟在真实项目中一样,构建一个可被编译的,可维护的组件。
    首先安装:

    npm install -g vue-cli
    vue init webpack-simple path/to/my-project

    (“Use sass”,回答Y,其他默认)
    然后切换到工程:

    cd path/to/my-project
    npm install
    npm run dev

    webpack会在浏览器打开你的组件,端口是8080:
    Welcome to Your Vue.js App!

    为了调试Vue组件,你需要在浏览器装一下插件:Vue devtools(chrome的扩展插件)

    第一个组件

    单文件是这么写的,.vue后缀的文件:

    <template>
      <!-- Your HTML goes here -->
      <ul>
        <li>One</li>
        <li>Two</li>
        <li>Three</li>
      </ul>
    </template>
    <script>
      /* Your JS goes here */
    </script>
    <style>
      /* Your CSS goes here */
    </style>

    我们在目录/src/components下:创建一个文件:Rating.vue,然后拷贝上面的代码。
    然后打开/src/main.js,按如下修改:

    import Vue from 'vue'
    import Rating from './components/Rating'
    new Vue({
      el: '#app',
      template: '<Rating/>',
      components: { Rating }
    })

    然后打开浏览器,你可以看到变化。
    你注意到,你不需要刷新页面。这是因为 vue-loader (webpack的loader)的热更新作用,你修改组件,只会刷新组件,不会刷新整个页面。

    模板

    安装如下,因为我们需要使用SVG 图标:

    npm install vue-awesome

    然后修改模板:

    <template>
      <div>
        <ul>
          <li><icon name="star"/></li>
          <li><icon name="star"/></li>
          <li><icon name="star"/></li>
          <li><icon name="star-o"/></li>
          <li><icon name="star-o"/></li>
        </ul>
        <span>3 of 5</span>
      </div>
    </template>
    <script>
      import 'vue-awesome/icons/star'
      import 'vue-awesome/icons/star-o'
      import Icon from 'vue-awesome/components/Icon'
      export default {
        components: { Icon }
      }
    </script>

    解释一下:
    Vue.js采用ES6模块的方式导入模块和导出模块。
    上面的Icon是Vue的单文件组件,就像我们上面自己构建的组件一样。
    export default是导出了一个对象,作为View Modal。导出了Icon供模板使用。

    注意:Vue只支持单元素root,所以必须包一层div

    样式

    CSS有一个不好的地方就是全局污染,你需要想办法隔离,重写不方便,复用和扩展都很难。
    一直以来我们都采用BEM方案,命名class的类名。

    现在,Vue和React引入了有作用域的样式。
    React是有一个样式组件,Vue有组件范围内的样式。你像往常一样写样式,不用担心污染,Vue会通过赋值给HTML一个data-attributes,并且拼接到样式里面来区别作用域。

    <template>
      <div class="rating">
        <ul class="list">
          <li class="star active"><icon name="star"/></li>
          <li class="star active"><icon name="star"/></li>
          <li class="star active"><icon name="star"/></li>
          <li class="star"><icon name="star-o"/></li>
          <li class="star"><icon name="star-o"/></li>
        </ul>
        <span>3 of 5</span>
      </div>
    </template>

    样式:注意style标签上的scoped属性(把样式放到html文件是不起作用的,因为这个样式是给组件用的)

    <style scoped>
      .rating {
        font-family: 'Avenir', Helvetica, Arial, sans-serif;
        font-size: 14px;
        color: #a7a8a8;
      }
      .list {
        margin: 0 0 5px 0;
        padding: 0;
        list-style-type: none;
      }
      .list:hover .star {
        color: #f3d23e;
      }
      .star {
        display: inline-block;
        cursor: pointer;
      }
      .star:hover ~ .star:not(.active) {
        color: inherit;
      }
      .active {
        color: #f3d23e;
      }
    </style>

    预处理器

    只需要在style标签加上:lang="scss"就行了

    行为

    修改一下代码:

    <script>
      ...
      export default {
        components: { Icon },
        data() {
          return {
            stars: 3,
            maxStars: 5
          }
        }
      }
    </script>
    <template>
      <div class="rating">
        <ul class="list">
          <li v-for="star in maxStars" :class="{ 'active': star <= stars }" class="star">
            <icon :name="star <= stars ? 'star' : 'star-o'"/>
          </li>
        </ul>
        <span>3 of 5</span>
      </div>
    </template>

    说明一下:
    1 通过data来设置组件的state:state的修改会反应在view层。
    2 data必须返回一个工厂函数,而不是一个对象引用。引用的话会被所有的组件共享,这不是我们要的。
    3 v-for是vue的指令,让你遍历。
    4 :class是v-bind:class的简写。动态绑定属性到一个表达式。
    5 只有当star小于stars时,会应用star class到li上面

    数量怎么弄?

    <span>{{ stars }} of {{ maxStars }}</span>

    当然最好是弄成计算属性:

    export default {
      ...
      computed: {
        counter() {
          return `${this.stars} of ${this.maxStars}`
        }
      }
    }
    <span>{{ counter }}</span>

    如果不需要数量的话,可以隐藏:

    <span v-if="hasCounter">{{ stars }} of {{ maxStars }}</span>
    export default {
      ...
      data() {
        return {
          stars: 3,
          maxStars: 5,
          hasCounter: true
        }
      }
    }

    交互

    <template>
      ...
      <li @click="rate(star)" ...>
      ...
    </template>
    export default {
      ...
      methods: {
        rate(star) {
          // do stuff
        }
      }
    }

    注意一点:Vue是单向数据流

    传递属性:props

    现在我们的数据都是写死在我们的组件里面的,因为我们的组件需要被复用。所以希望能从外面传递进来,这个时候就要用到props

    export default {
      props: ['grade', 'maxStars', 'hasCounter'],
      data() {
        return {
          stars: this.grade
        }
      },
      ...
    }

    main.js:

    new Vue({
      el: '#app',
      template: '<Rating :grade="3" :maxStars="5" :hasCounter="true"/>',
      components: { Rating }
    })

    props和data会在编译期间合并。data和props字段名最好不要一样,因为都是在模板直接使用的,避免混淆。

    为什么要把grade赋值给star呢: 因为props是会被修改的,最好使用的时候都复制一份。

    最后: prop检验器

    export default {
      props: {
        grade: {
          type: Number,
          required: true
        },
        maxStars: {
          type: Number,
          default: 5
        },
        hasCounter: {
          type: Boolean,
          default: true
        }
      },
      ...
    }

    以上就是今天的内容,感谢阅读。
    原文链接:https://frontstuff.io/build-your-first-vue-js-component

    作者知乎/公众号:前端疯 (一群热爱前端的一线程序员维护,想要用前端改变世界。)

  • 相关阅读:
    Python3简单的输入输出及内置函数查看
    Python绘制3d螺旋曲线图实例代码
    教女朋友学Python运行环境搭建
    初级模拟电路:3-4 共基放大电路(直流分析)
    初级模拟电路:3-3 共基组态
    初级模拟电路:3-2 BJT的工作原理
    初级模拟电路:3-1 BJT概述
    初级模拟电路:2-6 倍压电路
    初级模拟电路:2-5 钳位器
    初级模拟电路:2-4 限幅器
  • 原文地址:https://www.cnblogs.com/xunxing/p/462831972d466e582d591a6d495afea3.html
Copyright © 2011-2022 走看看