Vue2总结

1.内置指令

v-if

<div v-if="n === 1">Angular</div>
<div v-else-if="n === 2">React</div>
<div v-else>Vue</div>

v-for

<li v-for="(p,index) in persons" :key="index">
	{{p.name}}-{{p.age}}
</li>

key的作用原理:
·
旧虚拟DOM中找到了与新虚拟DOM相同的key:
若虚拟DOM中内容没变, 直接使用之前的真实DOM
若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM
旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面


其他内置指令

指令例子说明
v-text<div v-text="str"></div>v-text会替换掉节点中的内容
v-html<div v-html="str"></div>v-html会替换掉节点中所有的内容,v-html可以识别html结构
v-cloak使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题
v-once<h2 v-once>n初始化的值是:{{n}}</h2>v-once所在节点在初次动态渲染后,就视为静态内容了。以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
v-pre<h2 v-pre>Vue其实很简单</h2>可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译
v-bind单向绑定解析表达式,可简写为:
v-model双向数据绑定
v-on绑定事件监听,可简写为@
v-show条件渲染 (动态控制节点是否展示),v-show是控制display属性来控制组件是否显示的
v-cloak例子:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>v-cloak指令</title>
		<style>
			[v-cloak]{
				display:none;
			}
		</style>
	</head>
	<body>
		<div id="root">
			<h2 v-cloak>{{name}}</h2>
		</div>
		<script type="text/javascript" src="../js/vue.js"></script>
	</body>
	
	<script type="text/javascript">
		Vue.config.productionTip = false
		
		new Vue({
			el:'#root',
			data:{
				name:'尚硅谷'
			}
		})
	</script>
</html>

2 过滤器

过滤器笔记

3自定义指令

自定义指令笔记

4 watch监视属性和computed计算属性

watch 笔记
computed计算属性笔记
参考笔记

5 ref

打标识< h1 ref=“xxx”></ h1>< School ref=“xxx”></ School>
获取:this.$refs.xxx

6 mixin

mixin参考

mixin混入对象和Vuex的区别?
vuex是所有组件共同管理一个状态,状态共享
mixin是定义公用的变量或方法,但是mixin中的数据是不共享的,也就是每个组件中的mixin实例都是不一样的,都是单独存在的个体,不存在相互影响的;

7 plugin插件

plugin参考

8 WebStorage

类型说明
sessionStorageSessionStorage存储的内容会随着浏览器窗口关闭而消失
localStorageLocalStorage存储的内容,需要手动清除才会消失

LocalStorage为例

<body>
    <h2>localStorage</h2>
    <button onclick="saveDate()">点我保存数据</button><br/>
    <button onclick="readDate()">点我读数据</button><br/>
    <button onclick="deleteDate()">点我删除数据</button><br/>
    <button onclick="deleteAllDate()">点我清空数据</button><br/>

    <script>
        let person = {name:"JOJO",age:20}

        function saveDate(){
            localStorage.setItem('msg','localStorage')
            localStorage.setItem('person',JSON.stringify(person))
        }
        function readDate(){
            console.log(localStorage.getItem('msg'))
            const person = localStorage.getItem('person')
            console.log(JSON.parse(person))
        }
        function deleteDate(){
            localStorage.removeItem('msg')
            localStorage.removeItem('person')
        }
        function deleteAllDate(){
            localStorage.clear()
        }
    </script>
</body>

9 props(父子组件之间通信)

1.传递props参数 (父—>子)

<Student name='张三' sex='' :age='18'/>

2.接收props参数

  // 接收props方式1 简答接收
   props: ['name', 'sex', 'age'],
  // 接收props方式2 接收并预设数据类型
   props: {
      name: String,
      sex: String,
      age: Number
    },
  // 接收props方式3 接收并预设类型和必要性和默认值
   props: {
     name: { type: String, required: true },
     sex: { type: String, required: true },
     age: { type: Number, default: 99 },
     array: { type: Number, default:()=>[1,2,3]},
     array: { type: Object, default:()=>{name:'tom'}}
   }

3.使用props参数

<h2>学生的名称:{{name}}</h2>
<h2>学生的年龄:{{age+1}}</h2>
<h2>学生的性别:{{sex}}</h2>

