美文网首页
Vue项目实战(二)

Vue项目实战(二)

作者: 我是上帝可爱多 | 来源:发表于2017-08-23 15:56 被阅读72次

马上要下班了,实在是百无聊奈,所以我只好来写博客了,今天继续上一期的来讲。

1 数据最初的来源
import axios from 'axios'
// settings
axios.defaults.timeout = 5000
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
axios.defaults.baseURL = 'http://neteaseyanxuan.leanapp.cn/'
export function fetchPost (url, params = {}) {
  return new Promise((resolve, reject) => {
    axios.post(url, params).then(res => {
      resolve(res.data)
    }).catch((error) => {
      reject(error)
    })
  })
}
export function fetchGet (url, params = {}) {
  return new Promise((resolve, reject) => {
    axios.get(url, params).then(res => {
      resolve(res.data)
    }).catch((error) => {
      reject(error)
    })
  })
}
export default {
  // 缩略图展示信息
  getTypeDesc (path) {
    return fetchGet(`/${path}`)
  },

  // 商品详情展示信息
  getTypeDetail (type, id) {
    return fetchPost(`/${type}/detail`, {id})
  }
}

有没有,现在是不是豁然开朗,我们通过axios来拉取数据,它是一个异步的函数,通过then来进行数据返回的操作。
那么问题来了,什么是axios?


之前接触过vue1都知道vue-resource里面有封装好的http方法,说到这里,大家应该知道axios干嘛的吧

  • get请求
// Make a request for a user with a given ID
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// Optionally the request above could also be done as
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

本例子中就是用的第二种方式请求的。

  • POST请求
axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

下面这种用法显示了axios的强大

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // Both requests are now complete
  }));

这种连写的方法我们在promise里面也看到过,还算比较熟悉,对axios感兴趣的同学可以点这里

所以我们看到抓取商品详情的时候是这样的

import data from '@/fetch/api

const state = {
  homeDesc: {},
  homeDetail: {}
}

const actions = {
  gethomeDetail ({commit}, type, id) {
    data.getTypeDetail(type, id).then(res => {
      console.log('type data:', res)
      commit(types.SET_HOME_DETAIL, res)
    })
  }
}

const mutations = {
  [types.SET_HOME_DESC] (state, res) {
    state.homeDesc = res
  },
  [types.SET_HOME_DETAIL] (state, res) {
    state.homeDetail = res
  }
}
2 路由元信息
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const Home = { template: '<div>home</div>' }
const Foo = { template: '<div>foo</div>' }
const Bar = {
  template: `
    <div>
      bar
      <div style="height:500px"></div>
      <p id="anchor" style="height:500px">Anchor</p>
      <p id="anchor2">Anchor2</p>
    </div>
  `
}

// scrollBehavior:
// - only available in html5 history mode
// - defaults to no scroll behavior
// - return false to prevent scroll
const scrollBehavior = (to, from, savedPosition) => {
  if (savedPosition) {
    // savedPosition is only available for popstate navigations.
    return savedPosition
  } else {
    const position = {}
    // new navigation.
    // scroll to anchor by returning the selector
    if (to.hash) {
      position.selector = to.hash

      // specify offset of the element
      if (to.hash === '#anchor2') {
        position.offset = { y: 100 }
      }
    }
    // check if any matched route config has meta that requires scrolling to top
    if (to.matched.some(m => m.meta.scrollToTop)) {
      // cords will be used if no selector is provided,
      // or if the selector didn't match any element.
      position.x = 0
      position.y = 0
    }
    // if the returned position is falsy or an empty object,
    // will retain current scroll position.
    return position
  }
}

const router = new VueRouter({
  mode: 'history',
  base: __dirname,
  scrollBehavior,
  routes: [
    { path: '/', component: Home, meta: { scrollToTop: true }},
    { path: '/foo', component: Foo },
    { path: '/bar', component: Bar, meta: { scrollToTop: true }}
  ]
})

new Vue({
  router,
  template: `
    <div id="app">
      <h1>Scroll Behavior</h1>
      <ul>
        <li><router-link to="/">/</router-link></li>
        <li><router-link to="/foo">/foo</router-link></li>
        <li><router-link to="/bar">/bar</router-link></li>
        <li><router-link to="/bar#anchor">/bar#anchor</router-link></li>
        <li><router-link to="/bar#anchor2">/bar#anchor2</router-link></li>
      </ul>
      <router-view class="view"></router-view>
    </div>
  `
}).$mount('#app')

其实我想纠正一下我之前说的vue的路由比angular简单的结论,现在才发现任何一个成熟的前端框架路由都没那么简单,比如上面这个,他到底想做的是什么呢?

我们来看scrollBehavior这个函数,他有三个参数to,from,savedPosition,to是指要跳到的路由,from是指当前路由,savePosition用于前进后退位置的保存。

if (savedPosition) {
    // savedPosition is only available for popstate navigations.
    return savedPosition
  } 
//当前这个路由的跳转是通过popstate完成的

const position = {}
    // new navigation.
    // scroll to anchor by returning the selector
    if (to.hash) {
      position.selector = to.hash

      // specify offset of the element
      if (to.hash === '#anchor2') {
        position.offset = { y: 100 }
      }
    }
//当地址参数里面有#时,就会触发hash,固定锚点。

大家可以到这个地址自行下载 。

关于路由我会抽一期专题来讲这个。

3 解决组件引用

我们在写vue组件的时候,总是需要从外面import一个进来,这样做很麻烦,那么有没有什么方法不必每次都import。

import PixelContent from './views/Content/index'
import PixelContentComments from './views/Comment/index'
import PixelAtMeComment from './views/AtMeComment/index'
import PixelSpinner from './views/Spinner/index'
import PixelUserInfo from './views/UserInfo/index'

Vue.use(PixelContent)
Vue.use(PixelSpinner)
Vue.use(PixelContentComments)
Vue.use(PixelAtMeComment)
Vue.use(PixelUserInfo)

import PixelContentComments from './src/Comment'

PixelContentComments.install = function (Vue) {
    Vue.component(PixelContentComments.name, PixelContentComments)
}

export default PixelContentComments

这不就是仿vue用插件的写法吗。

这里最后我们再来说一下vue的插件使用方式。

let plugin = {};
plugin.install = function(Vue){
    Vue.prototype.say = function(){
        console.log('install')
        }
        
    Vue.mixin({
            created(){
            console.log('create')
            },
            mounted(){
            console.log('mounted')
            }
        })

   Vue.filter('formatTime', function (value) {
    Date.prototype.Format = function (fmt) { //author: meizz
        var o = {
            "M+": this.getMonth() + 1, //月份
            "d+": this.getDate(), //日
            "h+": this.getHours(), //小时
            "m+": this.getMinutes(), //分
            "s+": this.getSeconds(), //秒
            "q+": Math.floor((this.getMonth() + 3) / 3), //季度
            "S": this.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt))
            fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt))
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    }
    return new Date(value).Format("yyyy-MM-dd hh:mm:ss");
})
}
export default plugin   

最后在入口文件main.js里面使用该插件

import plugin from './views/Comment/plugin'
Vue.use(plugin)

引入上面插件后,所有的vue实例都有say方法,在created和mounted周期都会打印,其中也定义了filter管道,可以使用{{num|formatTime}}。

相关文章

网友评论

      本文标题:Vue项目实战(二)

      本文链接:https://www.haomeiwen.com/subject/ftbldxtx.html