Vue框架学习总结归纳

Vue框架

前文:库和框架的概念

1.库(lib) 代表:jQuery
说明:库里面有一系列函数的集合,我们想要实现某个功能,调用库里面的一些方法
特点:库为辅助功能,即开发人员说了算

2.框架(framework) 代表:vue
说明:框架里有一套完整的解决方案,‘它指定了一套规则’,使用这个框架就要按照它的规则去编写代码,编写好之后,框架会在适当的时机去解析我们的代码。
特点:框架说了算
比如:v-for created data

3.库和框架的区别:控制反转(谁说了算,谁起主导作用)
库:开发人员说了算
框架:框架说了算
从体量上看:框架>库(框架包含库)

一.vue的介绍

1.MVC模式和MVVM模式
(1)MVC模式:后端编写代码控制视图
M:model 数据
V:view 视图
C:control 控制器
简单的流程就是:用户与View交互;Controller时间处理器被触发,控制器从模型中请求数据(model),并反馈给视图层(view),视图讲数据呈现给用户。
注意:真正处理业务逻辑的是Model层而不是controller;controller只是对页面节点事件的注册和控制

(2)MVVM模式
vue的模式是MVVM模式(数据的双向绑定)
M:model 数据层
V:view 视图层
VM:ViewModel 视图数据层 == vm(vue的实例)

View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互。
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

数据驱动视图的思想,数据是核心(数据改变,视图也改)
① vue的数据双向绑定,是通过Object.defineProperty()数据劫持来实现
② Object.defineProperty(obj, prop, descriptor) 添加/修改属性
(参数1:对象;参数2:属性(添加/设置);参数3:属性描述符,对象形式)
obj:要定义属性的对象。
prop:要定义或修改的属性的名称或 Symbol 。
descriptor:要定义或修改的属性描述符。

const object1 = {
     };

Object.defineProperty(object1, 'property1', {
     
  value: 42,
  writable: false
});
// 读写设置为(writable: false),不能改
object1.property1 = 77;

console.log(object1.property1);
// 输出: 42

(3)vue的安装

// 安装:
npm i vue
// 导入:
<script src = './vue.js'></script>

二.vue的基本使用

{ {}} 插值表达式 小胡子语法
作用:直接读取data里的数据,展示到模板(<>{ {}}<>)
① 可以放表达式{msg + 200} { {[1, 2, 3].join(’-’)}}
② 不能放语句
③ { {}}不能用在属性上

<div id="app">
  {
    { message }}
div>
const vm = new Vue({
     
	el:'#app',
	data : {
     
		message : 'hhha'
	}
})

三.指令

1.v-model (数据的双向绑定)
场景:一般用在表单元素上

<div id="app">
  <p>{
    { message }}p>
  <input v-model="message">
div>
var app = new Vue({
     
  el: '#app',
  data: {
     
    message: 'Hello Vue!'
  }
})

2.v-text/v-html 和{ {}}效果一样
v-text 不识别标签 v-html 识别标签的

<span v-text="msg">span>

<span>{
    {msg}}span>

3.v-bind 动态绑定一个数据(单向m => v)
语法::属性 = ‘data里面的一个值’


<div :class="{ red: isRed }">div>
<div :class="[classA, classB]">div>
<div :class="[classA, { classB: isB, classC: isC }]">

<div :style="{
         fontSize: size + 'px' }">div>
<div :style="[styleObjectA, styleObjectB]">div>

4.v-on 注册/绑定事件
① v-on:事件 = ‘事件函数’
② 语法糖:@事件 = ‘事件函数’、
③ 事件函数

// html部分
<div id='app'><button @click='click1'>按钮button>div>
// js部分
const vm = new Vue({
     
	el:'#app',
	data:'...',
	method:{
     
		click1(){
     
			console.log('点击了按钮');
		}
	}
})

事件中的this就是vue实例
获取数据:
① 标签获取数据:{ message }
② js获取数据:this.message