1.props是只读的
Vue底层会监测你对props的修改,如果进行了修改,就会发出警告。
若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据
2.props不能用key,ref等内置名称作为参数名

4.使用props传递函数 (子—>父)

<School :getSchoolName='getSchoolName'/>
methods: {
  getSchoolName (name) {
   console.log('app收到了学校名:', name)
 }
}

5 使用props接收函数

props: ['getSchoolName'],

6 使用props调用函数

  methods: {
    // 调用props函数
    sendSchoolName () {
      this.getSchoolName(this.name)
    }
  },

10 自定义事件(父子组件之间的通信)

通过绑定自定义事件实现子---->父数据传递

1.1绑定自定义事件(方式1)

1.使用 @ 符来绑定自定义事件
2.如果只想让事件触发一次,可以使用:@getStudentName.once="getStudentName"

<Student @getStudentName="getStudentName"/><hr>
getStudentName (name,x,y,z) {
   console.log('app收到了学生名:', name,x,y,z)
}

1.2绑定自定义事件(方式2)

1.使用 ref + $on 来绑定自定义事件
2.这种方法的灵活性更强(绑定自定义事件的时间可以自己来定,例如挂载实例后等3秒再绑定事件)
3.如果只想让事件触发一次,可以将 $on 换为 $once

<Student ref="student"/><hr>
mounted () {
 setTimeout(() => {
    this.$refs.student.$on('getStudentName', this.getStudentName)
 }, 3000)
}

2.调用自定义事件

<button @click="sendStudentName()">把学生名字传给app</button>
 sendStudentName () {
   // 触发student实例身上的getStudentName事件
   this.$emit('getStudentName', this.name,this.x,this.y,this.z)
}

3 解绑自定义事件

给谁绑定的就在谁身上解绑

解绑一个自定义事件
unbind () {
  this.$off('getStudentName')
}
解绑多个自定义事件
unbind () {
  this.$off(['getStudentName','demo'])
}
解绑所有自定义事件
unbind () {
  this.$off()
}

4 补充说明

1.组件销毁后自定义事件失效。但原生绑定的事件还有效果
2.可以在组件上声明原生事件<School @click.native="alert(111)"/>要用native修饰,否则就会被当做自定义事件来处理


11 全局事件总线(任意组件之间通信)

实现任意组件组件的数据沟通
使用on注册事件,off撤销事件,emit调用事件

1.安装全局事件总线
在这里插入图片描述

school组件(绑定事件)

  mounted () {
    console.log('Scholl', this.x)
    this.$bus.$on('hello', (data) => {
      alert(`我是school组件,我收到了数据${data}`)
    })
  },
  //解绑
  beforeDestroy () {
    this.$bus.off('hello')
  }

student组件(调用事件)

<button @click="sendStudentName">把学生的名字给school</button>
  methods: {
    sendStudentName () {
      this.$bus.$emit('hello', this.name)
    }
  }

12 消息订阅与发布(任意组件之间通信)

订阅消息:需要消息的订阅消息
发布消息:提供消息的发布消息
下载需要的库:npm i pubsub-js

1.School组件(收数据)

import pubsub from 'pubsub-js'
mounted () {
 // 订阅消息
 this.pubId = pubsub.subscribe('hello', (messageName, data) => {
   console.log('有人发布了hello消息', data)
 })
},
beforeDestroy () {
 // 取消订阅消息
  pubsub.unsubscribe(this.pubId)
}

2.Student组件 (发数据)

<button @click="sendHelloMessage()">发布消息</button>
import pubsub from 'pubsub-js'

// 发布消息
// 参数1:消息的主键 参数2:消息
sendHelloMessage () {
  pubsub.publish('hello', 666)
}

13 &nextTick

页面修改顺序:vue修改某属性后----接着执行函数中的其他语句----函数执行完毕后再重新渲染页面
·
需要立即修改的时候使用nextTick
·
nextTick作用:在下一次dom更新结束后执行回调函数。

<template>
    <div class="Student">
        <div v-if="!showInput">{{msg}}</div>
        <input type="text" name="" id="" v-model="msg" v-else @blur="showtext()" ref="theInput">
        <button @click="toshowInput()">编辑</button>
    </div>
