Vue入门学习(下)

5 篇文章 0 订阅
2 篇文章 0 订阅

学Vue已经两周的时间,本篇接着上篇订下的思路继续讲,博主在学习当中也是发现说了很多,其实都不如举个栗子来的明白,所以下面也都会用到一些栗子,有些就是官网官博提供的栗子,博主稍微修改了一下,并且整合到了一起,完整的项目可以去博主GitHub上面查看,如果对您有帮助的话,也是希望不吝给个star,新人也是需要大家相互鼓励,这个是博主github地址
废话不多说了,补充之前说到的事件,有一个自定义的事件,用$emit来触发事件,然后在父组件上面v-on来监听这触发的事件,后面可以跟一个方法名或者是js的语法,这个博主看过以后感觉应该是父子组件用来通信的方法之一,后面说到的vuex,也是可以进行父子间的通信。
说完事件,就说到了vue中最重要的部分组件了,组件分为全局组件和局部组件,一般在项目中用的vue单文件组件也是属于局部组件的一种,所以接下来的todolist栗子也是之前提到的项目中的一块,用的就是vue单文件组件,栗子也是非常的经典,博主也是利用这个栗子来简单说下包含的一些东西,先看下最终的效果图
这里写图片描述

没有录制gif,想看的同学可以自己下载项目亲自实践,然后下面是代码部分

TodoItem.vue
<template>
  <li
    class="todo"
    :class="{completed: todo.done,editing: editing}">
    <div class="view">
      <input
        type="checkbox"
        class="toggle"
        :checked="todo.done"
        @change="toggleTodo(todo)">
      <label
        v-text="todo.text"
        class="todo-content"
        @dblclick="editing=true"/>
      <el-button
        @click="removeTodo(todo)"
        icon="el-icon-delete"
        type="danger"
        size="small"
        circle/>
    </div>
    <input
      type="text"
      class="edit"
      v-show="editing"
      v-focus="editing"
      :value="todo.text"
      @keyup.enter="doneEdit"
      @keyup.esc="cancelEdit"
      @blur="doneEdit">
  </li>
</template>

<script>
import { mapActions } from 'vuex'

export default {
  name: 'Todo',
  props: {
    todo: Object
  },
  data () {
    return {
      editing: false
    }
  },
  directives: {
    focus (el, {value}, {context}) {
      if (value) {
        context.$nextTick(() => {
          el.focus()
        })
      }
    }
  },
  methods: {
    ...mapActions('todo', [
      'editTodo',
      // 点击复选框,改变事项的完成状态
      'toggleTodo',
      'removeTodo'
    ]),
    doneEdit (e) {
      // 获得输入框中的值和当前组件的todo对象传递给相应的mutations
      const value = e.target.value.trim()
      const {todo} = this
      if (!value) {
        this.removeTodo(todo)
      } else if (this.editing) {
        this.editTodo({
          todo,
          value
        })
        this.editing = false
      }
    },
    cancelEdit (e) {
      e.target.value = this.todo.text
      this.editing = false
    }
  }
}
</script>

style部分的代码就没有贴出来了,这个是todoitem的组件,单文件组件分成三个部分,template,script,以及style,template就是一个html的模板,组件的结构就是在这里面去定义的,上面也用到了element-ui这个vue的ui框架,能够节省我们写一些常用的组件的时间,其他的有绑定class,绑定事件等等指令也都是我们非常熟悉的,另外注意的地方在于这里使用了一个自定义的指令v-focus,内置是没有这个指令的,声明自定义的指令其实很简单,就是在组件的script里面写一个directives的属性,属性值就是自定义指令的名字,后面写上方法,这里的nextTick的方法,官方的API上面也是有介绍,表示下次DOM更新结束后,即修改数组后会调用的回调方法,这里就是聚焦的意思,每次更新一个todo之后,会自动聚焦在input框上面。
另外要说到的重点就是vuex,vuex官方介绍说用于大型的项目当中,小型项目没有必要使用这个,但是不管我们做的什么项目,该了解还都是需要了解的,下面我们将上面的item组件封装一下

TodoList.vue
<template>
  <section class="todoapp">
    <!-- header -->
    <header class="header">
      <h1>todos</h1>
      <input
        class="new-todo"
        style="width: 30%;"
        placeholder="What needs to be done?"
        @keyup.enter="addTodo"/>
    </header>
    <!-- main section -->
    <section
      class="list-content"
      v-show="todos.length">
      <input
        class="toggle-all"
        id="toggle-all"
        type="checkbox"
        :checked="allChecked"
        @change="toggleAll(!allChecked)"
        :value="allChecked">
      <label for="toggle-all">{{ allChecked }}</label>
      <ol class="todo-list">
        <TodoItem
          v-for="(todo, index) in filteredTodos"
          :key="index"
          :todo="todo"
        />
      </ol>
    </section>
    <!-- footer -->
    <footer
      class="footer"
      v-show="todos.length">
      <span class="todo-count">
        <strong>{{ remaining }}</strong>
        {{ remaining | pluralize('item') }} left
      </span>
      <ul>
        <li
          v-for="(val, key) in filters"
          class="filters">
          <a
            :href="'#/' + key"
            :class="{ selected: visibility === key }"
            @click="visibility = key">{{ key | capitalize }}</a>
        </li>
      </ul>
      <el-button
        type="primary"
        v-show="todos.length > remaining"
        @click="clearCompleted">
        Clear completed
      </el-button>
    </footer>
  </section>
</template>

