昔洛 的个人博客

Bug不空,誓不成佛

  menu
70 文章
14633 浏览
5 当前访客
ღゝ◡╹)ノ❤️

Vue 框架学习(三)

学习内容

  • 单文件组件
    • scoped 属性
    • 父子嵌套组件应用
    • vscode 安装扩展
    • 父给子传值
    • this 是谁
    • render 方法扩展使用
  • SPA
  • 路由
    • 介绍
    • 安装
    • 子路由
    • 路由传参(动态路由)
    • 编程式导航
    • 路由守卫
    • 强制登录思路

单文件组件

把一个组件的全部内容汇合到一个文件中,文件名字是以.vue结尾的就称作vue单文件组件

  • 普通组件的缺点:普通vue组件 其代码 和 其它JS代码逻辑掺杂在一块儿,不易维护,优势没有发挥到极致!

创建一个简单的单文件组件

  • 通过 vuecli 创建一个空的项目并运行
  • 创建单文件组件 src/components/01-第一个单文件组件.vue文件,内容如下:
    	<template>
    	  <div>
    
    	    <p>今天是个好日子</p>
    	  </div>
    	</template>
    
    	<script>
    	</script>
    
    	<style>
    	</style>
    
  • src/main.js文件 导入注册 组件,内容如下:
    	import Vue from 'vue/dist/vue.common.js' // Vue实例没有render要使用该vue
    
    	// import Vue from 'vue' // Vue实例有render要使用该vue(vue.runtime.common.js)
    
    	// es6模块化导入单文件组件-默认方式
    	// import 组件模块 from './components/01-第一个单文件组件.vue'
    	import ComOne from './components/01-第一个单文件组件.vue'
    
    	Vue.config.productionTip = false
    
    	new Vue({
    	  // 把导入进来的组件给注册好
    	  // components:{组件名称:{配置对象成员}} // 普通组件
    	  // components:{组件名称:组件模块} // 单文件组件
    	  // 组件名称推荐是“xx-yy”格式
    	  components:{
    	    'com-one':ComOne
    	  },
    
    	  data:{
    	    msg:'开始学习Vue单文件组件'
    	  }
    	}).$mount('#app')
    
    • 注意:
      • vue 要引入 vue.common.js
      • import App 的内容要去除
      • Vue 实例内部 render 去除
  • public/index.html 文件使用单文件组件
<div id="app">
      {{msg}}
      <com-one></com-one>
</div>
  • 注意:
    • 单文件组件的模板内容必须通过template实现,内部要求有唯一根元素
    • 单文件组件文件本身比较特殊,必须借助vuecli脚手架项目才可以运行

组织结构

  • 构成如下:
    image.png
  • 一个单文件组件涉及有如下3部分:
    • template标签,内部要求有唯一根元素(推荐div),template是html5标签,只运行,浏览器源代码不显示
    • script标签:该标签内部可以执行普通js代码,但是最主要的是内部可以通过export default {} 导出一个对象,该对象的成员完全可以参考 Vue实例,类似 data、methods、created、filters、components等等都可以应用,各个成员都是为template模板服务的
    • style标签:设置css样式,作用给template内部的html标签使用

私有/全局组件的注册

  • 在 main.js 中引入单文件组件
    • 私有注册:在 new Vue() 中使用私有设置的方式,把组件引入进去
    • 全局注册:在 new Vue() 之前使用 Vue.component(组件名称, 组件模块),方式注册全局单文件组件

scoped 属性

默认情况下,vue单文件组件的style样式是全局的,如果在一个应用中使用了多个单文件组件,它们使用相同选择器为相同的元素设置了style样式,那么只有一个会起作用 (后者会覆盖前者)

  • 作用:使得style的样式针对自己组件生效
  • 原理:给每个style标签都设置一个scoped属性,这样组件的各个html标签解析出来后都会带有一个与其他单组件标签不同的 data-v-xxx 的唯一属性名称,style样式设定也会自动与这个的data-v-xxx联系起来,这样就使得style样式只针对自己的组件起作用了
  • 语法:
    	<style scoped>
    		....
    	</style>
    
  • 父子嵌套组件应用: 一个组件里使用另一个组件
<template>	<!-- 父组件内容 -->
	<div>
		<p>father</p>
		<my-son></my-son>	<!-- 子组件 -->
	</div>
</template>

vscode 扩展

安装 Vetur,Vue 2 Snippets 扩展,用于语法高亮,语法提示

  • Vue 2 Snippets:设置代码片段,vscode 默认不能给 vue 文件做代码片段设置,需要安装此扩展。
    • 设置 -> user snippets -> vue.json,设置如下内容:
      	{	
      		"Create vue template": {
      
      			"prefix": "vuec",
      			"body": [
      			 "<template>",
      			 "  <div>$1</div>",
      			 "</template>",
      			 "",
      			 "<script>",
      			 "  export default {",
      			 "}",
      			 "</script>",
      			 "",
      			 "<style lang=\"less\" scoped>",
      			 "</style>",
      			 "",
      			],
      			"description": "Create vue template"
      		}
      	}
      

      在 vue 文件中通过 "vuec" 代码片段创建组件结构内容