</template>
<script>
export default {
  name: 'Student',
  data () {
    return {
      msg: '我是一个尚硅谷的学生',
      showInput: false
    }
  },
  methods: {
    // 编辑
    toshowInput () {
      this.showInput = true
      // nextTick所指定的回调会在dom节点更新后执行
      this.$nextTick(() => {
        this.$refs.theInput.focus()
      })
    },
    showtext () {
      this.showInput = false
    }
  }
}
</script>

14 过渡与动画

14.1 动画

步骤 :

  • 定义动画
  • 将需要动画的dom用transition包裹
  • vue会根据标签的显示、隐藏自动的为需要动画的标签添加样式类名
<template>
    <div class="Test">
      <button @click="isShow=!isShow">显示隐藏</button>
      //用transition来包裹需要展示动画的标签 
      //name=>动画的类名 
      //:appear="true"是否在刚进入的时候展示动画
      <transition name="textshow" :appear="true">
        <h1 class="msg" v-show="isShow">{{msg}}</h1>
      </transition>
    </div>
</template>
<script>
export default {
  name: 'Student',
  data () {
    return {
      msg: '我是一个尚硅谷的学生',
      isShow: true
    }
  },
  methods: {
    // 编辑
    toshowInput () {
      this.showInput = true
      // nextTick所指定的回调会在dom节点更新后执行
      this.$nextTick(() => {
        this.$refs.theInput.focus()
      })
    },
    showtext () {
      this.showInput = false
    }
  }
}
</script>

<style scoped>
.msg{
  background-color: rgb(222, 168, 226);
  padding: 10px;
  width: 600px;
}
//进入时播放的动画 textshow=>自定义的动画类名 linear=>匀速
.textshow-enter-active{
  animation: textshow 1s linear;
}
//离开时播放的动画 reverse=>翻转(动画反着播放) textshow=>自定义的动画类名
.textshow-leave-active{
  animation: textshow 1s linear reverse;
}

//定义动画
@keyframes textshow {
  from{//从哪里来
    transform: translateX(-100%);
  }
  to{//到哪里
    transform: translateX(0px);
  }
}
</style>

14.2 过渡

<template>
<!-- 过渡 -->
    <div class="Test">
      <button @click="isShow=!isShow">显示隐藏</button>
      <transition name="textshow" :appear="true">
        <h1 class="msg" v-show="isShow">{{msg}}</h1>
      </transition>
    </div>
</template>
<script>
export default {
  name: 'Student',
  data () {
    return {
      msg: '我是一个尚硅谷的学生',
      isShow: true
    }
  },
  methods: {
    // 编辑
    toshowInput () {
      this.showInput = true
      // nextTick所指定的回调会在dom节点更新后执行
      this.$nextTick(() => {
        this.$refs.theInput.focus()
      })
    },
    showtext () {
      this.showInput = false
    }
  }
}
</script>

<style scoped>
.msg{
  background-color: rgb(222, 168, 226);
  padding: 10px;
  width: 600px;
}
/* 整个动画  linear=>匀速*/
.textshow-enter-active,.textshow-leave-active{
    transition: 1s linear;
}
/* 进入的起点 */
.textshow-enter{
    transform: translateX(-100%);
}
/* 进入的终点 */
.textshow-enter-to{
    transform: translateX(0);
}
/* 离开的起点 */
.textshow-leave{
    transform: translateX(0);
}
/* 离开的终点 */
.textshow-leave-to{
    transform: translateX(-100%);
}
</style>

14.3 多个元素过渡

transition标签:只能包含一个dom元素
transition group标签:可以包含多个元素

<transition-group name="textshow" :appear="true">
   <h2 class="msg" v-show="isShow" key="1">{{msg}}</h2>
   <h2 class="msg" v-show="!isShow" key="2">{{msg}}</h2>
</transition-group>

14.4 结合第三方动画库

下载依赖的库:npm install animate.css

在这里插入图片描述

15 配置代理

下载依赖的库:npm i axios
什么是跨域? 违背了同源策略
什么是同源策略? 协议名,主机名,端口号一致

