v-model和sync
v-model
这也是一种传值的方式,但是我们平时用的不多,
v-model它是一个语法糖,它是 value和事件[input[默认]]的集合体
我们一下面的形式写的情况下,在child的$attrs中就会有value这个值并且数据也在里面,因为v-model是:value='值'
和input事件的结合体
此时child组件中就有了value这个值
我们在子组件中就可以接受value这个值
可以通过v-model事件直接修改数据
修改v-model的默认值
model: {
// 修改v-model中的绑定的属性名称,默认为value
prop: 'title',
// 修改v-model它的自定义事件的名称,默认为input
event: 'change'
},
sync
sync修饰符是一个语法糖,他是动态属性和update:属性名 事件 在vue3中得到了加强
定义全局组件并使用
- 首先我们创建一个全局组件的页面
- 然后我们在main.js入口文件中引入全局组件这样我们就可以咱任何地方使用这个全局组件了
例子:我们创建了一个loading的全局组件,并通过main.js引入,在全局使用
下面的图片是vue文件
弹框的设置组件
如果直接将dailog(弹窗)放入app节点中会打乱 其他节点的层级,所以我们再次创建了一个类似app节点的dailog组件
步骤:
1.创建一个dailog文件夹并创建index.js入口文件以及创建dailog.vue
2.再通过extend方法是dailog继承vue的属性和方法
3.new一个dailog并挂载到#dailog上
4.并在main.js文件中 引入dailog
5.把dailog设置成文vue中的成员方法.
6.在页面中使用this.$dailog()
就可以使用弹层
组件中的插槽
单个插槽
当子组件模板只有一个没有属性的插槽时,父组件传入的整个内容片段将插入到插槽所在的 DOM 位置,并替换掉插槽标签本身。
注意:
1.声明位置,用于在调用此组件时为双标签时,中间内容显示的位置
2.单个插槽:一个组件只能有一个默认组件
单个组件插槽的使用
如果在父组件中,没有在子组件的双标签中写入内容,就会默认显示子组件中slot
标签中的值,这里是默认
具名插槽
给插槽起个名字,
具名插槽,给slot添加一个名称,名称不能重复
vue2.6之前
给插槽一个name属性,在父组件中使用的时候,就可以根据name的属性值,使用slot=‘name的属性值’
就可以使用多个插槽,可以重复调用,并且依次进行显示
vue2.6及之后写法
vue2.6及之后写法,他只能写在template中,不能直接写在html标签上
并且2.6及以后的剧名插槽,重复调用,只会执行最后一次,但是之前的可以重复调用
使用以下语法
<template v-slot:header>
<h3>我是文章标题</h3>
</tempalte>
v-slot的简写#
<template #header>
<h3>我是文章标题</h3>
</tempalte>
作用域插槽
作用域插槽是一种特殊类型的插槽,用作一个 (能被传递数据的)可重用模板,来代替已经渲染好的元素。在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样
作用域插槽简单来说就是可以从被调用的组件中传出数据,传给本组件使用
在vue2.6及以后的版本中使用以下方式
在vue2.6之前的版本
// 将<template></template中的方式替换成为以下的方式
<button slot="del” slot-scope="index"@click="del(index)>删除</button>
路由
路由概念
路由
的本质就是一种对应关系,根据不同的URL请求,返回对应不同的资源。那么url地址和真实的资源之间就有一种对应的关系,就是路由。
SPA(Single Page Application)
单页面应用程序,基于前端路由而起:整个网站只有一个页面,通过监听地址栏中的变化事件,来通过Ajax局部更新内容信息显示、同时支持浏览器地址栏的前进和后退操作。
前端路由实现
前端浏览器路由也有2种模式:
- hash模式(锚链接)
- hash模式兼容性很强,刷新浏览器,页面还会存在
- hash模式,缺点:地址栏不优雅,有#存在,不利于seo,记忆困难
hash路由模式是这样的:http://xxx.abc.com/#/xx。 有带#号,后面就是hash值的变化。改变后面的hash值,它不会向服务器发出请求,因此也就不会刷新页面。并且每次hash值发生改变的时候,会触发hashchange事件。因此我们可以通过监听该事件,来知道hash值发生了哪些变化。
window.addEventListener('hashchange', ()=>{
// 通过 location.hash 获取到最新的 hash 值
console.log(location.hash);
});
- history模式
- history模式,兼容性较差,刷新页面,页面会404,需要服务器端配置支持
- 优点:地址栏更优雅,方便记忆,有利于有seo
HTML5的History API为浏览器的全局history对象增加了该扩展方法。它是一个浏览器(bom)的一个接口,在window对象中提供了onpopstate事件来监听历史栈的改变,只要历史栈有信息发生改变的话,就会触发该事件。
history.pushState({},title,url); // 向历史记录中追加一条记录
history.replaceState({},title,url); // 替换当前页在历史记录中的信息。
window.addEventListener('popstate', function(event) {
console.log(event)
})
==注:==浏览器地址没有#, 比如(http://localhost:3001/a); 它也一样不会刷新页面的。但是url地址会改变。但它在服务器没有配置的情况下,不能手动刷新,否则返回404页面
Vue Router
功能:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于Vue.js 过度系统的视图过度效果
- 细粒度的导航控制
- 带有自动激活的CSS class的来链接
- html5历史模式或hash模式,在ie9中自动降级
- 自定义的滚动条行为
vue-router路由模式
- hash:使用Url hash值来做路由。支持所有浏览器,包括不支持 HTML5 History的浏览器。
- history: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。
- abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。(现在基本上不用)
安装
首先 vue2对应的vue-router的版本为版本3所以安装
npm i -S vue-router@3
Vue Router的基本使用
vue-router只能在vue中使用,不能在其他框架中使用
第一步
1.首先我们创建一个router文件夹,在里面创建一个index.js
2.在js文件中引入Vue 和vue-router
3.然后以插件的方式添加vue-router
4.然后创建vue-router实例化,在实例化中,写清楚使用的路由模式和路由规则表
5.然后将new的vue-router实例向外暴漏
第二步
- 我们需要在入口文件main.js中将路由引入,并绑定到一块
第三步
在App.vue中写入router-view渲染路由组件
最后当我们访问 http://xxx.xxx.xxx:xxxx/home的时候就会将Home组件中的内容渲染出来
声明式导航
它就是先在页面中定义好跳转的路由规则,vueRouter中通过 router-link组件来完成,其实就相当于a标签
router-link声明式导航,他编译成html标签为a,在vue-router3版本中可以自定义设置
- to:stirng|{path:string,query:{},params:{}} 目标地址 ,如果使用对象需要使用动态属性 :to={}
- tag: 默认编译生成的为a,可以自定义
- activeClass:指定激活样式名称,默认名称为:router-link-active
编程式导航
编程式导航就是通过js来实现路由跳转
this.$router.push('/login'); //跳转到对应的路由,可以回退(字符串模式)
this.$router.push({ path:"/login" }); //对象模式
this.$router.replace({name:'user',params:{id:123}),跳转
this.$router.push({ path:"/login",query:{username:"jack"} }); //带有query数据的
this.$router.go( n );//n为数字 负数为回退 ,正数为前进
重定向和404
用户在访问地址A的时候,强制用户跳转到地址C ,从而展示特定的组件页面。
在路由规则表中
重定向就是当我们在地址栏中输入 http://localhost:8080时,会直接跳转到home路由下
404当我们路由表中没有该路由时,让网页报404,
创建一个404页面,因为路由表是从上往下的顺序一一对应的
当我们上面没有对应的界面是就会匹配 * (匹配所有),它对应的组件就是404
补充点:setTimeout/setInterval 在组件销毁时,还会继续运行,所以我们在组件销毁的时候,将这两个清除,提升性能
嵌套路由
嵌套路由最关键在于理解子级路由的概念:
比如我们有一个/users的路由,那么/users下面还可以添加子级路由,如:
/users/index、/users/add等等,这样的路由情形称之为嵌套路由。
我们需要在路由表中设置
routes=[
{
path:'/admin',
component:Admin,
children:[
{
path:'/user',
component:User
}
]
}
]
这样在配上组件就可以实现路由嵌套的赶脚了!!
注意
我们能需要在父路由中,添加上<router-view />
这个挂载点啊
动态路由匹配
所谓动态路由就是路由规则中有部分规则是动态变化的,不是固定的值,需要去匹配取出数据(即路由参数)。
动态路由一定要先定义,再使用
:名称
定义动态路由参数的方式,可以定义n个
{
path:'/detail/:nid'
}
定义的动态路由参数可以通过this.$router.params
就能获取动态路由的参数,上面的id 可以通过this.$router.params.nid
获取
这个动态路由参数也可以是可选的(可选路由参数),在后面添加?就可以设置成为可选路由参数
{
path:'/detail/:nid?'
}
query方式和params这两种方式的优缺点
query的方式,参数不用再路由中定义,更加方便不需要,不利于seo,不优雅,安全性低
params方式,更加的优雅,不会暴漏数据,安全性更高,需要先定义再使用
qurey可以通过this.router.query
获取query字符串
extend继承
继承只能继承
exports default
中的方法和属性,并不能继承模板
一般用于对已有插槽的功能方法和属性不满意,进行微调时,可以使用继承
图1
图2
图2继承了图1的方法和属性
异步组件
异步组件的特点:组件需要渲染(组件第一次显示)的时候进行加载渲染并缓存,缓存是以备下次访问
异步组件使用方式
key标签名:函数,此函数必须返回一个promise函数
import当函数使用返回的就是一个promise
component:{
child:()=>import('./components/child.vue')
}
自定义分包的文件名称
component:{
child:()=>import(/*webpackChunkName:'abc'*/,'./components/child.vue')
}
进一步的使用可以查看vue2文档中的自定义组件模块中的内容