Vue 学习笔记(二)(router 路由,插槽) 包含实例小demo

一、 插槽

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的特性

1、匿名插槽

<div id="app">    
	<!-- 这里的所有组件标签中嵌套的内容会替换掉slot  如果不传值 则使用 slot 中的默认值  -->      
	<alert-box>有bug发生</alert-box>
	   <alert-box>有一个警告</alert-box>
	   <alert-box></alert-box>  
</div>
 <script type="text/javascript">
	/*      组件插槽:父组件向子组件传递内容    */
	Vue.component('alert-box', {
		template: `<div>,
		<strong>ERROR:</strong> 
		# 当组件渲染的时候,这个 <slot> 元素将会被替换为“组件标签中嵌套的内容”。
		# 插槽内可以包含任何模板代码,包括 HTML  
		<slot>默认内容</slot>        
		</div>`
	});
	var vm = new Vue({
		el: '#app',
		data: {}
	});
</script> 

2、具名插槽

  • 具有名字的插槽
  • 使用 ‘name’属性绑定元素
  • 一个不带 name 的 < slot > 出口会带有隐含的名字“default”。
 <div id="app">
   <base-layout>      
   	<!-- 2、 通过slot属性来指定, 这个slot的值必须和下面slot组件得name值对应上,如果没有匹配到 则放到匿名的插槽中   -->
   	 <p slot='header'>标题信息</p>
   	<p>主要内容1</p>
   	<p>主要内容2</p>
   	<p slot='footer'>底部信息信息</p>
   </base-layout>
   <base-layout>      
   	<!-- 注意点:template临时的包裹标签终不会渲染到页面上-->      
   	<template slot='header'>        
   		<p>标题信息1</p>      
   		< p>标题信息2</p>    
   	</template>
   	<p>主要内容1</p>      
   	<p>主要内容2</p>      
   	<template slot='footer'>        
   		<p>底部信息信息1</p>        
   		<p>底部信息信息2</p>     
   	</template>    
   </base-layout>  
</div>  
<script type="text/javascript" src="js/vue.js"></script>  <script type="text/javascript">
   /*      具名插槽    */
   Vue.component('base-layout', {
   	template: `<div><header>
   	### 1、 使用 <slot> 中的 "name" 属性绑定元素 指定当前插槽的名字,
   	<slot name='header'></slot>
   	</header>          
   	<main>            
   	<slot></slot>          
   	</main>          
   	<footer>            
   	###  注意点:             
   	###  具名插槽的渲染顺序,完全取决于模板,而不是取决于父组件中元素的顺序          
   	<slot name='footer'>
   	</slot>          
   	</footer>        
   	</div>      `
   });
   var vm = new Vue({
   	el: '#app',
   	data: {}
   });
</script>

三、作用域插槽

自 2.6.0 起有所更新。已废弃的使用 slot-scope
  • 父组件对子组件加工处理
  • 既可以复用子组件的slot,又可以使slot内容不一致
有时让插槽内容能够访问子组件中才有的数据是很有用的。例如,设想一个带有如下模板的 <current-user> 组件:
<span>
  <slot>{{ user.lastName }}</slot>
</span>

我们可能想换掉备用内容,用名而非姓来显示。如下:

<current-user>
  {{ user.firstName }}
</current-user>

然而上述代码不会正常工作,因为只有 <current-user> 组件可以访问到 user 而我们提供的内容是在父级渲染的。

为了让 user 在父级的插槽内容中可用,我们可以将 user 作为 <slot> 元素的一个特性绑定上去:

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

绑定在 <slot> 元素上的特性被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

二、路由

1、路由的概念

路由的本质就是一种对应关系,比如说我们在url地址中输入我们要访问的url地址之后,浏览器要去请求这个url地址对应的资源。
那么url地址和真实的资源之间就有一种对应的关系,就是路由。