事件对象(获取):
① 不传参,直接在事件函数里接收一个形参即可:@click = ‘fn’ fn(e){}
② 传参,vue预留了一个关键字 e v e n t @ c l i c k = ′ f n ( event @click = 'fn( event@click=fn(event, 123)’ fn(e, num){}

事件修饰符:
① 事件.prevent 阻止默认行为
② 事件.stop 阻止冒泡
③ 事件.capture 捕获(即内部元素触发的事件先在此处理,然后才交由内部元素进行处理)
④ 事件.self 点击自己才会被触发
⑤ 事件.once 点击只触发一次
⑥ 事件.passive 移动端提高性能

按键修饰符:
enter/tab/delete/esc/space/up/down/left/right
使用回车的三种方式:
① if(e.keyCode == 13){}
② @keyup.13 = ‘fn1’
③ @keyup.ente = ‘fn1’

5.v-for 遍历数据,创建对应的(指令所在的)标签
① 遍历数据

  • item数组里的元素 如果item为对象(item.id, item.name)
    index就是下标索引
    ② 遍历对象


    • value:值 key:键
      ③ 遍历数据
    • i从1开始创建100个li

      key:
      ① vue推荐使用v-for的时候,加上key
      ② 如果不加key,会出现‘就地复用’的策略
      ③ 解决‘就地复用’的问题:添加一个key属性,并且给key一个正确值
      ④ 给key赋值的俩种情况:
      => 如果数组里的元素是一个对象(90%),key取对象里的属性(固定,唯一) :key=‘iten.id’
      => 如果数组里的元素不是一个对象 :key=‘index’(不要让顺序发生改变)
      6.其它指令:
      ① v-pre 不解析
      ② v-once 解析一次
      ③ v-cloak 遮盖,解决闪烁问题
      [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。

      [v-cloak] {
             
        display: none;
      }
      
      <div v-cloak>
        {
            { message }}
      div>
      

      7.条件渲染指令
      v-if 和 v-show
      相同点:都可以切换元素的显示和隐藏
      不同点:
      v-if:显示(创建节点) 隐藏(删除节点)
      v-show:显示(display:block) 隐藏(display:none)
      场景:频繁(v-show) 不频繁(v-if)

      <div v-if="type === 'A'">
        A
      div>
      <div v-else-if="type === 'B'">
        B
      div>
      <div v-else-if="type === 'C'">
        C
      div>
      <div v-else>
        Not A/B/C
      div>
      

      四.数据变化与处理(nextTick(),computed())

      1.nextTick() 的自动触发
      数据发生改变,vue会自动更新视图。
      数据发生变化,不是一改变就立马更新的,而是当数据不再发生变化的时候,一次性统一更新的。
      nextTick 数据变化,自动触发
      this.nextTick(() => {})

      2.数据响应式问题(v-model)
      Vue无法检测到对象属性的添加或删除。
      总结:
      ① 尽量先在data里声明好,给一个初始值
      ② 在一些第三方框架里,我们必须动态地添加额外的数据。 this. s e t ( ) t h i s . set() this. set()this.set(obj, key, value)

      3.计算属性computed
      计算属性:是一个新值,不是data里的值

      computed:{
             
      	itemLeftCount(){
             
      		return this.list.filter(item=>!item.done).length
      	};
      	isClearCompletedShow(){
             
      		return this.list.some(item=>item.done)
      	}
      }
      

      五.监听器 watch

      1.监听简单类

      data:{
             
      	num:100;
      }
      watch:{
             
      	num(newVal, oldVal){
             
      		console.log('新知:', newVal, '旧值:', oldVal);
      	}
      }
      

      2.监听复杂类型
      方式1:监听对象+深度监听

      obj:{
             
      	deep:true,		// 深度监听
      	immediate:true,	//立即监听
      	handler(newVal){
             		// 处理函数
      		console.log(newVal.name);
      	}
      }
      

      方式2:直接监听对象里面的属性(name)

      'obj.name'(newVal):{
             
      	console.log(newVal);
      }
      

      六.过滤器filter

      作用:处理不合适的数据,处理好之后,返回合适的数据
      使用过滤器的步骤:
      ① 先注册
      全局过滤器:所有的vue实例里都可以使用
      局部过滤器:只能在当前注册的实例里使用
      ② 再使用‘管道’
      格式:要处理的数据 | 过滤器

      1.全局过滤器
      注意点(注册全局过滤器):
      ① 注册全局过滤器,一定要在实例vue之前注册
      ② 过滤器要有返回值,返回的值就是过滤处理好的值
      参数1:过滤器的名字 参数2:回调函数(当使用过滤器的时候使用)

      <div id='app'>
      	<h1>{
            {date | dateFilter}}h1>	// 使用‘管道’
      div>
      <script src='vue.js'>script>
      <script>
      	// 参数1 : 过滤器的名字
          // 参数2 : 回调函数 当使用过滤器的时候
          // 注册全局过滤器
      	Vue.filter('dateFilter', () => {
              
      		return 'hhha'
      	})
      	const vm = new Vue({
              
      		el:'#app',
      		data:{
              
      			date:new Date()	
      		}	
      	})
      script>
      

      过滤器配合moment处理日期
      ① 安装:npm i moment
      ② 引入
      ③ 使用

      Vue.filter('dateFilter', res => {
             
      	return moment(res).format('YYYY-MM-DD HH:mm:ss')
      })
      

      过滤器的参数:

      <div id='app'>
      	<h1>{
            { date | dateFilter('YYYY-MM-DD HH-mm-ss')}}h1>
      div>
      
      Vue.filter('dateFilter', (res, fStr='YYYY-MM-DD' => {
             
      	return moment(res).format(fStr)
      })
      

      2.局部过滤器:
      位置:局部过滤器是注册在vue实例里面

      const vm = new Vue({
             
      	el : '#app',
      	dat : {
             
      		date : new Date()
      	}
      	filters : {
             
      		dateFilter(res){
             
      			return moment(res).format('YYYY-MM')
      		}
      	}
      })
      

      七.生命周期

      生命周期的三个大阶段
      ① 第一个阶段:挂载阶段(进入页面的阶段)
      ② 第二个阶段:更新阶段(数据发生改变的阶段)
      ③ 第三个阶段:销毁阶段(卸载阶段,关闭页面)

      1.第一个阶段:挂载阶段(4个钩子函数)
      ① 第1个小阶段:数据的初始化 => msg:测试信息
      ② 第2个小阶段:找模板 => 找template等
      ③ 第3个小阶段:DOM渲染 => <标签>{ {msg}}=><标签>测试信息

      第1个小阶段:数据的初始化
      beforeCreate() 数据响应式之前调用
      特点:无法获取到数据和事件
      ☆ create() 数据响应式之后调用
      特点:可以获取到数据和事件
      使用场景:① 发送ajax ② 操作data ③ 操作本地数据(操作数据)

      第2个小阶段:找模板
      询问有没有‘el’配置项(①有=>继续下一步 ②没有=>vm.$mount(’#app’)=>继续下一步)
      询问有没有‘template’配置项(①有=>将template的值进行编译 ②没有=>el的outerHTML作为模板)
      目的:找模板 结论:template>el(既先看vue实例里有没有template)

      第3个小阶段:DOM渲染
      before() DOM渲染之前调用
      特点:<标签>{ {msg}}
      ☆ mounted() DOM渲染之后调用
      特点:<标签>测试信息
      使用场景:① 发送ajax ② 操作DOM

      第二个大阶段:更新阶段(2个钩子)
      beforeUpdate() 数据更新之前
      updated() 数据更新之后

      第三个大阶段:销毁阶段(2个钩子)
      beforeDestory() 销毁之前(可以清除开发人员自己添加的定时器等)
      destoryed() 销毁之后

      八.axios(基于promise,发送ajax的工具库)

      安装:npm i axios
      1.axios和ajax
      axios是一个基于promise,发送ajax的工具库,可用于浏览器/node.js
      ① axios是对ajax的一个封装
      ② axios是基于promise的
      2.格式:axios.get/post/put/patch(…).then(res => {})
      (1)get
      ① 获取全部数据
      参数:url地址接口

      axios.get('http://localhost:300/list').then(res => {
             cosole.log(res)})
      

      ② 获取具体某一个

      axios.get('http://localhost:300/list/3').then(res => {
             cosole.log(res)})
      

      ③ 获取具体某一个,id为参数
      语法:axios.get(url, config)
      配置项config:{params(对象)参数,herder(对象).请求头}

      axios.get('http://localhost:300/list',{
             
      	params : {
             id:4},
      	header : {
             }
      })
      

      (2)post添加
      post添加不需要传id的
      语法:axios.post(url, data)

      axios.post('http://localhost:300/list', {
             name:'ZS', done:false}).then(res => {
             console.log(res)})
      

      (3)delete删除

      axios.delete('http://localhost:300/list/3').then(res => {
             cosole.log(res)})
      

      (4)put/patch修改

      axios.put('http://localhost:300/list/3', {
             name:'改李四', done:false}).then(res => {
             cosole.log(res)})
      axios.patch('http://localhost:300/list/3', {
             name:'改老王'}).then(res => {
             cosole.log(res)})
      axios.patch('http://localhost:300/list/$(this.editId)', {
             name:e.target.value}).then(res => {
             cosole.log(res)})
      

      3.json-server
      作用:可以根据一个json文件,开启一个借口服务器
      安装:npm i json-server -g
      使用:‘json-server json文件的路径’ =>终端运行命令获得浏览器路径
      遵循REST API格式:
      (1)获取:get
      ① 获取全部:http://localhost:300/list
      ② 获取具体某个:http://localhost:300/list/3
      (2)添加
      http://localhost:300/list
      不需要id 参数:{name:‘张三’, done:true}
      (3)删除:delete
      http://localhost:300/list/2
      (4)修改:put/patch
      ① put(修改某一个):http://localhost:300/list/3
      把需要修改的和不需要修改的都传过去{name:‘张三’, done:true}
      ②patch(修改某一个):http://localhost:300/list/3
      哪里需要修改就传对应的修改数据

      九.组件

      组件可以看作是一些可复用的UI模块
      官网:组件是可复用的Vue实例
      1.注册组件
      (1)全局组件
      注意:
      ① 注册组件要在vue实例之前注册
      ② template只能有一个根节点
      ③ 组件里的data是一个函数,不是一个对象(因为想让组件复用,不想让组件里的数据复用)

      <div id='app'><one>one>div>
      
      <script src='./vue.js'></script>
      <script>
      Vue.compent('two', {
             
      	template:'

      { {msg}}

      '
      }), data(){ return { msg:123 } } </script>

      (2)局部组件
      位置:vue实例里面

      const child = {
             
      	template: '
      局部组件child:{ {msg}}
      '
      , data(){ return { msg:'局部组件:哈哈'} } } const one = { ...} const two = { ...} const vm = new Vue({ el: '#app', data: { }, filters: { }, components: { child, one, two } })

      ★2.组件间的通信机制
      (1)父传子(父组件数据传给子组件)
      步骤:
      ① 通过属性传递给子组件
      ② 子组件通过props配置项,指定一下要接收过来的数据 props : [‘msg’]

      <div id="app">
        
        <child :msg="pmsg">child>
      div>
      <script src="./vue.js">script>
      <script>
        // 子组件
        Vue.component('child', {
              
          template: `
          
      子组件 : { { msg }}
      `
      , // 第二步 : 子组件通过 props 配置项 指定一下要接收过来的数据 props: ['msg'] }) // 父组件 const vm = new Vue({ el: '#app', data: { pmsg: '父组件里的信息' } })
      script> body>

      (2)子传父(子组件数据传给父组件)
      步骤:
      ① 父组件准备一个方法fn1(){}
      ② 通过自定义事件,把方法传递给子组件@fn=‘fn1’
      ③ 子组件通过$emit触发事件(手动触发事件)
      $emit(参数1:事件(fn), 参数2:子组件传递的数据)

      <div id="app">
        
        
        <child @fn="fn1">child>
      div>
      <script src="./vue.js">script>
      <script>
        // 子组件
        Vue.component('child', {
              
          template: `
          
      子组件 :
      `
      , created() { // 例子 // @click='fn1' // 1. 点击 => 调用fn1 // 2. 手动触发 this.$emit('click') => fn1 // 第三步 : 子组件里面触发这个事件,就调用了fn1 // $emit(参数1:事件 参数2..:传递的数据) this.$emit('fn', '我是子组件里的数据') } }) const vm = new Vue({ el: '#app', data: { }, // 第一步: 父组件准备好一个方法 methods: { fn1(res) { console.log('fn1调用了:', res) } } })
      script>

      (3)父子组件传递数据的总结
      ① 单向数据流(组件与组件之间)
      所有的prop都使得父子prop之间形成一个单向下行绑定
      父级更新可以,子组件不能修改父组件数据(简单数据和复杂数据(地址))

      ② props的特点:只读
      注意:子组件不允许修改父组件传过来的prop数据(如果想修改可以通过子传父将要修改的信息传给父组件)
      简单类型修改会报错
      复杂类型:修改不会报错,因为地址没变,测试‘obj={}’马上报错=>改变了地址
      ③ prop的大小写问题
      父传子: c-msg(属性) => CMsg(prop中)
      子传父:@add-todo(自定义事件) => add-todo($emit中)

      
      <div id="app">
        <child :c-msg="pMsg" @add-todo="pAddTodo">child>
      div>
      <script src="./vue.js">script>
      <script>
        Vue.component('child', {
              
          template: `
          
      子组件 : { { cMsg }}
      `
      , props: ['cMsg'], created() { this.$emit('add-todo') } }) const vm = new Vue({ el: '#app', data: { pMsg: '父的信息' }, methods: { pAddTodo() { console.log('hha') } } })
      script>

      ④ prop的类型问题
      通过prop 赋值的时候,
      如果直接赋值一个静态值 不管是什么,都是字符串类型( ‘abc’ / ‘123’ / ‘true’)
      可以在 属性前面加一个: , 可以获取它的真实类型

      总结 :
      :msg=‘pmsg/动态值/data里属性’
      :msg=‘固定值/静态值’ 读取固定值的真实类型赋值给 msg

      <div id="app">
        <child :msg="true" :na="name">child>
      div>
      <script src="./vue.js">script>
      <script>
        Vue.component('child', {
              
          template: `
            
      子组件 :
      `
      , props: ['msg'], created() { // 'abc' => 字符串 // '123' => '123' 字符串 console.warn(this.msg, typeof this.msg) } }) const vm = new Vue({ el: '#app', data: { name: 123 } })
      script>

      ⑤ prop的校验(判断传过来的数据是否为自己想要的)

      props: {
              
      	// 默认值为数字
      	msg1: {
             
      		type: Number,
              default: 100			// 默认为数字100
          },
          // 默认值为对象
      	msg2: {
             
      		type: Object,
          	// 对象或数组默认值必须从一个工厂函数获取
          	default: function () {
             return {
              message: 'hello' }
      	}
      }
      
      

      (4)非父子之间的通信是通过事件总线(event bus)来实现的
      步骤:
      ① 创建事件总线(bus):一个空的vue实例
      const bus = new Vue()
      ② 发送数据:触发事件=>bus. e m i t ( ′ 事 件 名 ′ , ′ 数 据 ′ ) ③ 接 收 数 据 : 注 册 事 件 = > b u s . emit('事件名', '数据') ③ 接收数据:注册事件=>bus. emit(,)=>bus.on(‘事件名’, res => {})

      <div id="app">
        <div>
          <div>
            <component1>component1>
          div>
        div>
        <div>
          <component2>component2>
        div>
      div>
      <script src="./vue.js">script>
      <script>
        //1. 事件总线
        const bus = new Vue()
      
        // component1
        Vue.component('component1', {
              
          template: `
      组件1
      `
      , methods: { send() { console.log('send') // 发送 一起 jump 的话 //2. 发送数据, 触发事件 bus.$emit('jump', 'component1发送的数据') } } }) // component2 Vue.component('component2', { template: `
      组件2
      `
      , created() { //3. 接收数据 注册事件 console.log('on') bus.$on('jump', res => { console.log('rose接收到的:', res) }) } }) const vm = new Vue({ el: '#app', data: { } })
      script>

      (5)refs:refs可以获取DOM元素/组件
      步骤:
      ① 注册ref=‘c’
      ② 获取:this.$refs.c

      <div id="app">
      	// 注册ref
        <div ref="d">我是divdiv>
        <p ref="p">我是p标签p>
        <child ref="c">child>
      div>
      <script src="./vue.js">script>
      <script>
        // 组件 看做是一个个可复用的ui模块
        // 组件的本质 vue 实例
        Vue.component('child', {
              
          template: `
        
      子组件 :
      `
      , data() { return { cmsg: '子组件里的数据' } } }) const vm = new Vue({ el: '#app', data: { }, created() { }, mounted() { // 可以通过 this.$refs 获取dom元素/组件 console.log(this.$refs.p) console.log(this.$refs.d) // 也可以获取组件里的数据 // 父组件可以通过 refs 拿到子组件里的数据 console.log(this.$refs.c.cmsg) } })
      script>

      (6)组件传参的方式
      ① 方式1:to=’/one/4’ path=’/one/:id’
      组件: r o u t e . p a r a m s . i d 事 件 : t h i s . route.params.id 事件:this. route.params.idthis.route.params.id
      ② 方式2:路由规则里props:true
      将参数id作为组件的属性存在
      路由里:props:true
      组件内:props:[‘id’]
      使用{ {id}}
      ③ 方式3:对象模型
      路由里:props:{aaa:‘bbb’}
      组件内:props:[‘aaa’]
      使用{ {aaa}}
      ④ 方式4:函数模式
      路由里: props : to => { return { aaa : ‘ccc’ } }
      组件内:props:[‘aaa’]
      使用{ {aaa}}

      <div id="app">
        
        <router-link to="/one">onerouter-link>
      
        
        <router-view>router-view>
      div>
      <script src="./vue.js">script>
      <script src="./node_modules/vue-router/dist/vue-router.js">script>
      <script>
        // 3. 组件
        const One = {
              
          props: ['id', 'aaa'],
          template: `
      one组件 { { aaa }}
      `
      } // 实例化 const router = new VueRouter({ // 2. 规则 // props : true 将id参数作为组件的属性存在 routes: [ // { path: '/one/:id', component: One, props: true } // 将aaa 作为 组件的属性存在 // { path: '/one', component: One, props: { aaa: 'bbb' } } { path: '/one', component: One, props: to => { return { aaa: 'ccc' } } } ] }) const vm = new Vue({ router, el: '#app', data: { } })
      script>

      (7)单页面应用程序(SPA:Singe Page Application)
      浅谈前端SPA(单页面应用):https://blog.csdn.net/huangpb123/article/details/86183453
      Vue框架学习总结归纳_第1张图片

      优势:
      ① 减少了体积,加快了页面响应速度,降低了对服务器的压力
      ② 更好的用户体验,让用户在web app感受到native app的流畅(局部刷新)
      劣势:
      ① 开发成本高(需要学习路由)
      ② 不利于SEO

      十.路由

      1.路由的基本使用
      (1)准备工作
      ① 安装路由 npm i vue-router
      ② 引入路由
      ③ 实例化路由 + 挂载到vue上

      (2)使用步骤
      ① 入口 (哈希值) 手动在url上写 /one
      ② 规则(routes):路由的匹配规则,一个哈希值对应一个组件
      ③ 组件 :路由组件
      ④ 出口:路由输出位置
      既:根据入口哈希值路径,参与路由匹配规则,找到对应的组件,显示到对应的出口位置上

      
      <div id="app">
        
        <router-view>router-view>
      div>
      <script src="./vue.js">script>
      <script src="./node_modules/vue-router/dist/vue-router.js">script>
      <script>
        // 第三步 : 路由组件
        const One = {
              
          template: `
      one组件
      `
      } // 实例化路由 const router = new VueRouter({ // 第二步 : 路由的匹配规则 一个哈希值 对应一个组件 routes: [{ path: '/one', component: One }] }) const vm = new Vue({ router, el: '#app', data: { } })
      script>

      (3)入口(修改url路径)
      ① 手动url修改 /one
      ② 声明式导航 one
      router-link最终会被编译成a标签
      to:转换成href
      作用:改变入口的哈希值路径
      ③ 编程式导航 this. r o u t e r . p u s h ( ′ / o n e ′ ) 前 进 ( 跳 转 ) = = > − t h i s . router.push('/one') 前进(跳转) ==> - this. router.push(/one)()==>this.router.push() - 有记录
      - this. r o u t e r . r e p l a c e ( ) − 没 有 记 录 返 回 = = = = > t h i s . router.replace() - 没有记录 返回 ====> this. router.replace()====>this.router.back()

      // 声明式导航
      <router-link to='/one'>one</router-link>
      // 编程式导航
      this.$router.push('/two')
      this.$router.replace('/two')
      

      (4)多个路径和嵌套路由

      // 多个路径的路由写法
      const router = new VueRouter({
             
      // 路由的匹配规则 一个哈希值 对应一个组件
      	routes: [
      		{
              path: '/one', component: One },
      	 	{
              path: '/two', component: Two }
      	]
      })
      
      
      <div id="app">
        
        
        
        <router-view>router-view>
        <hr />
      div>
      <script src="./vue.js">script>
      <script src="./node_modules/vue-router/dist/vue-router.js">script>
      <script>
        // 3. 组件
        const parent = {
              
          template: `
      parent组件
      `
      } const child = { template: `
      child组件
      `
      } // 实例化 const router = new VueRouter({ // 2. 规则 routes: [ { path: '/parent', component: parent, children: [{ path: '/child', component: child }] } ] }) const vm = new Vue({ router, el: '#app', data: { } })
      script>

      (5)动态路由
      ① 使用参数接收不同的路由参数path=’/detali/:id’
      ② 参数可传可不传path=’/detali/:id?’

      精确匹配和模糊匹配:
      ① router-link-exact-active精确匹配
      url上的路径==href的值
      ② router-link-active(包含)既>=href的值

      (6)$route路由对象 哈希值#/one/2?age=18#abc
      fullpath:字符串/one/2?age=18#abc 全路径
      hash:字符串=>#abc 哈希
      ★ params:对象=>{id:‘2’} 路由参数
      ★ path:字符串=>/one/2 #后面?前面的path
      ★ query:对象=>{age:18} 查询参数

      ★重点:使用watch监听$route路由对象(地址改变)获取里面信息

      watch: {
             
        $route(newVal) {
             
          console.warn(newVal.params.id)
        }
      }
      

      (7)命名路由(同路径多组件)和命名路由

      
      <div id="app">
        
        <router-view>router-view>
        <router-view name="m">router-view>
        <router-view name="f">router-view>
      div>
      <script src="./vue.js">script>
      <script src="./node_modules/vue-router/dist/vue-router.js">script>
      <script>
        // 3. 组件
        const header = {
              
          template: `
      header组件
      `
      } const main = { template: `
      main组件
      `
      } const footer = { template: `
      footer组件
      `
      } // 实例化 const router = new VueRouter({ // 2. 规则 routes: [ { path: '/', components: { default: header, m: main, f: footer } } ] }) const vm = new Vue({ router, el: '#app', data: { } })
      script>
      <div id="app">
        
        
        
        <router-link :to="{ name : 'one' }">onerouter-link>
        <router-link :to="{ name :'two' }">tworouter-link>
      
        
        <router-view>router-view>
      div>
      <script src="./vue.js">script>
      <script src="./node_modules/vue-router/dist/vue-router.js">script>
      <script>
        // 3. 组件
        const One = {
              
          template: `
      one组件
      `
      } const Two = { template: `
      two组件
      `
      , created() { console.log(this.$route.name) } } // 实例化 const router = new VueRouter({ // 2. 规则 routes: [ { path: '/one', name: 'one', component: One }, { path: '/two', name: 'two', component: Two } ] }) const vm = new Vue({ router, el: '#app', data: { } })
      script>

      (8)重定向

      路径的三种方式:
      ① 方式1:path路径 {path:’/’, redirect:’/one’}
      ② 方式2:路由的名称 {path:’/’, redirect:{name:‘one’}}
      ③ 方式3:函数

      routes: [
        // 方式1 : path路径
        // { path: '/', redirect: '/one' },
        // 方式2 : 路由的名称
        // { path: '/', redirect: { name: 'one' } },
        // 方式3 : 函数
        {
             
          path: '/',
          redirect: to => {
             
            if (to.XXX) {
             
               return {
              name : 'one'}
            } else {
             
               return {
             name : 'two' }
            }
          }
        }
      ]
      

      (9)元信息:路由里添加meta字段
      {path:/one, name:‘one’, component:one, meta:{title:‘张三页’}}
      示例:meta信息修改document.title = this.$route.meta.title

      (10)前置导航守卫:beforeEach
      场景:先登录再访问
      ① 写法 router.beforeEach( (to,from ,next)=> {} )
      ② 参数:
      to : 目标路由对象
      from : 来源路由对象
      next: 下一步
      ③ next() 允许下一步
      next(false) 不允许
      next(’/login’) 跳转到login

      // 先登录后访问
      router.beforeEach((to, from, next) => {
             
      	if(to.name == 'login'){
             
      		next();
      	}else{
             
      		next('/login');
      	}
      })
      
  • 你可能感兴趣的:(前端,vue框架,vue.js,vue)