1.渲染函数
render(针对的是组件模板)
组件模板:let myA={
template:``
//渲染函数 参数createElement是一个函数 创建节点的函数
render(createElement){ createElement() }
}
### js代码
// 创建组件
let myA={
data(){
return {
}
},
props:{
level:{
type:Number,
required:true
}
},
// render(createElement){
// return createElement('div',{
// attrs:{
// id:"one",
// title:'two'
// }
// },'文本')
// },
render(createElement){
return createElement(
'h'+this.level,
this.$slots.default
)
},
template:`
<div>
hello
</div>
`
}
Vue.component('my-a',myA)
new Vue({
el:'#app',
data:{
}
})
### html代码
<div id="app" >
<my-a :level='1'>
<template #default>
<div>
default
</div>
</template>
<template #header>
<div>
header
</div>
</template>
</my-a>
</div>
plugin
插件通常用来为 Vue 添加全局功能。Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:
### html代码
<div id="app">
{{msg}} {{msg | myFilter}}
</div>
### js代码
<script>
// 声明插件对象
let myPlugin = {
//install方法在Vue.use(myPlugin)会运行
install(Vue, options) {
// console.log(1);
// 提供一些静态属性或者方法
Vue.isVue = () => { }
// 提供一些原型属性或者方法
Vue.prototype.$sayVue = () => { }
// 全局注册(组件/过滤器/指令/混入)
Vue.filter('myFilter', (data) => {
return data.toUpperCase()
})
}
};
// console.log(Vue.isVue);
// 使用插件,在new Vue之前使用
Vue.use(myPlugin);
// console.log(Vue.isVue);
// Object.prototype.say = () => { }
// let obj = new Object()
// obj.say();
let vm = new Vue({
el: '#app',
data: {
msg: 'hello'
},
methods: {}
})
// console.log(vm.$sayVue);
</script>
2.路由机制
vue-router是vue的一个插件,用来提供路由功能。通过路由的改变可以动态加载组件,达到开发单页面程序的目的。
安装
方式一 : CDN引入
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.0-beta.7/vue.cjs.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/4.0.10/vue-router.cjs.js"></script>
方式二:本地引入
<script src='vue.js'></script>
<script src='vue-router.js'></script>
方式三 : cnpm下载
cnpm install vue-router
使用
在html文件中使用时需要引入vueRouter(先引入vue.js,在引入vueRouter)
### js代码
<script>
// 声明组件
let myA = {
template: `
<div>A组件</div>
`
};
let myB = {
template: `
<div>B组件</div>
`
};
// 1.定义路由对象数组 route路由对象 router路由器对象 routes路由对象组
let routes = [{
path: '/a',
component: myA
}, {
path: '/b',
component: myB
}];
// 2.创建路由器对象 声明路由器实例对象
let router = new VueRouter({
// 声明配置路由对象
routes: routes
})
// 3.注册路由器对象
new Vue({
el: '#app',
// 将路由实例对象导入vue实例,相当于router:router,在此使用简写形式
router,
components: {
'my-a': myA,
'my-b': myB
},
data: {
msg: 'hello'
},
})
</script>
### html代码
<div id="app">
{{msg}}
<!-- 4.实现路由切换,router-link的本质是创建a标签 -->
<div>
<router-link to="/a">去A路由</router-link>
<router-link to="/b">去B路由</router-link>
<a href="#/a">a标签路由去A</a>
</div>
<div>
<!-- 路由组件显示的位置 路由出口,将匹配到的路由组件,渲染到此-->
<router-view></router-view>
</div>
</div>
let routes=[
{
path:"/",
//路由名称
name:"aRoute",
//别名 重命名
alias:'/aa',
//重定向
// redirect:'/a'
redirect:{name:'aRoute'}
}
]
3.动态路由匹配
需要把某种模式匹配到的所有路由,全部映射到同一个组件。
例如 : 有一个user组件,对于所有id不同的用户,都要使用这个组件来渲染,那么可以在vue-router的路由路径中使用动态路径参数来达到这个效果。
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch $route 对象,或者使用组件内部的导航守卫
<div id="app">
{{msg}}
<!-- 4.使用路由 -->
<div>
<router-link to="/user/id/1/username/zhangsan">去A路由</router-link>
</div>
<div>
<!-- 路由组件显示的位置 -->
<router-view></router-view>
</div>
</div>
// 声明组件
let myA = {
data() {
return {
id: null,
username: ''
}
},
template: `
<div>A组件{{id}}--{{username}}</div>
`,
/* created() {
alert(1);
// console.log(this.$route);
this.id = this.$route.params.id;
this.username = this.$route.params.username;
} */
//监听
/* watch: {
msg(newValue, oldValue) { },
$route(to, from) {
// to是新路由 from是旧路由
// console.log(to, from);
this.id = to.params.id;
this.username = to.params.username;
}
} */
// 监听路由发生变化 路由守卫
beforeRouteUpdate(to, from, next) {
// console.log(to.params);
this.id = to.params.id;
this.username = to.params.username;
// 继续
// next();
// 阻断
// next(false)
}
};
let myB = {
template: `
<div>B组件</div>
`
};
// 1.定义路由对象数组 route路由对象 router路由器对象 routes路由对象组
let routes = [{
// 动态路由
// /user/id/1/username/zhangsan
// /user/id/2/username/lisi
path: '/user/id/:id/username/:username',
component: myA
}];
// 2.创建路由器对象
let router = new VueRouter({
routes: routes
})
// 3.注册路由器对象
new Vue({
el: '#app',
router: router,
components: {
'my-a': myA,
'my-b': myB
},
data: {
msg: 'hello'
},
methods: {}
})
4.嵌套路由
实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件 :
### js代码
<script>
// 创建一个组件
let user={
template:`
<div>
<router-link to='/userChild1'>子组件1</router-link>
<router-link to='/userChild2'>子组件2</router-link>
<router-view ></router-view>
</div>
`
}
let manager={
template:`
<div>管理员</div>
`
}
let userChild1={
template:`
<div>子组件1</div>
`
}
let userChild2={
template:`
<div>子组件2</div>
`
}
let routes=[{
path:'/manager',
component:manager
},{
path:'/user',
component:user,
redirect:'/userChild1',
children:[{
path:"/userChild1",
component:userChild1
},{
path:"/userChild2",
component:userChild2
}]
}];
let router=new VueRouter({
routes
})
new Vue({
el:"#app",
router,
data:{
}
})
### html代码
<div id="app">
<router-link to='user'>去用户</router-link>
<router-link to='manager'>去管理员</router-link>
<router-view></router-view>
</div>
5.编程式导航
除了使用 <router-link>
创建 a 标签来定义导航链接,还可以借助 router 的实例方法,通过编写代码来实现。this.$router.push()跳转到指定路由,会向history栈添加一个新的记录,当用户点击浏览器回退按钮的时候,可以回到跳转前的url。
### js代码
<script>
// 创建A B组件
let myA={
data(){
return {
}
},
template:`
<div>
A组件
</div>
`,
created(){
console.log(this.$route)
},
}
let myB={
data(){
return {
}
},
template:`
<div>
B组件
</div>
`
};
// 创建路由组件对象数组 routes router路由器对象 route路由对象
let routes=[
{
path:"/a",
component:myA,
name:'mya'
},
{
path:"/b",
component:myB,
// 路由独享守卫
}
];
// 创建路由器对象实例
let router=new VueRouter({
// 配置路由对象组
routes
})
new Vue({
el:'#app',
data:{
},
// 3.注册路由
router,
components:{
'my-a':myA,
'my-b':myB
},
methods:{
toPath(){
this.$router.push({
// 有效
path:"/a?id=1",
// 有效
// query:{id:1},
// // 无效
// params:{name:"terry"}
})
},
toPath1(){
this.$router.push({
name:'mya',
query:{id:1},
// 参数是一次性携带刷新页面 params失效
params:{
name:"terry"
}
})
}
}
})
</script>
### html代码
<div id="app">
<router-link to='/a'>去a路由</router-link>
<router-link to='/b'>去b路由</router-link>
<a href="#/a/2">去a路由</a>
<button @click="$router.push('/a')">跳转到A路由</button>
<button @click="$router.push('a')">跳转到A2路由</button>
<button @click="toPath">跳转到A3路由</button>
<button @click="toPath1">跳转到A4路由</button>
<router-view></router-view>
</div>
this.$router.go()这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步。
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,则会报错
router.go(-100)
router.go(100)
6.路由组件传参
路由传递是指,从A页面跳转到B页面时,将A页面中的变量传递给B页面使用,传递参数的方式有两种 :
path-query传参
使用path与query结合的方式传递参数时,参数会被拼接在浏览器地址栏中,并且刷新页面后数据也不会丢失。
name-params传参
### js代码
<script>
let user = {
template:`
<div @click="userHandler">普通用户,点击此处可跳转至管理员页面</div>
`,
data() {
return {
list:"hello",
obj:{
name:'tom',
age:3
}
}
},
methods: {
userHandler() {
// 跳转
this.$router.push({
path:'/manager',
query:{
list:this.list,
obj:JSON.stringify(this.obj)
}
})
}
},
}
let manager = {
template:`
<div>管理员 {{$route.query.list}} {{$route.query.obj}}</div>
`
}
let router = new VueRouter({
routes:[{
path:'/user',
component:user
},{
path:'/manager',
component:manager
}]
})
new Vue ({
el:"#app",
router
})
</script>
### html代码
<div id="app">
<router-link to="/user">user</router-link>
<router-link to="/manager">manager</router-link>
<router-view></router-view>
</div>
name-params传参
### js代码
<script>
let user = {
template:`
<div @click="userHandler">普通用户,点击此处可跳转至管理员页面</div>
`,
data() {
return {
list:"hello",
obj:{
name:'tom',
age:3
}
}
},
methods: {
userHandler() {
// 跳转
this.$router.push({
name:'manager',
params:{
list:this.list,
obj:JSON.stringify(this.obj)
}
})
}
},
}
let manager = {
template:`
<div>管理员 {{$route.params.list}} {{$route.params.obj}}</div>
`
}
let router = new VueRouter({
routes:[{
path:'/user',
component:user,
name:'user'
},{
path:'/manager',
component:manager,
name:'manager'
}]
})
new Vue ({
el:"#app",
router
})
</script>
### html代码
<div id="app">
<router-link to="/user">user</router-link>
<router-link to="/manager">manager</router-link>
<router-view></router-view>
</div>
导航守卫 --路由的改变会触发导航守卫
全局守卫
全局守卫有全局前置守卫、全局后置守卫。
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })
const router = new VueRouter({ ... }) router.afterEach((to, from) => { // ... })
路由独享守卫
组件内守卫
beforeRouteEnter: (to, from, next) => { //不!能!获取组件实例 this
} beforeRouteUpdate (to, from, next) {//在当前路由改变,但是该组件被复用时调用,可访问this} beforeRouteLeave (to, from, next) {//导航离开该组件的对应路由时调用,可访问this}
### 全局前置守卫
let router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
### 全局后置钩子
let router = new VueRouter({ ... })
router.afterEach((to, from) => {
// ...
})
全局守卫参数说明:
* to: Route : 即将要进入的目标路由对象
* from: Route : 当前导航正要离开的路由
* next: Function : 一定要调用该方法来**resolve**这个钩子。执行效果依赖 next 方法的调用参数
路由独享守卫
可以在路由配置上直接定义 beforeEnter 守卫,该守卫与全局前置守卫的方法参数是一样的 :
let router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
组件内的守卫
// 组件内的守卫
beforeRouteEnter(to,from,next){
// this--window
console.log(this,'beforeRouteEnter');
next()
},
beforeRouteUpdate(to,from,next){
//this--组件实例
console.log(this,'beforeRouteUpdate');
next()
},
beforeRouteLeave(to,from,next){
//this--组件实例
console.log(this,'beforERouteLeave')
}