路由分为前端路由和后端路由
1).后端路由是由服务器端进行实现,并完成资源的分发
2).前端路由是依靠hash值(锚链接)的变化进行实现 

前端路由的基本概念:根据不同的事件来显示不同的页面内容,即事件与事件处理函数之间的对应关系
前端路由主要做的事情就是监听事件并分发执行事件处理函数

2、Vue Router简介

Vue Router的特性:
支持H5历史模式或者hash模式
支持嵌套路由
支持路由参数
支持编程式路由
支持命名路由
支持路由导航守卫
支持路由过渡动画特效
支持路由懒加载
支持路由滚动行为

3.Vue Router的使用步骤

A.导入js文件
<script src="lib/vue_2.5.22.js"></script>
<script src="lib/vue-router_3.0.2.js"></script>
B.添加路由链接:<router-link>是路由中提供的标签,默认会被渲染为a标签,to属性默认被渲染为href属性,
to属性的值会被渲染为#开头的hash地址
<router-link to="/user">User</router-link>
<router-link to="/login">Login</router-link>
C.添加路由填充位(路由占位符)
<router-view></router-view>
D.定义路由组件
var User = { template:"
This is User
"
} var Login = { template:"
This is Login
"
} E.配置路由规则并创建路由实例 var myRouter = new VueRouter({ //routes是路由规则数组 routes:[ //每一个路由规则都是一个对象,对象中至少包含path和component两个属性 //path表示 路由匹配的hash地址,component表示路由规则对应要展示的组件对象 {path:"/user",component:User}, {path:"/login",component:Login} ] }) F.将路由挂载到Vue实例中 new Vue({ el:"#app", //通过router属性挂载路由对象 router:myRouter })

借助实例理解一下(里面包含动画)

 <!-- 这里是引入vue的配置文件 -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <!-- 引入路由 -->
    <script src=" https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <title>路由的使用</title>
    <style>
        /* 设置路由的样式,设置高光亮节 */
        .router-link-active {
            background-color: palegreen;
            font-size: 32px;
        }
        .myRouterClass {
            background-color: peru;
            font-family: Arial, Helvetica, sans-serif;
        }
        .v-enter,.v-leave-to {
            opacity: 0;
            transform: translateY(250px);
        }
        .v-enter-active,.v-leave-active {
            transition: 1s;
        }
        /* 也可以使用自己定义的类名,不使用默认的 */
    </style>
</head>
<body>
    <div id="app">
        <!-- <a href="#/login">登录</a>
        <a href="#/register">注册</a> -->
        <!--router-link 默认渲染成一个a标签  -->
        <!-- <router-link to="/login">登录</router-link>
        <router-link to="/register">注册</router-link> -->
        <!-- router-link 也可以渲染成其他的标签,也是可以点击的 -->
        <router-link to="/login" tag="span">登录</router-link>
        <router-link to="/register" tag='button'>注册</router-link>
        <!-- router-view 是vue-router提供一个标签 ,使用它就能够使用路由规则匹配的组件-->
        <!-- 路由实现动画 -->
        <transition mode="out-in">
            <router-view></router-view>
        </transition>
    </div>
    <template id="login">
        <div>
            <h2>登录的组件</h2>
        </div>
    </template>
    <template id="register">
        <div>
            <h2>注册的组件</h2>
        </div>
    </template>
    <script>
        //定义一个组件对象
        var login = {
            template: "#login",
        }
        var register = {
            template: "#register"
        }
        //创建一个路由对象
        var routerObj = new VueRouter({
            //routers 表示路由的匹配规则
            routes: [
                //路由的重定向,指定默认的页面
                {
                    path: '/',
                    redirect: '/login'
                },
                {
                    //每个匹配规则都是一个对象,这个对象对象有两个属性,属性1是path,路由的监听路径,
                    //属性2 是Component,表示的是组件,这里的值一定组件的对象,不是组件的名字
                    path: '/login',
                    component: login
                },
                {
                    path: "/register",
                    component: register
                }
            ],
            // 自定义类名
            linkActiveClass: "myRouterClass"
        })
        var vm = new Vue({
            el: "#app",
            data: {
            },
            methods: {
            },
            components: {
                "login": login,
                "register": register
            },
            //将路由注册到vue实例中
            router: routerObj
        })
    </script>
</body>

小结

Vue Router的使用步骤还是比较清晰的,按照步骤一步一步就能完成路由操作
A.导入js文件
B.添加路由链接
C.添加路由占位符(最后路由展示的组件就会在占位符的位置显示)
D.定义路由组件
E.配置路由规则并创建路由实例
F.将路由挂载到Vue实例中

补充:
路由重定向:可以通过路由重定向为页面设置默认展示的组件
在路由规则中添加一条路由规则即可,如下:
var myRouter = new VueRouter({
    //routes是路由规则数组
    routes: [
        //path设置为/表示页面最初始的地址 / ,redirect表示要被重定向的新地址,设置为一个路由即可
        { path:"/",redirect:"/user"},
        { path: "/user", component: User },
        { path: "/login", component: Login }
    ]
})

4、嵌套路由,动态路由的实现方式

当我们进行路由的时候显示的组件中还有新的子级路由链接以及内容。
嵌套路由最关键的代码在于理解子级路由的概念:
比如我们有一个/login的路由
那么/login下面还可以添加子级路由,如:
/login/account
/login/phone

借助实例理解一下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="dist/vue.min.js"></script>
    <!-- 引入路由 -->
    <script src=" https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <title>路由的嵌套</title>
</head>
<body>
    <!-- 实现组件的嵌套 -->
    <div id="app">
        <router-link to='/wrap'>外部组件</router-link>
        <router-view></router-view>
    </div>
    <template id="login">
        <div>
            <h3>登录的组件</h3>
        </div>
    </template>
    <template id="register">
        <div>
            <h3>注册的组件</h3>
        </div>
    </template>
    <template id="wrap">
        <div>
            <h3>外部的组件</h3>
            <router-link to="/wrap/login" tag="span">登录</router-link>
            <router-link to="/wrap/register" tag='button'>注册</router-link>
            <router-view></router-view>
        </div>
    </template>
    <script>
        // 定义组件的模板
        var login = {
            template: '#login',
        }
        var register = {
            template: '#register'
        }
        var wrap = {
            template: '#wrap'
        }
        // 定义路由
        var router = new VueRouter({
            //这里配置路由的规则
            routes: [{
                path: '/wrap',
                component: wrap,
                children: [{
                        path: 'login',
                        component: login
                    },
                    {
                        path: 'register',
                        component: register
                    }
                ]
            }]
        })
        var vm = new Vue({
            el: "#app",
            data: {
            },
            components: {
                "login":login,
                "register":register,
                "wrap":wrap
            },
            router: router
        })
    </script>
</body>
</html>

5、路由传递参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>路由传递参数</title>
    <script src="dist/vue.min.js"></script>
    <!-- 引入路由 -->
    <script src=" https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
    <!-- 这个主要是实现路由的参数 -->
    <div id="app">
        <!-- 第一种传递参数的形式,直接在路径后面加上参数 -->
        <router-link to='/login?id=2&name=zhangshan'>登录</router-link>
        <router-link to='/register?id=3&name=lisi'>注册</router-link>
        <!-- 获取传递的参数 通过-->
        <p>通过路由传递的参数是:{{$route.query.id}}------{{$route.query.name}}</p>
        <!--使用路由 -->
        <router-view></router-view>
        <!-- 第二种传递参数的形式,直接字路径后面加上参数 -->
        <router-link to='/login/1'>登录</router-link>
        <router-link to='/register/2'>注册</router-link>
        <!-- 获取传递的参数 通过-->
        <p>通过路由传递的参数是:{{$route.params.id}}</p>
        <!--使用路由 -->
        <router-view></router-view>
    </div>
    <template id="login">
        <div>
            <h3>登录的组件</h3>
        </div>
    </template>
    <template id="register">
        <div>
            <h3>注册的组件</h3>
        </div>
    </template>
    <script>
        // 定义组件的模板
        var login = {
            template: '#login', 
        }
        var register = {
            template: '#register'
        }
        // 定义路由
        var router = new VueRouter({
            //这里配置路由的规则
            routes: [{
                    path: '/login/:id',
                    component: login
                },
                {
                    path: '/register/:id',
                    component: register
                }
            ]
            
        })
        var vm = new Vue({
            el: "#app",
            data: {},
            // vue 实例的周期函数
            created(){
                // 输出路由对象
               console.log(this.$route)
           },
            methods: {
            },
            components: {
                "login": login,
                "register": register
            },
            // 将路由注入的vue实例中
            router: router
        }) 
    </script>
</body>
</html>

6、动态匹配路由

var User = { template:"
用户:{{$route.params.id}}
"
} var myRouter = new VueRouter({ //routes是路由规则数组 routes: [ //通过/:参数名 的形式传递参数 { path: "/user/:id", component: User }, ] })

补充:

如果使用$route.params.id来获取路径传参的数据不够灵活。
1.我们可以通过props来接收参数
var User = { 
    props:["id"],
    template:"
用户:{{id}}
"
} var myRouter = new VueRouter({ //routes是路由规则数组 routes: [ //通过/:参数名 的形式传递参数 //如果props设置为true,route.params将会被设置为组件属性 { path: "/user/:id", component: User,props:true }, ] }) 2.还有一种情况,我们可以将props设置为对象,那么就直接将对象的数据传递给 组件进行使用 var User = { props:["username","pwd"], template:"
用户:{{username}}---{{pwd}}
"
} var myRouter = new VueRouter({ //routes是路由规则数组 routes: [ //通过/:参数名 的形式传递参数 //如果props设置为对象,则传递的是对象中的数据给组件 { path: "/user/:id", component: User,props:{username:"jack",pwd:123} }, ] }) 3.如果想要获取传递的参数值还想要获取传递的对象数据,那么props应该设置为 函数形式。 var User = { props:["username","pwd","id"], template:"
用户:{{id}} -> {{username}}---{{pwd}}
"
} var myRouter = new VueRouter({ //routes是路由规则数组 routes: [ //通过/:参数名 的形式传递参数 //如果props设置为函数,则通过函数的第一个参数获取路由对象 //并可以通过路由对象的params属性获取传递的参数 // { path: "/user/:id", component: User,props:(route)=>{ return {username:"jack",pwd:123,id:route.params.id} } }, ] })

7、命名路由以及编程式导航
A.命名路由:给路由取别名

var myRouter = new VueRouter({
    //routes是路由规则数组
    routes: [
        //通过name属性为路由添加一个别名
        { path: "/user/:id", component: User, name:"user"},
        
    ]
})

//添加了别名之后,可以使用别名进行跳转
<router-link to="/user">User</router-link>
<router-link :to="{ name:'user' , params: {id:123} }">User</router-link>

//还可以编程式导航
myRouter.push( { name:'user' , params: {id:123} } )

B.编程式导航

页面导航的两种方式:
A.声明式导航:通过点击链接的方式实现的导航
B.编程式导航:调用js的api方法实现导航

Vue-Router中常见的导航方式:
this.$router.push("hash地址");
this.$router.push("/login");
this.$router.push({ name:'user' , params: {id:123} });
this.$router.push({ path:"/login" });
this.$router.push({ path:"/login",query:{username:"jack"} });

this.$router.go( n );//n为数字,参考history.go
this.$router.go( -1 );

VUE 学习笔记一

你可能感兴趣的:(VUE,vue)