vue实战2知识点回顾

vue实战2知识点回顾

项目背景

该项目是第二个vue实战项目,第一个是跟着gitbook上的vue学习课程一起来的。这个项目呢是跟着从github上找的vue项目一起来的。源项目地址是 https://github.com/liangxiaojuan/vue-todos。

在这个项目中分了好几个阶段来完成:

阶段描述完成度
step1项目需求分析100%
step2组件撰写、数据模拟和功能初步实现95%
step3css样式化实现,和源项目不同,这里没有用less来实现95%
step4组件间数据共享实现100%
step5部分问题解决90%
step6项目回顾100%
step7添加github预览项目功能100%

项目预览

预览地址

注:这里预览地址采用的是GitHub Pages,而不是GitHub & BitBucket HTML Preview。

项目需求

  • 查询所有待办事项,待办单项
  • 新增,修改待办事项
  • 删除,锁定待办事项
  • 新增,修改,删除待办单项
  • 未完成的待办单项的计数

箭头函数

api中有不少这样的写法,这个呢实际上是箭头函数表达式的语法。

export const editTodo = params => {
  return axios.post(`/todo/editTodo`, params).then(res => res.data)
}

export const editRecord = params => {
  return axios.post(`/todo/editRecord`, params).then(res => res.data)
}

箭头函数的语法如下:很明显上面的写法符合单一参数时,园括号是可选的,这里就是没有写。

(参数1, 参数2,, 参数N) => { 函数声明 }
(参数1, 参数2,, 参数N) => 表达式(单一)
//相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }

// 当只有一个参数时,圆括号是可选的:
(单一参数) => {函数声明}
单一参数 => {函数声明}

// 没有参数的函数应该写成一对圆括号。
() => {函数声明}

所以结合箭头函数的语法来看:

addRecord({id: ID, text: this.text}) 等价于这个:


{id: ID, text: this.text} => {
  return axios.post(`/todo/editRecord`, {
    id: ID,
    text:
    // 箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。
    // 在ECMAScript 3/5中,通过将this值分配给封闭的变量,可以解决this问题。
    this.text}).then(res => res.data)
}

axios

axios是基于Promise的http库,用在浏览器和node.js中。axios常用的是get和post请求。get请求呢可以理解为向服务器发送索取数据的请求,post请求则是向服务器提交数据的请求。get请求中的数据是附在url后面,数据都是明文可见的,所以相对于post请求 没有那么安全。

Promise

Promise就是用来进行异步处理的,替代以前JS的异步处理方式(回调函数)。Promise迷你书

Promise方法链,.then()实际上返回的也是一个Promise对象。而Promise构造函数中resolve和reject参数是默认的,resolve代表着success后调用.then()。

new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve([200, {
        todo: todo
        }])
    }, 200).then(res => {
        let {
            id,
            title,
            count,
            isDelete,
            locked,
            record
        } = res.data.todo
    ...
    ).then(...)

Vue Router

动态路由匹配: 动态路径参数 以冒号开头。

**嵌套路由: 在 VueRouter 的参数中使用 children 配置。

命名路由: 可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。这样更容易找到该路由。

export default new Router({
  routes: [
    {
      path: '/', // 访问路径
      name: 'Layouts', // 路径名
      component: Layouts, // 访问的组件,即访问‘/’,它会加载 Layouts 组件所有的内容。
      children: [{
        path: '/todo/:id',
        name: 'todo',
        component: todo
      }]
    }
  ]
})

编程式导航: 导航到指定的 URL,这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

//等价于 声明式: <router-link :to="...">
this.$router.push({name: 'todo', params: {id: id}})

Vuex

vuex的核心就是store。store可以看作是一个仓库,里面包含着应用中大部分的state。

  1. vuex的状态存储是响应式的。若store中的state发生了变化,那么相应的组件也会相应地得到高效更新。
  2. store中的state不能直接更改,必须通过mutations。

下面的这段代码,vuex主要包含如下字段:statemutationsgettersactions

Vue.use(Vuex)

// 创建初始应用全局状态变量
const state = {
  todoList: [], // 指我们的待办事项列表数据
  menuOpen: false // 移动端的时候菜单是否开启
}

// 定义所需的 mutations
const mutations = {
  EDITTODE (state, data) { // 定义名为 EDITTODE函数用作改变todoList的值
    state.todoList = data
  },
  MENUOPEN (state) { // 定义名为 MENUOPEN函数用作改变menuOpen的值
    state.menuOpen = !state.menuOpen
  }
}

// 创建 store 实例并且导出
export default new Vuex.Store({
  actions,
  getters,
  state,
  mutations
})

state不用多说,包含应用全局状态变量。

提交 mutations是更改state的唯一方法,比如:

commit('EDITTODE', res.data.todos)

// type: EDITTODE
// state作为第一参数,data作为mutations的载荷,是可选参数
EDITTODE (state, data) {
    state.todoList = data
},

gettters呢是从store中的state中派生出来的内容。比如下面的这段代码中要获取state中的todoList变量,直接调用getTodoList接口即可。

// 调用方式
this.$store.getters.getTodoList

export const getTodoList = state => {
  // 派生状态todoList
  return state.todoList
}

actions类似于mutations,差异在于:

  1. 它提交的是mutation,而不是直接变更状态。
  2. actions可以包含任意异步操作。
// 调用方式
this.$store.dispatch('getTodo').then(

export const getTodo = ({commit}) => {
  return new Promise((resolve) => {
    getTodoList().then(res => {
      commit('EDITTODE', res.data.todos)
      resolve()
    })
  })
}

Mock

下面这段代码是利用Mock框架生成的模拟的数据。具体的语法可以参考wiki: https://github.com/nuysoft/Mock/wiki

Mock.mock({ // 根据数据模板生成模拟数据。
    id: Mock.Random.guid(), // 随机生成一个 GUID
    title: Mock.Random.first(), // 随机生成一个常见的英文名。
    isDelete: false, // 是否删除
    locked: Mock.Random.boolean(), // 随机锁定
    record: COUNT.map(() => { // 代办单项列表的数据
      return {
        text: Mock.Random.cparagraph(2), // 随机内容
        isDelete: false, // 是否删除
        checked: Mock.Random.boolean() // 是否完成
      }
    })
  })

光有Mock生成的数据还是无法工作的,需要想办法和axios关联起来,所以axios-mock-adapter 就来了

下面部分的代码就有模拟get和post请求的。具体的语法可以参考npm对应包里面的注释

get和post请求的回复 reply函数,它的参数格式是这样的:[status, data, headers],reply允许返回一个promise对象。

let mock = new MockAdapter(axios)

// 对应 axios.get(`/todo/listId`, { params: params})
mock.onGet('/todo/listId').reply(config => {
  let {
    id
  } = config.params
  // id 是传进来的值
  // todo 是根据id和现有的Todos数据匹配,找出id相等的数据,在进行返回
  let todo = Todos.find(todo => {
    return id && todo.id === id
  })
  // todo.count (等待完成数目)等于 todo.record(代办事项列表下面未被选择的数据
  todo.count = todo.record.filter((data) => {
    return data.checked === false
  }).length

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve([200, {
        todo: todo
      }])
    }, 200)
  })
})


// 对应 axios.post(`/todo/editTodo`, params).then(res => res.data)
mock.onPost('/todo/editTodo').reply(config => {
  let {
    todo
  } = JSON.parse(config.data)
  Todos.some((t, index) => {
    if (t.id === todo.id) {
      t.title = todo.title
      t.locked = todo.locked
      t.isDelete = todo.isDelete
      return true
    }
  })

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve([200])
    }, 200)
  })
})
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值