马上要下班了,实在是百无聊奈,所以我只好来写博客了,今天继续上一期的来讲。
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}}。
网友评论