Vue听课笔记(Vue2~Vue3)-3

一、指令

1.1、指令写法

指令:对于底层DOM操作的一种封装

封装在指令里面可以进行复用

<div id="box">
	<div v-hello=" 'red' "></div>
<div>
<script>
	//自定义指令
	//inserted第一个参数得到的就是这个元素,第二个参数是元素对象
	Vue.directive("hello",{
		//指令的生命周期
		inserted(el,binding){
		//第一次插入到父节点是触发
			el.style.background =binding。value
	},
	update(){
	}	
})
	new Vue ({
		el="box"
	})
</script>
  • 自定义指令使用Vue.directive("指令名",{})在定义

1.2、指令应用

  1. 指令在dom创建好之后就会触发
  2. 有时数据引入我们的文件中时,难以判断dom创建的时间
  3. 我们可以通过给引入数据的元素上加上自定义指令
  4. 当某一个数据引入,dom节点创造好了以后就可以执行某一段行为

1.3、指令补充&nextTick

简写指令

Vue.directive("hello",(el,binding)=>{
	el.style.background=binding.value
})

指令生命周期:

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted∶被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。
  • upiate :所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前。指令的值
    能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新(详
    的钩子函数参数见下)。
  • componentUpdated∶指令所在组件的VNode及其子VNode全部更新后调用。
  • unbind(销毁) :只调用一次,指令与元素解绑时调用。

在Vue3中,指令的生命周期发生变化

  • Vue3中的生命周期与组件生命周期大致相同,仅仅没有了beforeCreate

nextTick

  • updated执行的都完,只执行一次
  • 不能复用只能独自使用
this.$nextTick(()=>{

},2000)

二、Vue-cli

2.1、Vue-cli创建项目

在原来的文件中写Vue

  • 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复
  • 字符串模板 (String templates) 缺乏语法高亮,在 HTML 有多行的时候,需要用到丑陋的 \
  • 不支持 CSS (No CSS support) 意味着当 HTML 和 JavaScript 组件化时,CSS 明显被遗漏
  • 没有构建步骤 (No build step) 限制只能使用 HTML 和 ES5 JavaScript,而不能使用预处理器,如 Pug (formerly Jade) 和 Babel

可以使用.vue文件

文件扩展名为 .vue 的 single-file components (单文件组件) 为以上所有问题提供了解决方法,并且还可以使用 webpack 或 Browserify 等构建工具。

在这里插入图片描述

  • 不过.vue文件,浏览器不认识

有了 .vue 组件,我们就进入了高级 JavaScript 应用领域。如果你没有准备好的话,意味着还需要学会使用一些附加的工具:

  • Node Package Manager (NPM):阅读 Getting Started guide 中关于如何从注册地 (registry) 获取包的章节。

  • Modern JavaScript with ES2015/16:阅读 Babel 的 Learn ES2015 guide。你不需要立刻记住每一个方法,但是你可以保留这个页面以便后期参考。

在你花一天时间了解这些资源之后,我们建议你参考 Vue CLI 3。只要遵循指示,你就能很快地运行一个带有 .vue 组件、ES2015webpack热重载 (hot-reloading) 的 Vue 项目!

2.2、启动流程&入口文件

  • 可以在packgae.json文件中直接运行脚本
  • 或者在packgae.json文件的集成终端直接运行
    • 使用npm run serve 或着npm start来启动
  • 通过App.vue文件进入

2.3、eslint修复

  • 在使用CLI时,语法规则非常苛刻,因此会出现许多错误

解决方案:

  1. 在集成终端使用npm run lint
    • 被赋值但没使用这种错误,这个方法无法修复
  2. vscode自动修复eslint
    • 安装eslint插件,并启用
    • 有时这个插件用不了,可以先将其关闭,最后写完代码在启用,修复文件
  3. 先将其关闭,最后写完代码在启用,修复文件
    • vue.config.js文件中添加以下代码
    module.export = {
    	lintOnSave: false//暂时关闭代码格式检测
    }
    
    • 在写完代码以后在集成终端使用npm run lint

2.4、单文件组件-注册

  1. 内容写在template标签下
  2. 不能有两个相同的元素 兄弟标签
  3. js部分必须使用ES6导出规范export default{}
  4. data使用函数式的写法
  5. 可以使用style标签写css,不需要写道行内
  6. 如果还需要在文件里引入子组件
    • 先在外面创建一个.vue文件在里面写组件的内容
    • 在将这个组件 通过 import 子组件名 from '子组件文件的地址'引入
    • 全局写法:
      • 还需要再父文件中注册组件 Vue.component('子组件名' , 子组件文件名)
      • 再需要使用 import Vue from 'vue'来引入一次
    • 局部写法:
      • components:{ 子组件名 }