<script>
import { mapActions } from 'vuex'
import TodoItem from '../components/TodoItem.vue'
const filters = {
  all: todos => todos,
  active: todos => todos.filter(todo => !todo.done),
  completed: todos => todos.filter(todo => todo.done)
}
export default {
  components: { TodoItem },
  data () {
    return {
      visibility: 'all',
      filters: filters,
    }
  },
  computed: {
    todos () {
      return this.$store.state.todo.todos
    },
    allChecked () {
      //检测todos中done属性,如果全部都为true,也就是都完成的情况下,返回true,否则返回false
      return this.todos.every(todo => todo.done)
    },
    filteredTodos () {
      // 返回过滤后三种状态的todos,all,active,complete
      return filters[this.visibility](this.todos)
    },
    remaining () {
      //返回done为false的选项,也就是未完成的事项的长度
      return this.todos.filter(todo => !todo.done).length
    }
  },
  methods: {
    ...mapActions('todo', [
      'toggleAll',
      'clearCompleted'
    ]),
    addTodo (e) {
      const text = e.target.value
      if (text.trim()) {
        this.$store.dispatch('todo/addTodo', text)
      }
      e.target.value = ''
    }
  },
  filters: {
    //过滤items的复数形式,等于1的时候不加s,其他情况都加上s
    pluralize: (n, w) => n === 1 ? w : (w + 's'),
    //首字母大写过滤
    capitalize: s => s.charAt(0).toUpperCase() + s.slice(1)
  }
}
</script>

TodoList组件添加一个输入框,用来添加代办事项,底部则是类似tab的作用,显示三种不同类型的列表,我们从input框输入待办事项开始,按下enter,这里就用了按键事件,发出一个action,addTodo方法先获取用户输入的值,检测空白字符输入,有值的话,分发action到store上,这个有一个前缀,类似路径的写法todo/addTodo,是因为使用了store的模块写法,像是其他的语言的命名空间的写法,最后我们在将input框情况,那么添加待办项就完成了,又是如何去完成的呢,这就要说说vuex了。
看完了vuex的文档,博主认为vuex其实就几个主要的概念理解明白其实就已经差不多了,先看state,就是保存基础数据的对象,一般数据都是保存在state中,getters就是根据state中的数据进行计算获得的数据,可以理解为组件当中的computed计算属性,actions就是我们发出的动作,会被acitons接受,actions来发出commit给mutaitions,那么mutations很显然就是最后来改变状态的“人”了,所有的状态改变都需要经手mutation来修改,而无法直接去修改,也有人会疑惑,那直接commit给mutations就可以了,为什么还需要actions呢,官方给出的答案是actions可以接受异步操作,而mutations只能是同步的,所以才会有了actions来commit操作,同时我们上面用到了dispatch,就是分发动作的作用,分发给actions。说了这么多,我们来看看store究竟长什么样子

const state = {
  todos: [
    {text: 'todos-vuejs',done: false},
    {text: 'todos-reactjs',done: false}
  ]
}

const actions = {
  addTodo ({commit}, text) {
    commit('addTodo', {
      text,
      done: false
    })
  },
  removeTodo ({commit}, todo) {
    commit('removeTodo', todo)
  },
  toggleTodo ({commit}, todo) {
    commit('editTodo', {
      todo,
      done: !todo.done
    })
  },
  editTodo ({commit}, {todo, value}) {
    commit('editTodo', {
      todo,
      text: value
    })
  },
  toggleAll ({state, commit}, done) {
    state.todos.forEach((todo) => {
      commit('editTodo', {
        todo,
        done
      })
    })
  },
  clearCompleted ({state, commit}) {
    //找到数组中已经完成的项,再遍历已经完成的项,提交删除的commit
    state.todos.filter(todo => todo.done)
      .forEach(todo => {
        commit('removeTodo', todo)
      })
  }
}

const mutations = {
  addTodo (state, todo) {
    state.todos.push(todo)
  },

  removeTodo (state, todo) {
    //找到传递进来的todo索引,删除当前的todo
    state.todos.splice(state.todos.indexOf(todo), 1)
  },

  editTodo (state, { todo, text = todo.text, done = todo.done }) {
    todo.text = text
    todo.done = done
  }
}

export default {
  namespaced: true,
  state,
  actions,
  mutations
}

是不是非常简单,就是一个对象写法,然后export default输出这个模块,再看看里面的就分为了刚刚博主说的几个属性,博主也在上面做了注释,供大家理解,而从这一整套的过程当中不难看出,使用vuex的话,组件之间发生了交互,并且有共享的数据,从上面的store中,我们也能看出来这个栗子当中产生的一系列动作,首先增加待办项,删除待办项,取反完成状态,编辑待办项,选择复选框变为完成状态,清除已完成的待办项这几个动作,可以看到大部分都是触发的editTodo的mutations,而这个mutations从上面的代码可以看到就是给数组中的属性复制,并且还设置了函数参数默认值,如果对函数参数默认值还不了解的同学也是需要去抓紧学习了。我们看到actions和mutations都接受了一个参数,参数也是actions传递过来的,参数可以是一个对象。说完这么多,整个栗子其实也就差不多了,输入值新增,勾选某一项,表示完成了待办项,勾选单独的复选框则表示取所有的事项的相反的状态,双击某一项,可以去编辑事件的内容,下面的三个列表则是所有,已完成,未完成事件的展示,如果某一项完成的话,就会出现清空的完成项的按钮。
以上的栗子也是涵盖了表单输入绑定,组件,vuex,vue-cli3.0,也算是比较全面的栗子了,下面我们就说说过渡,vue提供了一个过渡组件transition,还有过渡的钩子函数和过渡的类名,文档说的非常明白,这里就不赘述了,都这么聪明,肯定都懂的。
还有提到的vue-cli的工具,博主也是只会基本用法,某些配置还在摸索中,后续遇到有趣的东西,也是会在博客中和大家分享。最后这个万恶的排版,博主还是没有搞明白,只能将就看下了|- -

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值