对练习过程中遇到的疑惑和问题,进行归纳和总结
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" ],
设置依赖,实现代码规范之间的转换。更多详见:https://cnodejs.org/topic/56460e0d89b4b49902e7fbd3
二、 知识点整理
1.vue-router
(1) v-link
v-link有三种用法:
//route.js export default new Router({ routes:[{ path : ‘/home/:id‘, name : ‘detail‘, component : resolve => require([‘./components/home.vue‘],resolve) }] //index.html <!-- 字面量路径 --> <a v-link="‘home‘">Home</a> <!-- 效果同上 --> <a v-link="{ path: ‘home‘ }">Home</a> <!-- 具名路径 --> <a v-link="{ name: ‘detail‘, params: {id: ‘01‘} }">Home</a>
v-link
会自动设置 <a>
的 href
属性,你无需使用href
来处理浏览器的调整,原因如下:
- 它在 HTML5 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
当前路径的名字,如果没有使用具名路径,则名字为空。
$router.matched
属性,它是一个包含性的匹配,它会将嵌套它的父路由都匹配出来。
例如,/home/news/detail/:id
这条路径,它包含3条匹配的路由:
- /home/news/detail/:id
- /home/news
- /home
详见:http://www.cnblogs.com/avon/p/5943008.html
(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: true 34 }, 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 router 58 59 //res => res.meta.requireAuth 60 //function(res){ 61 // return res.meta.requireAuth; 62 //}
对是否登录验证
它的三个参数:
to: (Route路由对象)
即将要进入的目标 路由对象 to对象下面的属性: path params query hash fullPath matched namefrom: (Route路由对象)
当前导航正要离开的路由next: (
一定要调用该方法来 resolve 这个钩子。 调用方法:next(参数或者空) 必须调用Function函数
)
next(无参数的时候)
: 进行管道中的下一个钩子,如果走到最后一个钩子函数,那么 导航的状态就是 confirmed (确认的)
next(‘/‘)
或者 next({ path: ‘/‘ })
: 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
全局钩子函数 afterEach:after
钩子没有 next
方法,不能改变导航,代表已经确定好了导航怎么去执行后,附带的一个执行钩子函数
组件内钩子函数 beforeRouteEnter beforeRouteLeave watch,以项目https://github.com/shinygang/Vue-cnodejs中组件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方法 },
详见:http://www.cnblogs.com/faith3/p/6224235.html
2. vuex (详见:http://blog.csdn.net/sinat_29412671/article/details/53635897)
(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.js import 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.js import demo from ‘demo.js‘ Vue.use(demo); //index.js mounted(){ alert(this.$myName); alert(this.checkUserName(‘hello‘)); }
详见:http://blog.csdn.net/github_26672553/article/details/53046923