父给子传值

父组件可以 引入、使用 子组件,从业务上看,该父组件有可能对子组件有个性化需求,为了体现组件的灵活多变,可以通过传值实现

  • 语法:
    <子组件标签 name=value name=value name=value></子组件标签>
  • 子组件接收并应用值,具体通过props接收
    	<!--在模板中应用传递来的数据-->
    	<input :style="{color:xx}">
    	<script>
    	  export default {
    	    // 通过props接收父传递过来的数据,注意各个名称需要使用单引号圈选
    	    props:['xx','xx','xx']
    	  }
    	</script>
    

this 指向与 render 方法扩展使用

  • Vue实例内部指向 new Vue()
  • 组件内部指向组件实例(VueComponent),同时该VueComponent有继承Vue,因此组件内部使用this与Vue实例的用法完全一致,即组件内部this可以正常访问自己的data、methods、computed等成员
  • render 语法
    	new Vue({
    	  render:h=>h('p','ok')  // 要生成 <p>ok</p> 并覆盖渲染 div容器
    	  render:h=>h(组件模块) // 要使用一个组件模块 对 div容器 进行覆盖渲染
    	})
    
    • 真实项目中一般喜欢创建一个名称为App.vue的组件,并用它去渲染覆盖 div容器
    • 所有业务逻辑实现都从App.vue开始,div容器 就是一个空壳摆设
    • 通过render对App.vue组件覆盖渲染应用,所有业务通过App.vue展开:
      • 在main.js文件中,要使用默认的vue import Vue from 'vue'
      • 所有业务组件都通过App.vue文件做应用( 组件的引入、注册、使用)

SPA

概念定义:SPA英文全称是Single Page Application, 中文翻译是 “单页面应用程序项目”,通俗的理解是:一个网站只有一个Web页面;网站的所有功能都在这个唯一的页面上进行展示与使用

  • 好处:
    • 实现了前后端分离模式(目前最好的开发模式)开发,各司其职;提高了开发效率;
    • 用户体验好,页面部分内容发生变化只需要更新局部即可(非刷新整个页面);
  • 缺点:
    • 对SEO(搜索引擎)不是很友好,网站从开始到结束始终访问一个程序文件,造成搜索引擎不给检索, 但是有解决方案,再者后台系统应用本身对seo不做要求
    • 每次应用运行时,需要一次性把全部的html、js、css等内容加载进来,因此会造成页面一开始请求速度较慢的问题(首页较慢,后续页面正常)
  • spa 应用场合:
    后台管理系统 和 移动端项目,它们特点是供访问的页面总数量小于500个

路由

路由是一个js功能模块,用于解决做个组件切换显示问题的,本身对组件切换的各个底层技术有做封装,是更成熟组件切换解决方案,使用起来更高级、方便。路由封装的元素有:#锚点超链接、component占位符标签、window.onhashchange、window.location.hash等等

583.png

安装路由

  • 安装路由两种方式:
    • vuecli 创建想项目的时候选择路由
    • 单独安装
  • 指令:yarn add vue-router

依赖包:通过npm i 或 yarn add 装的东西就是依赖包,每个依赖包内部有多个功能模块
模块:一个js文件内部有做"模块化导出"动作,这个js文件就是一个(功能)模块
yarn add 依赖包
npm install 依赖包

使用路由

  • 配置使用路由的基本步骤:

    • 打开 src/main.js
    • import 引入路由
    • Vue.use(路由模块) 注册路由组件
    • 创建路由对象,通过 path、component 设置#锚点与组件的联系
    • 在 Vue 实例内部挂载 router 路由对象
  • 设置切换按钮和占位符

    • 按钮:
      	<router-link to="/home">首页</router-link>
      	<router-link to="/user">会员</router-link>
      	<router-link to="/movie">电影</router-link>
      

      路由中通过 router-link 设置按钮和#锚点信息

    • 占位符:
      	<router-view></router-view>
      

      路由中通过 router-view 设置组件显示占位符

  • 执行过程:

    • 用户点击 页面的 路由链接router-link,点击的一瞬间,就会修改 浏览器 地址栏 中的 #号 锚点地址信息
    • #锚点变化了 会立即被 路由 监听到 (路由有封装onhashchange事件)
    • 之后 路由 会获取变化后的#锚点信息 (路由有封装window.location.hash)
    • 再之后 路由 根据#锚点信息找到对应 的组件 (在main.js中可知)
    • 最后组件是通过路由占位符rouer-view显示的
  • 重定向:

    使得一个路由地址A与另一个路由地址B联系起来,执行A的时候会跳转执行B

    • 语法:
    	var router = new VueRouter({
    	  routes:[
    	    // {path:'/', redirect:'跳转到的路由锚点信息'}
    	    {path:'/', redirect:'/home'},
    	    {path:'/home', component:Home},
    	    ……
    	  ]
    	})
    
    • 注意:
      • 不仅 "/" 可以被重定向配置,其他的普通路由锚点信息也可以设置
      • 重定向会使得路由再次发生调用请求
  • router-link-exact-active:

    • 路由严格匹配时才会有这个 class 属性,模糊匹配时该信息就没有了。