如何解决跨域?

  • 使用cors:后端人员特殊配置,但是会导致所有人都可以请求
  • 使用jsonp:利用script标签的src属性不受同源策略控制的属性来发送请求,但是只能处理get请求,并且需要前端后端配合,麻烦
  • 配置代理:代理服务器,服务器和服务器之间交流无需ajax

开启代理服务器 方法1

借助vue脚手架开启代理服务器

vue.config.js:配置代理服务器

module.exports={
    pages:{
        index:{
            //入口
            entry:'src/main.js'
        }
    },
    //开启代理服务器
    devServer:{
        proxy:'http://localhost:5000'
    }
}
发送请求:
注意这里是用8080来进行请求

getStuednts () {
      axios.get('http://localhost:8080/students').then(
        res => { console.log(res.data) },
        error => { console.log(error.message) }
      )
}

注意:当8080端口下存在对应的内容时,就不会走代理服务器了,而是请求已有的。
注意2:8080端口就相当于public文件夹下的内容
注意3:这种配置的方式只能配置一个端口的跨域

开启代理服务器 方法2

vue.config.js:配置代理服务器

module.exports={
    pages:{
        index:{
            //入口
            entry:'src/main.js'
        }
    },
    devServe:{
        proxy:{
            '/api':{
                target:'http://localhost:5000',
                pathRewrite:{'^/api':''},
                ws:true, //用于支持websocket
                changeOrigin:true //用于控制请求头中的host字段
            },
            '/foo':{
                target:'http://localhost:5001',
                pathRewrite:{'^/foo':''},
                ws:true, 
                changeOrigin:true 
            }
        }
    }
}
发送请求:

getStuednts () {
      axios.get('http://localhost:8080/api/student').then(
        res => { console.log(res.data) },
        error => { console.log(error.message) }
      )
}

16 插槽

16.1 默认插槽

定义插槽

在组件中定义插槽

<template>
   <div class="category">
     <h3 class="title">{{title}}</h3>
     <!-- 定义一个插槽 等着组件的使用者进行填充 -->
     <slot>
       我是默认值,使用者没有传结构的时候出现
     </slot>
   </div>
</template>

<script>
export default {
  name: 'Category',
  props: ['title']

}
</script>

使用插槽

调用组件时使用插槽

<template>
  <div id="app" class="mian-content">
     <Category :listDate='foods' title="美食">
       <img src="./assets/food.jpg" alt="" class="img">
     </Category>

     <Category :listDate='games' title="游戏">
       <ul>
          <li v-for="(item,index) in games" :key="index">{{item}}</li>
       </ul>
     </Category>

     <Category :listDate='films' title="电影">
     </Category>
  </div>
</template>

<script>
import Category from './components/Category.vue'
export default {
  name: 'App',
  components: {Category},
  data () {
    return {
      games: ['游戏1', '游戏2', '游戏3', '游戏4']
    }
  }
}
</script>

效果
在这里插入图片描述

16.2 具名插槽

定义具名插槽

<template>
   <div class="category">
     <h3 class="title">{{title}}</h3>
     <!-- 定义一个插槽 等着组件的使用者进行填充 -->
     <slot name="center"> 我是插槽1,我是默认值,使用者没有传结构的时候出现 </slot>
     <slot name="footer"> 我是插槽2,我是默认值,使用者没有传结构的时候出现 </slot>
   </div>
</template>

调用具名插槽

   <Category :listDate='foods' title="美食">
       <div slot="center">
         <img src="./assets/food.jpg" alt="" class="img">
       </div>
       <!-- 写多个 相当于追加 -->
       <div slot="footer">
         <a href="">其他美食</a>
       </div>
       <div slot="footer">
         <a href="">其他美食</a>
       </div>
  </Category>

优化:使用template来包裹

template可以忽略最外层没有作用的结构
最新的写法: v-slot:center,只能用在template结构上

   <Category :listDate='foods' title="美食">
        <template v-slot:center>
          <img src="./assets/food.jpg" alt="" class="img">
        </template>
        <!-- 写多个 相当于追加 -->
        <template v-slot:footer>
          <a href="">其他美食</a>
          <a href="">其他美食</a>
        </template>
     </Category>

效果图
在这里插入图片描述

16.3 作用域插槽

定义作用域插槽

