vue 2 demo

安装

npm i vue-cli --global
vue init webpack vue-demo

安装有一些选项要选

Vue build: Runtime + Compiler
Install vue-router: n
Use ESLint to lint your code: y
Pick an ESLint preset: Standard
Set up unit tests: n
Setup e2e tests with Nightwatch: n
Should we run `npm install` for you after the project has been created: Yes, use NPM

然后启动

npm run start

VSCode 配置

"files.autoSave": "onFocusChange",
"files.associations": {
    "*.vue": "html"
},
"editor.autoClosingBrackets": "always",
"javascript.updateImportsOnFileMove.enabled": "always"

安装插件 Vetur 、 Vue 2 Snippets 和 ESLint

编写代码

准备做的是 todo-list 所以先写一个待办项的组件

src/conponents/TodoItem.vue

<template>
  <li
  class="item"
  @click="handleDelete"
  >{{content}}</li>
</template>

<script>
export default {
  props: ['content', 'index'],
  methods: {
    handleDelete () {
      this.$emit('delete', this.index)
    }
  }
}
</script>

<style scoped>
  .item {color: green}
</style>

首先先看 script 部分,props 属性声明了该组件接受两个传入的数据: content(代办项内容) 和 index(待办项下标)

methods 中定义了 handleDelete 的方法,用于向父组件发送请求删除自己的消息(通过 emit 触发 delete 消息并附带 index 参数)

再看 template 部分,@click="handleDelete" 在该组件上绑定了点击事件为 handleDelete

src/TodoList.vue

<template>
  <div>
    <div>
      <input v-model="inputValue"/>
      <button @click="handleSubmit">提交</button>
    </div>
    <ul>
      <todo-item
       v-for="(item, index) of list"
       :key="index"
       :content="item"
       :index="index"
       @delete="handleDelete"
      ></todo-item>
    </ul>
  </div>
</template>

注意 vue 规定组件只能有一个根元素,所以最外层要用 <div> 包裹。 input 元素通过 v-model 与 inputValue 的值绑定了。 button 的点击事件为 handleSubmit

<todo-item> 使用 v-for 根据 list 的数组生成多个该组件,同时把 list 中每个元素的内容和索引通过 item 和 index 传递,注意 vue 规定遍历中每个组件都要有自己的 key 值,这个 key 值必须是唯一的,但是不推荐用 index 作为 key 值(大概是因为性能问题,详情请查看官方文档)。由于是 demo 所以用了 index 作为 key 值

在 todo-item 组件中传入 item 的参数,注意当前的组件和作用域,一个很常见的错误写法是在 <todo-item>{{item}}</todo-item> 但是 todo-item 组件内是无法直接使用 父组件 TodoList 中的 list 的数据和 list 中的 item 内容的。 vue 中的模块必须通过一些方法来传递数据,比如上面在写 todo-item 组件的时候我们在 props 中定义了 ‘content’,所以父组件要通过 :content=”item” 来将 item 的数据传给 todo-item 组件。index同理。

在父组件中给 todo-item 监听了一个叫做 delete 的事件,处理方法为 handleDelete。注意这个 handleDelete 是父组件的 handleDelete,而 delete 监听的是来自子组件的事件。

<script>
import TodoItem from './components/TodoItem'
export default {
  components: {
    'todo-item': TodoItem
  },
  data () {
    return {
      inputValue: '',
      list: []
    }
  },
  methods: {
    handleSubmit () {
      this.list.push(this.inputValue)
      this.inputValue = ''
    },
    handleDelete (index) {
      this.list.splice(index, 1)
    }
  }
}
</script>

<style>
</style>

通过 import TodoItem from './components/TodoItem' 从文件中导入 TodoItem 子组件,写不写 .vue 都是可以的。通过 components: {'todo-item': TodoItem}<todo-item> 标签和 TodoItem 组件对应。

vue 规定在组件中 data 不是对象而是方法,要写成

data () {
  return {
    inputValue: '',
    list: []
}

定义了 handleSubmit 方法将 inputValue 的内容添加到自身的 list 数据,handleDelete 方法删除自身数据 list 中下标为传入参数 index 的数据

在 vue 中把组件之间的消息传递写好之后,就可以只操作数据而不用关心视图了

src/main.js

import Vue from 'vue'
import TodoList from './TodoList'

let vm = new Vue({
  el: '#app',
  components: { TodoList },
  template: '<TodoList/>'
})

vm.$mount('#app')

最后修改入口文件,浏览器应该就能查看效果了,如果有警告的话查看是不是 es6 语法写错了。