子路由

一般项目开发中,App.vue是根基组件(第1级别的),内部可以有具体业务组件(Home.vue Movie.vue Music.vue,它们是第2级别的),根据业务需要,业务组件内部还要做内容分级显示,这样就形成第3级别的业务组件,第3级别组件(香港音乐/台湾音乐/大陆音乐)的路由 是 第2级别组件路由 的子路由

  • 引入子路由的代码示例:
    	……
    	// 引入第3级别业务组件
    	import Hongkong from './components/yinyue/Hongkong'
    	import Taiwan from './components/yinyue/Taiwan'
    	import Dalu from './components/yinyue/Dalu'
    	……
    
    	var router = new VueRouter({
    	  routes: [
    	    { path: '/', redirect: '/hm' },
    	    { path: '/hm', component: Home },
    	    { path: '/mv', component: Movie },
    	    {
    	      path: '/ms',
    	      component: Music,
    	      children: [
    	        // 给Music创建子路由
    	        { path: '/ms/hk', component: Hongkong },
    	        { path: '/ms/tw', component: Taiwan },
    	        { path: '/ms/du', component: Dalu }
    	      ]
    	    }
    	  ]
    	})
    
  • 注意:
    • 要通过 children 关键字设置子路由
    • 第三级别组件对应的 切换按钮(router-link) 和 显示占位符(router-view) 需要在对应的第二级别组件Music.vue中设置
    • 第二级别组件对应的 切换按钮(router-link) 和 显示占位符(router-view) 需要在App.vue组件中设置

路由传参(动态路由)

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果

  • 声明路由参数:
    { path: '/dt/:xx/:yy/:zz', component: Detail }
  • 接收路由参数:
    	<标签>{{$route.params.xxx}}</标签>
    	<script>
    	new Vue({
    		this.$route.params.xxx
    	})
    	</script>
    
  • 注意:
    • 路由有参数,那么应用中要传递该参数
    • router-link 标签默认被编译为超链接 a 标签,可以设置 tag 属性,使其变为其他标签

编程式导航

一个路由被执行的过程就是一次导航

  • 导航种类:
    • 声明式导航:router-link 可以编译生成超链接按钮,单击按钮就切换路由并显示对应的组件,这个过程称为"声明式导航(静态)"
    • 编程式导航:有时由于业务需要,一个路由被切换执行并不方便通过声明式导航实现,相反是要通过程序代码的方式给实现出来,就是“编程式导航(动态)”
  • 编程式导航:
路由对象.push(锚点信息)	// 根据锚点执行指定的路由,最经常使用
路由对象.back()			// 后退
路由对象.forward()		// 前进
路由对象.go(数字整数)	// 根据"整形数字"参数做路由的,前进(大于0)、刷新(等于0)、后退(小于0)操作
// 与 BOM 浏览器对象相似
window.history.go()
window.history.back()
window.history.forward()
  • 路由对象:
    • main.js 中,就是 router
    • 在组件实例中就是 this.$router

路由守卫

每个路由在执行的时候都会经历一些“关卡”关卡可以做决定是否继续前进或执行其他路由或停止当前路由执行,关卡就是守卫,守卫有着一夫当关,万夫莫开的作用。

51555401458158.png

  • 使用场景:每个项目都要使用守卫,例如后台管理系统,很多组件页面要求只有处于登录状态(token)的用户才可以访问,判断是否登录就是通过守卫做的
  • 语法:router.beforeEach((to,from,next)=>{code})
    • router 是 new VueRouter() 得到的路由对象
    • to:是一个对象,保存这将要访问的路由相关参数
    • from:是一个对象,保存着离开的那个路由的相关参数
    • next:是一个回调函数,对后续的执行起着拦截或放行的作用,如果没有问题一定要执行**next()**方法,以进行后续操作,next()方法也可以通过传递路由信息实现其他组件的显示,例如,next('/login') 显示登陆组件,next(false) 停止当前路由执行

强制登录思路

主要思路:守卫 + sessionStorage + 路由 + 编程式导航

  • 保持用户登录状态:
    实际项目中:用户输入用户名、密码后,该账号信息需要给到服务器端做校验,校验成功 后台系统会给客户端浏览器传递一个秘钥信息 token [学员胸牌],表明当前账号已经登录系统,请客户端浏览器把token保存起来,后期每次向服务器端发起请求的时候,都要把这个token带着,以便服务器端识别当前账号ok的,因此浏览器中有token就是登录状态,没有就是退出状态
    1572678736831.png
(゚д゚)σ弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌弌⊃