<template>
   <div class="category">
     <h3 class="title">{{title}}</h3>
     <!-- 将games传递给了插槽的使用者 -->
     <slot :gamesList="games"> 我是默认值,使用者没有传结构的时候出现 </slot>
   </div>
</template>

<script>
export default {
  name: 'Category',
  props: ['title'],
  data () {
    return {
      games: ['游戏1', '游戏2', '游戏3', '游戏4']
    }
  }

}
</script>

调用作用域插槽

<template>
  <div id="app" class="mian-content">
     <Category title="游戏">
       <template slot-scope="listData">
          <ul>
            <li v-for="(item,index) in listData.gamesList" :key="index">{{item}}</li>
          </ul>
       </template>
     </Category>
     <Category title="游戏">
       <template slot-scope="listData">
          <ol>
            <li v-for="(item,index) in listData.gamesList" :key="index">{{item}}</li>
          </ol>
       </template>
     </Category>
     <Category title="游戏">
       <template slot-scope="listData">
          <h3 v-for="(item,index) in listData.gamesList" :key="index">{{item}}</h3>
       </template>
     </Category>
  </div>
</template>

优化:使用解构赋值来提取数据

     <Category title="游戏">
       <template slot-scope="{gamesList}">
          <h3 v-for="(item,index) in gamesList" :key="index">{{item}}</h3>
       </template>
     </Category>

16.4 v-slot

在vue2.6中。上述的API被软废弃(3.0正式废弃),取而代之的是内置指令v-slot,可以缩写为【#】

一般用法:

子组件用法保持不变,父组件中

  • slot属性弃用,具名插槽通过指令参数v-slot:插槽名的形式传入,可以简化为#插槽名
  • slot-scope属性弃用,作用域插槽通过v-slot:xxx="slotProps"slotProps来获取子组件传出的属性
  • v-slot属性只能在template上使用,但在只有默认插槽时可以在组件标签上使用
//Parent
<template>
  <child>
   <!--默认插槽-->
   <template v-slot>
     <div>默认插槽</div>
   </template>
   <!--具名插槽-->
   <template #header>
     <div>具名插槽</div>
   </template>
   <!--作用域插槽-->
   <template #footer="slotProps">
     <div>
      {{slotProps.testProps}}
     </div>
   </template>
  <child>
</template>

扩展用法:

  • 同样可以通过解构获取v-slot={user},还可以重命名v-slot="{user:newName}"和定义默认值v-slot=“{user = ‘默认值’}” 例:v-slot:title="{ item }
  • 插槽名可以是动态变化的v-slot:[slotName]

注意:

  • 默认插槽名为default,可以省略default直接写v-slot,缩写为#时不能不写参数,写成#default(这点所有指令都一样,v-bind、v-on)
  • 多个插槽混用时,v-slot不能省略default

17 路由

17.1 创建路由器

1.路由就是一组key-value的对应关系
2.多个路由需要通过路由器(router)的管理

下载依赖包:
npm i vue-router@3

在main.js中引入:
// 引入
import VueRouter from 'vue-router'
// 调用
Vue.use(VueRouter)

mian.js
在这里插入图片描述

router.js

import VueRouter from 'vue-router'
// 引入组件
import Abbout from '../components/Abbout.vue'
import Home from '../components/Home.vue'
export default new VueRouter({
  routes: [
    {
      path: '/about',
      component: Abbout
    },
    {
      path: '/home',
      component: Home
    }
  ]
})

17.2 路由的基本使用

router-link:切换路由
router-view: 指定路由组件的呈现位置

在这里插入图片描述

17.2 路由需要注意的几个点

路由组件:放在 pages 文件夹中
一般组件:放在 components 文件夹中

切换走的路由组件实质上是被 销毁 了,切换组件实质上就是组件销毁和挂载的过程

每个组件都有自己的r$route属性,里面存储了自己的路由相信。

整个应用都只有一个router可以通过组件的$router属性获取到

17.3 嵌套(多级)路由

注册子路由

    {
      path: '/home',
      component: Home,
      children: [
        {
          path: 'message',
          component: Message
        },
        {
          path: 'news',
          component: News
        }
      ]
    }

使用子路由进行路由跳转

<div class="list-group">
   <router-link class="list-group-item" active-class="active" to="/home/message">message</router-link>
   <router-link class="list-group-item" active-class="active" to="/home/news">news</router-link>
