ref
就是在页面进行dom选择
1.使用ref绑定你要设置的dom
2.使用this.$refs.你要查找的ref名字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <template> <div>
<h1 ref="h">ref</h1> <button @click="fun()">点我修改上面的颜色</button> </div> </template>
<script> export default { methods:{ fun(){
this.$refs.h.style.color="yellow" } } } </script>
<style>
</style>
|
ref 绑定到dom之上
可以进行dom元素的查找
ref绑定到组件之上
得到子组件的所有数据
vue中父组件如何触发子组件的方法?
ref 因为ref绑定到组件之上 可以得到他绑定的所有信息
路由
完成单页面应用(spa)单页面应用表示的不是只能显示一个页面 而是只有一个html作为显示的基础
spa可以让用户在切换页面的时候 没有切换过程的割裂感以及在切换过去之后那种白屏的感觉提升用户体验 让我们的web端应用更加接近于原生app的那种丝滑的感觉
基本路由创建–脚手架方式
1.创建项目的时候 需要选中router项 即可
2.会发现在创建好的项目中src文件夹下多了两个文件夹 分别是 router(配置路由的) 和 views( 用来容纳页面的文件夹)
3.创建页面
4.配置路由页面 router下的index.js中配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| import Vue from 'vue' import VueRouter from 'vue-router'
import Home from '../views/Home.vue' import About from '../views/About.vue' import User from '../views/user.vue' import Phone from '../views/phone.vue'
Vue.use(VueRouter)
const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/user', name: 'user', component: User }, { path: '/phone', name: 'phone', component: Phone }, ]
const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes })
export default router
|
5 设置路由出口(默认情况下脚手架帮我们写了)app.vue
1 2 3 4 5 6 7 8 9 10 11
| <template> <div id="app"> <router-view/> </div> </template>
<style>
</style>
|
路由导航
声明式导航—-router-link
标签的方式跳转页面
你要在页面显示的内容
router-link最终在浏览器端会被解析成a标签的 但是 我们不能使用a标签
router-link动态样式类
vue路由中会自动给 当前的路由导航添加一个 router-link-active的类名 通过这个类名 可以添加相关的选中样式
但是如果路由的规则上有 / 这种默认路径 那么每次都会匹配上 所以不要有/
编程式导航
使用js的方式跳转页面
this.$router.push(“/你要去的路径”) 跳转
this.$router.replace(‘/你要去的路径’) 替换
this.$router.go() 正数 前进 负数 后退
重定向–redirect
重新定位方向
写在路由规则上 并且放到规则的最下面
{
path:”/“,
redirect:”/home”
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| import Vue from 'vue' import VueRouter from 'vue-router'
import Home from '../views/Home.vue' import About from '../views/About.vue' import User from '../views/user.vue' import Phone from '../views/phone.vue'
Vue.use(VueRouter)
const routes = [ { path: '/home', name: 'Home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/user', name: 'user', component: User }, { path: '/phone', name: 'phone', component: Phone },
{ path:"/", redirect:"/home" } ]
const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes })
export default router
|
404页面
需要在用户跳转到错误路径的时候 有个错误提示页面
1.新建一个404页面
2.配置规则 一定要放到最下面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| import Vue from 'vue' import VueRouter from 'vue-router'
import Home from '../views/Home.vue' import About from '../views/About.vue' import User from '../views/user.vue' import Phone from '../views/phone.vue' import No from '../views/no.vue'
Vue.use(VueRouter)
const routes = [ { path: '/home', name: 'Home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/user', name: 'user', component: User }, { path: '/phone', name: 'phone', component: Phone },
{ path:"/", redirect:"/home" },
{ path: '*', name: 'no', component: No }, ]
const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes })
export default router
|
多级/二级路由–children
就是在一个路由页面中 嵌套另外一个路由的 关系
1.写页面
2.配置二级路由的规则(二级路由的规则需要在对应以及路由规则中进行配置)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| import Vue from 'vue' import VueRouter from 'vue-router'
import Home from '../views/Home.vue' import About from '../views/About.vue' import User from '../views/user.vue' import Phone from '../views/phone.vue' import No from '../views/no.vue'
Vue.use(VueRouter)
const routes = [ { path: '/home', name: 'Home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/user', name: 'user', component: User }, { path: '/phone', name: 'phone', component: Phone, children:[ { path: '/era', name: 'era', component: Era }, { path: '/erc', name: 'erc', component: Erc }, { path: '/erd', name: 'erd', component: Erd }, ] },
{ path:"/", redirect:"/home" },
{ path: '*', name: 'no', component: No }, ]
const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes })
export default router
|
3.千万不要忘了设置二级路由的出口 router-view
设置在你配置的他爸的路由页面中
扩展—多级路由配置路径问题
大家会发现 上面我们二级路由的配置 在规则中 path:”/二级路由” 会发现带了个 / 那么 在设置导航去二级路由的时候 我们在导航的路径中只需要写 /二级路由.
1 2 3 4 5 6 7 8 9 10 11
| { path: '/erd', //路径带 / name: 'erd', component: Erd }, 页面的导航 /二级路由 <router-link to="/era">era</router-link> <router-link to="/erc">erc</router-link> <router-link to="/erd">erd</router-link>
|
另外一种写法
在配置二级路由的时候 path 不加/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| children:[ { path: 'era', name: 'era', component: Era }, { path: 'erc', name: 'erc', component: Erc }, { path: 'erd', name: 'erd', component: Erd },
|
那么路由导航的路径就必须是 /一级路由/二级路由
1 2 3
| <router-link to="/phone/era">era</router-link> <router-link to="/phone/erc">erc</router-link> <router-link to="/phone/erd">erd</router-link>
|
路由模式
hash模式
默认值
history模式
区别 |
hash |
history |
url展示形态上 |
带# |
不带# |
兼容性 |
兼容性好 |
是h5新增特性 所以低版本浏览器不兼容 |
刷新页面 |
正常 |
上线之后会丢失 需要后台配置重定向 |
路由传参/动态路由匹配
就是把数据从一个页面传递到另外一个页面(新闻列表页面用户点击某个新闻标题 跳转到对应的详情页面)
params方式
1.在需要接收数据的路由规则上path中配置接收参数/:xxx
1 2 3 4 5 6
| { path: '/shop/:xiaoming', name: 'shop', component: Shop },
|
2.发送
声明式发送
1 2 3 4 5 6 7 8 9 10 11 12 13
| <template> <div> <Bb/> 新闻列表
<router-link :to="{name:'shop',params:{xiaoming:'我是user的数据么么哒!'}}"> 点我把数据传递到shop页面 </router-link> </div> </template>
|
编程式发送
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <template> <div> <Bb/> 新闻列表
<router-link :to="{name:'shop',params:{xiaoming:'我是user的数据么么哒!'}}"> 点我把数据传递到shop页面 </router-link> <button @click="fun()">点我传递数据到user</button> </div> </template>
<script> export default { methods:{ fun(){ this.$router.push({name:'shop', params:{xiaoming:'我是我是编程式user的数据么么哒!'}}) } } } </script>
<style>
</style>
|
3.接收
this.$route.params.xxx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <template> <div> <Bb/> 新闻详情----{{this.$route.params.xiaoming}} </div> </template>
<script> export default {
} </script>
<style>
</style>
|
query方式
1.发送
编程式发送数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <template> <div> <Bb/> phome <h1>query传递数据</h1>
<button @click="fun()">点我使用query进行数据传递</button> </div> </template>
<script> export default { methods:{ fun(){ this.$router.push({name:"about", query:{xiaobai:'我是编程试query方式传参'}}) } } } </script>
<style>
</style>
|
声明式发送数据
router-link :to=”{name:”about”,query:{xiaobai:’我是编程试query方式传参’}}”
query还有第二种发送数据的方式
{ path:”/你去的路径”,query:{传递的数据key:数据} }
2.接收
this.$route.query.xxxx
1 2 3 4 5 6
| <template> <div class="about"> <Bb/> <h1>This is an about page----{{this.$route.query.xiaobai}}</h1> </div> </template>
|
query与params方式的区别
1.语法上
query方式在发送数据的时候 可以使用name还可以使用path来设置去的路径 params只能使用name来进行路径的设置
query和params在接收参数的时候不同 一个是使用this.$route.query.xxxx 一个是this.$route.params.xxx
2.url展示形态上
query在url展示形态上 是key=val的格式
params url 直接是 val的方式
相对来说 params在传递数据的时候安全一点点 因为key没有显示(params相当于post请求,query相当于get请求)
路由守卫/导航守卫/路由钩子/导航钩子
在路由跳转的特定阶段内被自动调用的函数
可以完成一些业务功能 比如 登录的验证
全局守卫
会在所有路由跳转的时候生效
全局前置守卫—beforeEach()
路由跳转之前触发
全局后置守卫—afterEach()
路由跳转完成触发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' import About from '../views/About.vue' import Phone from '../views/phone.vue' import User from '../views/user.vue' import Shop from '../views/shop.vue' import List from '../views/list.vue' import Item from '../views/item.vue'
Vue.use(VueRouter)
const routes = [ { path: '/list', name: 'list', component: List }, { path: '/item', name: 'item', component: Item }, { path: '/home', name: 'Home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/user', name: 'user', component: User }, { path: '/phone', name: 'phone', component: Phone }, { path: '/shop/:xiaoming', name: 'shop', component: Shop }, { path:"/", redirect:"/home" } ]
const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes })
router.beforeEach((to,from,next)=>{ console.log("前置守卫to",to) console.log("前置守卫from",from)
if(to.path=="/list"||to.path=="/item"){ next() }else{ alert("您没有登录请您登录后访问") next("/list") } next() })
router.afterEach((to,from)=>{ console.log("后置守卫to",to) console.log("后置守卫from",from) }) export default router
|
路由独享守卫—beforeEnter()
仅仅只对一个路由生效
1 2 3 4 5 6 7 8 9 10 11 12
| { path: '/list', name: 'list', component: List, beforeEnter(to,from,next){ console.log("路由独享to",to) console.log("路由独享from",from) alert("当前是vip页面请您登录充值后在访问") next("/home") } },
|
进入组件之前调用–beforeRouteEnter
离开组件之前调用–beforeRouteLeave
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <template> <div class="home"> <Bb/> <img alt="Vue logo" src="../assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> </div> </template>
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default { name: 'Home', components: { HelloWorld },
beforeRouteEnter(to,from,next){ console.log("进来啦"+to,from) next() }, beforeRouteLeave(to,from,next){ console.log(to+from) if(confirm("确定离开吗?")){ next() }else{ next(false) }
},
} </script>
|
route与router的区别
route 当前路由对象 我们在操纵的时候只想获取当前路由信息的时候使用
router 所有路由对象 我们在操纵所有路由的时候使用
路由懒加载
路由懒加载可以解决spa应用首页加载过慢白屏问题(单页面应用会在第一次加载的时候把所有的页面全部加载出来 可能会影响首屏的显示速度)
懒加载 按需加载 你想用谁谁加载
import方式
component:()=>import(“你引用的路由页面地址”)
异步组件方式
component: (resolve) => require([‘你引用路由页面的地址’], resolve)
路由创建手工方式
1.下载vue-router npm install –save vue-router
2.创建router与views文件夹
3.创建 路由页面
4.在router文件夹下配置index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import Vue from 'vue' import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{ path: '/home', name: 'About', component: () => import('../views/Home.vue') }, { path: '/about', name: 'About', component: () => import('../views/About.vue') }, { path: '/user', name: 'user', component: () => import('../views/user.vue') }, ]
const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes })
export default router
|
创建路由出口
6.注入路由到vue实例
1 2 3 4 5 6 7 8 9 10
| import Vue from 'vue' import App from './App.vue' import router from './router'
Vue.config.productionTip = false
new Vue({ router, render: h => h(App) }).$mount('#app')
|
slot插槽/槽口
用来混合父组件与子组件自己的模板(给组件内部插入dom元素 扩展可复用性)
组件的本质是 自定义标签 自定义标签也是标签 标签就可以有单标签 和 双标签
在vue中默认情况下 我们把组件调用设置成双标签 是没有问题的 但是 我们往双标签中插入新的dom节点 是不会显示的(因为组件是一个完整独立的个体 默认情况下不能往内部插入内容)
slot 就是给组件设置一个开口(插槽/槽口)我们才可以正常的把内容插进来
语法:
放置到组件需要插入外部dom的地方即可
上面传统slot不方便管理插入的内容
具名slot
具名槽口(带有名字的槽口)
语法:
定义槽口使用name属性起名字
插入的时候使用slot属性告诉dom你插入的位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <template> <div> fuffufufufufu <Zi> <h1 slot="nan">你好么么哒!!!!!!!!1</h1> <h1 slot="nv">你好么么哒!!!!!!!!2</h1> <h1>你好么么哒!!!!!!!!3</h1> <h1>你好么么哒!!!!!!!!4</h1> <h1>你好么么哒!!!!!!!!5</h1> <h1>你好么么哒!!!!!!!!6</h1> <h1 slot="nan">你好么么哒!!!!!!!!7</h1> <h1>你好么么哒!!!!!!!!8</h1> </Zi> </div> </template>
<script> import Zi from "./zi.vue"; export default { components:{ Zi } }; </script>
<style> </style>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div> <slot name="nv"></slot> zizizi <slot name="nan"></slot> </div> </template>
<script> export default {
} </script>
<style> </style>
|