对练习过程中遇到的疑惑和问题,进行归纳和总结
vue 2.8.1
一、遇到问题
1.scss引入
在最新的cli脚手架中,scss被默认处理,不需要专门在webpack.base.conf.js中对scss进行规则设置。
2.exports is not define
在练习中,通过exports导出接口的时候,控制台报错exports is not define,此时可以尝试通过export XXX导出,或者通过npm安装babel-preset-es2015,在.babel文件中
"presets": [ ["env", { "modules": false }], "es2015", "stage-2" ],
设置依赖,实现代码规范之间的转换。更多详见:
二、 知识点整理
1.vue-router
(1) v-link
v-link有三种用法:
//route.jsexport default new Router({ routes:[{ path : '/home/:id', name : 'detail', component : resolve => require(['./components/home.vue'],resolve) }]//index.html Home Home Home
v-link
会自动设置 <a>
的 href
属性,你无需使用href
来处理浏览器的调整,原因如下:
-
它在 history 模式和 hash 模式下的工作方式相同,所以如果你决定改变模式,或者 IE9 浏览器退化为 hash 模式时,都不需要做任何改变。
-
在 HTML5 history 模式下,
v-link
会监听点击事件,防止浏览器尝试重新加载页面。 -
在 HTML5 history 模式下使用
root
选项时,不需要在v-link
的 URL 中包含 root 路径。
(2) 路由对象this.$route
在使用了 vue-router 的应用中,路由对象会被注入每个组件中,赋值为 this.$route
,并且当路由切换时,路由对象会被更新。
路由对象暴露了以下属性:
-
- $route.path 字符串,等于当前路由对象的路径,会被解析为绝对路径,如
"/home/news"
。 - $route.params 对象,包含路由中的动态片段和全匹配片段的键值对
- $route.query 对象,包含路由中查询参数的键值对。例如,对于
/home/news/detail/01?favorite=yes
,会得到$route.query.favorite == 'yes'
。 - $route.router 路由规则所属的路由器(以及其所属的组件)。
- $route.matched 数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
- $route.name 当前路径的名字,如果没有使用具名路径,则名字为空。
- $route.path 字符串,等于当前路由对象的路径,会被解析为绝对路径,如
$router.matched
属性,它是一个包含性的匹配,它会将嵌套它的父路由都匹配出来。
例如,/home/news/detail/:id
这条路径,它包含3条匹配的路由:
- /home/news/detail/:id
- /home/news
- /home
详见:
(3) 切割流水线(钩子函数)
$route可以在子组件任何地方调用,代表当前路由对象,这个属性是只读的,里面的属性是 immutable(不可变) 的,不过你可以 watch(监测变化) 它。
全局钩子函数:beforeEach afterEach
组件内钩子函数:beforeRouteEnter beforeRouteLeave watch函数
以登录验证为例,使用全局钩子函数beforeEach(before each意思是在 每次每一个路由改变的时候都得执行一遍)
1 import Vue from 'vue' 2 import Router from 'vue-router' 3 4 Vue.use(Router) 5 6 const router = new Router({ 7 routes: [ 8 { 9 path: '/',10 /*11 * 按需加载 12 */13 component: (resolve) => {14 require(['../components/Home'], resolve)15 }16 }, {17 path: '/record',18 name: 'record',19 component: (resolve) => {20 require(['../components/Record'], resolve)21 }22 }, {23 path: '/Register',24 name: 'Register',25 component: (resolve) => {26 require(['../components/Register'], resolve)27 }28 }, {29 path: '/Luck',30 name: 'Luck', 31 // 需要登录才能进入的页面可以增加一个meta属性32 meta: { 33 requireAuth: true34 },35 component: (resolve) => {36 require(['../components/luck28/Luck'], resolve)37 }38 }39 ]40 })41 // 判断是否需要登录权限 以及是否登录42 router.beforeEach((to, from, next) => {43 if (to.matched.some(res => res.meta.requireAuth)) { // 判断是否需要登录权限44 if (localStorage.getItem('username')) { // 判断是否登录45 next()46 } else { // 没登录则跳转到登录界面47 next({48 path: '/Register',49 query: {redirect: to.fullPath}50 })51 }52 } else {53 next()54 }55 })56 57 export default router58 59 //res => res.meta.requireAuth60 //function(res){ 61 // return res.meta.requireAuth;62 //}
它的三个参数:
-
to: (Route路由对象)
即将要进入的目标 to对象下面的属性: path params query hash fullPath matched name -
from: (Route路由对象)
当前导航正要离开的路由 -
next: (
一定要调用该方法来 resolve 这个钩子。 调用方法:next(参数或者空) 必须调用Function函数
)
next(无参数的时候)
: 进行管道中的下一个钩子,如果走到最后一个钩子函数,那么 导航的状态就是 confirmed (确认的)
next('/')
或者 next({ path: '/' })
: 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
全局钩子函数 afterEach:after
钩子没有 next
方法,不能改变导航,代表已经确定好了导航怎么去执行后,附带的一个执行钩子函数
组件内钩子函数 beforeRouteEnter beforeRouteLeave watch,以项目中组件list.vue为例
1 ... 2 beforeRouteLeave(to,from,next){ 3 //如果跳转到详情页,记录重要数据 4 //方便从详情页返回到该页面的时候继续加载之前位置的数据 5 if(to.name === 'topic'){ 6 //当前滚动条位置 7 window.window.sessionStorage.scrollTop = $(window).scrollTop(); 8 //当前页面主题数据 9 window.window.sessionStorage.topics = JSON.stringify(this.topics);10 //查询参数11 window.window.sessionStorage.searchKey = JSON.stringify(this.searchKey);12 //当前tab from.query.tab有值则赋值否则赋值'all'13 window.window.sessionStorage.tab = from.query.tab || 'all'14 }15 $(window).off('scroll');16 next();17 },18 beforeRouteEnter(to,from,next){19 if(from.name !== 'topic'){20 //页面切换移除之前记录的数据集21 window.window.sessionStorage.removeItem('topics');22 window.window.sessionStorage.removeItem('searchKey');23 window.window.sessionStorage.removeItem('tab');24 }25 next();26 },27 ...28 watch : {29 //切换页面30 '$route' (to,from){31 //如果是当前页面切换分类的情况32 if(to.query && to.query.tab){33 this.searchKey.tab = to.query.tab;34 this.topics = [];35 this.index = {};36 }37 this.searchKey.page = 1;38 this.getTopics();39 //隐藏导航栏40 this.$refs.head.show = false;41 }42 },43 ...
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch(监测变化) $route
对象:
const User = { template: '...', 1、watch: { '$route' (to, from) { // 对路由变化作出响应... } } 2、watch: { '$route': 'fetchData' // 如果路由有变化,会再次执行fetchData方法 },
详见:
2. vuex (详见:)
(1) mapGetters辅助函数
mapGetters 辅助函数仅仅是将 store 中的 getters 映射到局部计算属性:
import { mapGetters } from 'vuex'export default { // ... computed: { // 使用对象展开运算符将 getters 混入 computed 对象中 ...mapGetters([ 'doneTodosCount', 'anotherGetter', // 映射 this.doneCount 为 store.getters.doneTodosCount doneCount: 'doneTodosCount' // ... ]) }}
3. vue自定义属性或方法
//demo.jsimport Vue from 'vue'export default{ install(){ Vue.prototype.$myName = "hello"; Vue.prototype.checkUserName = (value) => { if(/\w{6,20}/.test(value)){ return true; }else{ return false; } } } }//main.jsimport demo from 'demo.js'Vue.use(demo);//index.jsmounted(){ alert(this.$myName); alert(this.checkUserName('hello'));}
详见:http://blog.csdn.net/github_26672553/article/details/53046923