</div>
<div>
    <router-view/>
</div>

17.4 路由命名

简化路由跳转

路由命名
在这里插入图片描述
使用路由名称进行组件切换

<div class="list-group">
    <router-link class="list-group-item" active-class="active" :to="{name:'message'}">message</router-link>
    <router-link class="list-group-item" active-class="active" :to="{name:'news'}">news</router-link>
</div>
<div>
    <router-view/>
</div>

17.5 路由传递query参数

传递query参数

<li v-for="item in messageList" :key="item.id">
        <!-- 写法2:to的字符串写法 -->
     <router-link :to="`/home/message/detail?id=${item.id}&title=${item.title}`">{{ item.title }}</router-link>
        <!-- 写法2:to的对象写法【推荐】 -->
     <router-link :to="{ path:'/home/message/detail', query:{ id:item.id, title:item.title } }">
          {{ item.title }}
     </router-link>
</li>

接收query参数

this.$route.query.id

<ul>
    <li>消息编号:{{this.$route.query.id}}</li>
    <li>消息标题:{{this.$route.query.title}}</li>
</ul>

17.6 路由传递params参数

传递params参数

<li v-for="item in messageList" :key="item.id">
    <!-- 写法2:to的字符串写法 -->
    <router-link :to="`/home/message/detail/${item.id}/${item.title}`">{{ item.title }}</router-link>
    <!-- 写法2:to的对象写法 -->
    <router-link :to="{ name:'detail', params:{ id:item.id, title:item.title } }">
        {{ item.title }}
    </router-link>
</li>

注意:使用to的对象写法,只能用name来设置路由

声明接收params参数

children: [
     {
         name: 'detail',
         path: 'detail/:id/:title',
         component: Detail
     }
]

接收params参数

<ul>
   <li>消息编号:{{this.$route.params.id}}</li>
   <li>消息标题:{{this.$route.params.title}}</li>
</ul>

17.7 路由的props配置

17.7.1 props的对象形式

props的对象写法:该对象的所有参数都会以props的形式传给detail组件

配置props

          children: [
            {
              name: 'detail',
              path: 'detail',
              component: Detail,
              props: {a: 1, b: 'hello'}
            }
          ]

接收props参数

<template>
  <div>
      <h3>detail</h3>
      <ul>
          <li>a:{{a}}</li>
          <li>b:{{b}}</li>
      </ul>
  </div>
</template>

<script>
export default {
  name: 'Detail',
  props: ['a', 'b']
}
</script>
17.7.2 props的布尔值写法

true:把该路由组件收到的params参数以props的形式传递给detail组件

配置props

          children: [
            {
              name: 'detail',
              path: 'detail/:id/:title',
              component: Detail,
              props: true
            }
          ]

传递params参数

<router-link :to="{ name:'detail', params:{ id:item.id, title:item.title } }">
        {{ item.title }}
</router-link>

以props形式接收params参数

<template>
  <div>
      <h3>detail</h3>
      <ul>
          <li>id:{{id}}</li>
          <li>title:{{title}}</li>
      </ul>
  </div>
</template>

<script>
export default {
  name: 'Detail',
  props: ['id', 'title']
}
</script>
17.7.2 props的函数写法

可以把该路由组件收到的各类参数以props的形式传递给detail组件

配置props

children: [
  {
    name: 'detail',
    path: 'detail',
    component: Detail,
    props ($route) {
      return {id: $route.query.id, title: $route.query.title}
    }
  }
]

例子:传递query参数

<router-link :to="{ name:'detail', query:{ id:item.id, title:item.title } }">
        {{ item.title }}
</router-link>

以props形式接收query参数

<template>
  <div>
      <h3>detail</h3>
      <ul>
          <li>id:{{id}}</li>
          <li>title:{{title}}</li>
      </ul>
  </div>
</template>

<script>
export default {
  name: 'Detail',
  props: ['id', 'title']
}
</script>

17.8 route_link的replace属性

将路由的切换形式改为replace(替换路由)

17.9 编程式路由导航

作用: 不借助router_link实现路由的跳转