2.5、单文件组件-通信

  • 父子通信和以前的写法相同
  • 插槽也能使用
  • 子组件的样式会被父组件的影响,插入样式时,先封装子组件的样式再封装父组件的样式,后封装的会影响前封装的
    • 只需要在子组件的style标签中加scoped就可以防止被覆盖
  • style加上long:"scss" 就能使用scss的写法

2.6、单文件组件-生命周期

  • 与以前得生命周期一样
  • 也可以从其他文件从在生命周期得阶段引入到文件
  • 也可以引入axios文件来使用axios方法
    • 需要在终端写npm i --save axios

2.7、单文件组件-指令与过滤器

  • 指令

    • 先引入 import Vue from 'vue'
    • 接着指令的方法与原来相同
  • 过滤器

    • 先在文件中使用Vue.filter("过滤器名称",()=>{需要修改的操作})声明即可用

2.8、反向代理&别名

在这里插入图片描述
反向代理需要在vue.config.js文件中加入一段代码

devServer: {
	port : 8000//随便改端口号
	proxy : {
		'/api' : {
		target: 'https ://*.*.com' ,//需要代理的网站
		host: '*.*.com ' ,
		changeOrigin :true,
		pathRewrite:{
				'自定义接口的名字':''//将自定义接口的名字转为空字符串
			}
		}
	}
}
  • 在接口前端自定义一个名字是为了防止引入多个网址时'/api'相同

在vue文件中 @ 为别名,永远指向src绝对路径,在src下面引入文件时,只需要加@就能引入里面文件的绝对路径

三、路由

3.1、spa&路由引入

SPA概念

单页面应用(SinglePage Web Application ,SPA)多页面应用(MultiPage Application, MPA)
组成一个外壳页面和多个页面片段组成多个完整页面构成
资源公共(css js)公用,只需要在外壳部分加载不共用,每个页面都需要加载
刷新方式
url模式a.com/#/pageone a.com/#/pagetwoa.com/pageone.html a.com/pagetwo.html
用户体验页面片段间的切换快,用户体验良好页面切换加载缓慢,流畅度不够,用户体验比较差
转场动画容易实现无法实现
数据传递容易依赖url传参、或者cookie .localStorage等
搜索引擎优化(SEO)需要单独方案,实现比较困难,不利于SEO检索 可利用服务器端渲染(SSR)优化实现方法简易
试用范围高要求的体验度,追求界面流畅的应用适用于追求高度支持搜索引擎的应用
开发成本较高,常常需要借助专业的框架较低,但页面重复代码多
维护成本相对容易相对复杂

vue-router

  • 根据不同的路径加载到不同的页面
    在这里插入图片描述

3.2、一级路由

  1. main.js先引入router文件,并且将给文件渲染

  2. 再创建几个组件

  3. 在路由文件(index.js)中引入组件

    import 组件名称 from '组件相对地址'
    Vue.ues(VueRouter)//注册路由插件,两个全局router-view router-link
    
    
    const routes =[
    {
    	path:'/组件名',
    	component:组件名称
    }//有几个组件就写几次
    ]
    
    const router =new VueRouter({
    	routes
    })
    
    export default router
    
  4. 在根文件中加上router-view标签相当于slot标签

3.3、重定向

  • 就是希望打开页面是就会指向我们希望出现的组件页面
const routes =[
	{
		path:'/组件名',
		component:组件名称
	},
	{
	path:'/',
	redirection:'/组件名'
	}
	]

这样操作即可

  • 如果想在输入一个未定义的组件,依旧是跳转到我们希望出现的组件页面
const routes =[
	{
		path:'*',
		component:组件名称
	},
	{
	path:'*',
	redirection:'/组件名'
	}
	]

3.4、声明式导航

  1. 第一种方法

    • 使用<router-link>标签进行跳转组件(使用to="组件绝对地址")时,会自动给跳转的组件加上class,可以通过给这个class加上高亮属性,来使得点击某个图标跳转之后可以使得该图标保持高亮
    • 并且可以在这个标签中自定义class属性,通过active-class="class名称"的方式添加
  2. 第二种方法

    • 使用插槽的方式使用<router-link>标签进行跳转组件(使用to="组件绝对地址"),在这个标片中间再加一个<li>标签,在存放组件
    • <router-link>标签中加custom v-slot="{navigate,isActive}"属性
    • <li>标签上@事件="navigate"属性
    • isActive是判断是否在当前组件上,是的话就是true,否则是false,可以通过这一特性,添加动态class
      • :class="isActive?自定义属性:''"