<button @click="pushShow(item)">push查看</button>
<button @click="replaceShow(item)">replace查看</button>
<button @click="forward">前进</button>
<button @click="back">后退</button>
<button @click="go">前进一个路由</button>
    // push查看
    pushShow (item) {
      this.$router.push({
        name: 'detail',
        params: { id: item.id, title: item.title }
      })
    },
    // replace查看
    replaceShow (item) {
      this.$router.replace({
        name: 'detail',
        query: { id: item.id, title: item.title }
      })
    },
    // 前进
    forward () {
      this.$router.forward()
    },
    // 后退
    back () {
      this.$router.back()
    },
    // go:传入数组 正数前进,负数后退
    go () {
      this.$router.go(1)
    }

17.10 缓存路由组件

让不展示的组件保持挂载,不被销毁
include里面写的是组件名

<!-- include里面写的是组件名 -->
<keep-alive include="News">
       <router-view/>
</keep-alive>
include="News"
:include=["News","Message"]

出现问题:当要keep-alive的组件需要在beforeDestory中执行某些操作的时候,无法执行beforeDestory生命周期。

17.10.1两个新的生命周期函数
<template>
    <div>
      <ul>
        <li :style="{opacity}">欢迎学习vue</li>
        <li>news001<input/></li>
        <li>news002<input/></li>
        <li>news003<input/></li>
      </ul>
    </div>
</template>
<script>
export default {
  name: 'News',
  data () {
    return {
      opacity: 1,
      timer: null
    }
  },
  mounted () {
    this.timer = setInterval(() => {
      this.opacity -= 0.02
      if (this.opacity <= 0) this.opacity = 1
    }, 100)
  },
  activated () {
    console.log('组件被激活了')
  },
  deactivated () {
    console.log('组件失活了')
    clearInterval(this.timer)
  }
  // beforeDestroy () {
  //   clearInterval(this.timer)
  // }
}
</script>

17.11 路由守卫

17.11.1 全局-前置路由守卫

router.beforeEach

import VueRouter from 'vue-router'
// 引入组件
import Abbout from '../pages/Abbout.vue'
import Home from '../pages/Home.vue'
import Message from '../pages/Message.vue'
import News from '../pages/News.vue'
import Detail from '../pages/Detail.vue'

const router = new VueRouter({
  routes: [
    {
      name: 'about',
      path: '/about',
      component: Abbout
    },
    {
      name: 'home',
      path: '/home',
      component: Home,
      children: [
        {
          name: 'message',
          path: 'message',
          component: Message,
        },
        {
          name: 'news',
          path: 'news',
          component: News
        }
      ]
    }
  ]
})

// 全局前置路由守卫 每次路由切换之前和初始化的时候调用
router.beforeEach((to, from, next) => {
  if (to.path === '/home/news' || to.path === '/home/message') {
    if (localStorage.getItem('school') === 'atguigu') {
      next()
    } else {
      alert('学校名称不对,无权查看')
    }
  } else {
    next()
  }
})

export default router

可以在路由配置中插入 路由元信息,用于决定路由是否需要走路由守卫

import VueRouter from 'vue-router'
// 引入组件
import Abbout from '../pages/Abbout.vue'
import Home from '../pages/Home.vue'
import Message from '../pages/Message.vue'
import News from '../pages/News.vue'
import Detail from '../pages/Detail.vue'

const router = new VueRouter({
  routes: [
    {
      name: 'about',
      path: '/about',
      component: Abbout
    },
    {
      name: 'home',
      path: '/home',
      component: Home,
      children: [
        {
          name: 'message',
          path: 'message',
          component: Message,
          meta: {isAuth: true}
        },
        {
          name: 'news',
          path: 'news',
          component: News,
          meta: {isAuth: true}
        }
      ]
    }
  ]
})

// 全局前置路由守卫 每次路由切换之前和初始化的时候调用
router.beforeEach((to, from, next) => {
  if (to.meta.isAuth) {
    if (localStorage.getItem('school') === 'atguigu') {
      next()
    } else {
      alert('学校名称不对,无权查看')
    }
  } else {
    next()
  }
})

export default router
17.11.2 全局-后置路由守卫
import VueRouter from 'vue-router'
// 引入组件
import Abbout from '../pages/Abbout.vue'
import Home from '../pages/Home.vue'
import Message from '../pages/Message.vue'
import News from '../pages/News.vue'
import Detail from '../pages/Detail.vue'