3.5、嵌套路由

  • 在父组件中再嵌套一个路由的方法
import 组件名称 from '组件相对地址'
import 子组件名称 from '子组件相对地址'
	Vue.ues(VueRouter)//注册路由插件,两个全局router-view router-link
	
	const routes =[
	{
		path:'/组件名',
		component:组件名称,
		children:[
			{
				path:'/组件名/子组件名',
				component:子组件名称,
			}
		]
	}
	]
  • 重定向使其跳转到子组件
const routes =[
	{
		path:'/组件名',
		component:组件名称,
		children:[
			{
				path:'/组件名/子组件名',
				component:子组件名称,
			}
			{
				path:'*',
				redirect:'/组件名/子组件名'
			}
		]
	}
	]
  • 有些路径上时二级关系,但实际上是兄弟关系

3.6、编程式导航

  1. 给值赋上事件,通过执行某个函数触发location.href = '#/组件名',使其跳转到那个组件页面
  2. 给值赋上事件,通过执行某个函数触发this.$router.push('/组件名'),使其跳转到那个组件页面

3.7、动态路由

在这里插入图片描述

  • 在路由文件中设置一个动态路由

    const routes =[
    	{
    		path:'/组件名/:id',//通过id来获取组件
    		component:组件名称
    	}
    	]
    
  • 在改组件中设置this.$route.params.id来获取id值,发送请求到后端

  • 在根组件中设置点击事件后,设置一个函数,参数就是id,通过this.$router.push(/组件名称/${id})的方式,使得创建一个组件

3.8、路由命名

  • 给路由组件加一个name属性
const routes =[
		{
			name:'asd'
			path:'/组件名/:id',//通过id来获取组件
			component:组件名称
		}
		]
  • 然后通过name进行跳转
函数名(参数){
this.$router.push({
	name:'asd',
	params:{
		id:参数
	}
})
}

3.9、路由模式

  • 如果不想要地址出现#,可以使用history模式
    • 在分享时有些网站会加上#,使用这种模式不影响
    • 加入mode:'history'即可
const router =new VueRouter({
		mode:'history'
		routes
	})
  • 弊端

    • 不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问http: //oursite.com/user/id就会返回404,这就不好看了。
  • 如果出现了问题,就使用npm run build生成了dist文件夹,仍给后端

3.10、全局路由拦截

  • 在一些页面不授权不给进入

  • 可以给路由加上一个meta属性,在里面自定义一个属性,自定义属性值为true

meta:{
	isASD:true
}
router.beforeEach((to,from,next)=>{
	if(某几个需要授权的路由/*to.meta.isASD==>通过判断这个值是不是true来进行判断是否通过*/){
		//判断本地储存中是否有token字段
		if(localStorage.getItem('token')/*授权通过*/){
			next()
		}else{
			next('/login')
		}
	}else{
		next()	
	}
})
  • to:Route:即将要进入的目标路由对象
  • from:Route:当前导航正要离开的路由

3.11、局部路由拦截

router.beforeEach((to,from,next)=>{
	if(某几个需要授权的路由/*to.meta.isASD==>通过判断这个值是不是true来进行判断是否通过*/){
		//判断本地储存中是否有token字段
		if(localStorage.getItem('token')/*授权通过*/){
			next()
		}else{
			next('/login')
		}
	}else{
		next({
			path:'/login',
			query:{redirect:to.fullPath}
		})
	}
})

跳转路由的代码

this.$router.push(this.$route.query.redirect)
  1. 路由独享的守卫
    • 将以下代码写道路由里面
beforeEach((to,from,next)=>{}
  1. 组件内的守卫
    • 将以下代码写到组件内
// 路由生命周期
beforeRouteEach((to,from,next)=>{
//在渲染该组件的对应路由被·confirm·前调用·
//不!能!获取组件实例`this`
//因为当守卫执行前,组件实例还没被创建
}

3.12、局部懒加载

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。

  • 删除原先导入的路由组件 即
import 组件名称 from '组件相对地址'

再在组件内部替换一条语句

{
		path:'/组件名',
		component:()=>import('组件相对地址')//懒加载
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值