const router = new VueRouter({
  routes: [
    {
      name: 'about',
      path: '/about',
      component: Abbout,
      meta: {title: '关于'}
    },
    {
      name: 'home',
      path: '/home',
      component: Home,
      meta: {title: '主页'},
      children: [
        {
          name: 'message',
          path: 'message',
          component: Message,
          meta: {title: '消息', isAuth: true},
          children: [
         {
            name: 'detail',
            path: 'detail',
            meta: {title: '详情', isAuth: true},
            component: Detail,
         },
        {
          name: 'news',
          path: 'news',
          component: News,
          meta: {title: '新闻', isAuth: true}
        }
      ]
    }
  ]
})

// 全局前置路由守卫 每次路由切换之前和初始化的时候调用
router.beforeEach((to, from, next) => {
  if (to.meta.isAuth) {
    if (localStorage.getItem('school') === 'atguigu') {
      next()
    } else {
      alert('学校名称不对,无权查看')
    }
  } else {
    next()
  }
})

// 全局后置路由守卫 每次路由切换之后和初始化的时候调用
router.afterEach((to, from) => {
  document.title = to.meta.title || '硅谷系统'
})

export default router

17.11.3 独享路由守卫

独享的路由守卫只有前置没有后置

       {
          name: 'news',
          path: 'news',
          component: News,
          meta: {title: '新闻', isAuth: true},
          beforeEnter: (to, from, next) => {
            if (to.meta.isAuth) {
              if (localStorage.getItem('school') === 'atguigu') {
                next()
              } else {
                alert('学校名称不对,无权查看')
              }
            } else {
              next()
            }
          }
        }
17.11.4 组件内路由守卫
<template>
  <div>
      <h2>about</h2>
  </div>
</template>

<script>
export default {
  name: 'Abbout',
  // 通过路由规则进入该组件时被调用
  beforeRouteEnter (to, from, next) {
    console.log('app------beforeRouteEnter')
    next()
  },
  // 通过路由规则离开该组件时被调用
  beforeRouteLeave (to, from, next) {
    console.log('app------beforeRouteLeave')
    next()
  }
}
</script>

17.12 history模式和hash模式

模式说明特点兼容性
hash【默认】带#号,#后面的东西是hash值hash值不会随http请求发送给服务器兼容性好
history不带#号hash值不会随http请求发送给服务器兼容性略差

切换模式
在这里插入图片描述

18 项目打包

npm run build

19 vue前端请求接口封装

19.1 utils文件

在src目录下新建 utils:实用程序 文件夹
创建request.js来作为axios封装文件
在这里插入图片描述

//request.js
import axios from 'axios'

const request = axios.create({
  baseURL: 'http://localhost:3000',
  timeout: 5000
})

export default request

19.1 api文件

在src目录下新建 api 文件夹
创建xxxx.js 用于封装请求
创建index.js用于批量暴露请求
在这里插入图片描述

//实例:produce.js
import request from '../utils/request'

export function getProduce (params) {
  return request({
    method: 'GET',
    url: '/produce',
    params
  })
}

export function getProduceInfo (params) {
  return request({
    method: 'POST',
    url: '/produceInfo',
    params
  })
}
//index.js
import * as produce from './produce'
const apiObj = {
  produce
}

const install = function (Vue) {
  if (install.installed) return
  install.installed = true
  Object.defineProperties(Vue.prototype, {
    $api: {
      get () {
        return apiObj
      }
    }
  })
}
export default {
  install
}

19.3 使用封装过后的axios进行请求

1.在main.js中引入index.js
在这里插入图片描述

2.在pages中使用
在这里插入图片描述

19.4 vue前端请求、相应拦截器

vue前端请求、相应拦截器

20 全局变量

1. 新建global.js文件
在这里插入图片描述
global.js文件内容

export default{
    // nowSystemName:'四川省卫生健康信息中心线上培训信息系统',
    nowSystemName:'电子科大科园商学院',
}

1. 在main.js中引入并使用

import global from './components/common/global'

Vue.prototype.$global = global

3. 在组件中使用

this.$global.nowSystemName
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值