上海千语创想科技有限公司
 175-2108-6175
网站建设资讯详细

如何学习vue框架?vue学习总结

日期:2020-03-16  作者:千语创想  浏览:3199

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里面的一个值’


<!-- class 绑定操作样式 -->

<div :class="{ red: isRed }"></div>

<div :class="[classA, classB]"></div>

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

<!-- style 绑定操作行内样式 -->

<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 遍历数据,创建对应的(指令所在的)标签

① 遍历数据<li v-for = ‘(item, index) in list’

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)})

1

② 获取具体某一个


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

1

③ 获取具体某一个,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)})

1

(3)delete删除


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

1

(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>

1

<script src='./vue.js'></script>

<script>

Vue.compent('two', {

template:'<div><h1>{{msg}}</h1></div>'

}),

data(){

return { msg:123 }

}

</script>


(2)局部组件

位置:vue实例里面


const child = {

template: '<div>局部组件child:{{msg}}</div>',

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: `

    <div> 子组件 : {{ msg }} </div>

      `,

    // 第二步 : 子组件通过 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">

  <!-- 第二步 : 通过自定义事件 把方法传递给子组件  -->

  <!-- 例子  @click="f" -->

  <child @fn="fn1"></child>

</div>

<script src="./vue.js"></script>

<script>

  // 子组件

  Vue.component('child', {

    template: `

    <div> 子组件 :  </div>

    `,

    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中)


<!-- 

   (prop的)大小写问题 

   1. 父传子  c-msg  =>  cMsg

   2. 子传父 @add-todo   => add-todo

 -->

<div id="app">

  <child :c-msg="pMsg" @add-todo="pAddTodo"></child>

</div>

<script src="./vue.js"></script>

<script>

  Vue.component('child', {

    template: `

    <div> 子组件 :  {{ cMsg }} </div>

    `,

    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: `

      <div> 子组件 :  </div>

      `,

    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: `<div @click='send'>组件1</div>`,

    methods: {

      send() {

        console.log('send')

        // 发送 一起 jump 的话

        //2. 发送数据, 触发事件

        bus.$emit('jump', 'component1发送的数据')

      }

    }

  })


  // component2

  Vue.component('component2', {

    template: `<div>组件2</div>`,

    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">我是div</div>

  <p ref="p">我是p标签</p>

  <child ref="c"></child>

</div>

<script src="./vue.js"></script>

<script>

  // 组件 看做是一个个可复用的ui模块

  // 组件的本质 vue 实例

  Vue.component('child', {

    template: `

  <div> 子组件 :  </div>

    `,

    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.id事件:this.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">

  <!-- 1. 入口 -->

  <router-link to="/one">one</router-link>


  <!-- 4. 出口 -->

  <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: `<div>one组件 {{ aaa }}</div>`

  }


  //  实例化

  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



优势:

① 减少了体积,加快了页面响应速度,降低了对服务器的压力

② 更好的用户体验,让用户在web app感受到native app的流畅(局部刷新)

劣势:

① 开发成本高(需要学习路由)

② 不利于SEO


十.路由

1.路由的基本使用

(1)准备工作

① 安装路由 npm i vue-router

② 引入路由

③ 实例化路由 + 挂载到vue上


(2)使用步骤

① 入口 (哈希值) 手动在url上写 /one

② 规则(routes):路由的匹配规则,一个哈希值对应一个组件

③ 组件 :路由组件

④ 出口:路由输出位置

既:根据入口哈希值路径,参与路由匹配规则,找到对应的组件,显示到对应的出口位置上


<!-- 第一步:浏览器路径直接访问(....html#/one)-->

<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: `<div>one组件</div>`

  }


  // 实例化路由

  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">

  <!-- 1. 入口 -->

  <!-- 

    需求 :  child组件放到parent组件 里面

    办法 :  children : [路由规则]

   -->

  <!-- 4. 出口 -->

  <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: `<div>parent组件  <router-view ></router-view>  </div>`

  }

  const child = {

    template: `<div>child组件</div>`

  }


  //  实例化

  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">

  <!-- 4. 出口 -->

  <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: `<div>header组件</div>`

  }

  const main = {

    template: `<div>main组件</div>`

  }

  const footer = {

    template: `<div>footer组件</div>`

  }


  //  实例化

  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">

  <!-- 1. 入口 -->

  <!-- 下面两个用的都是 path -->

  <!-- <router-link to="/one">one</router-link>

  <router-link to="/two">two</router-link> -->

  <router-link :to="{ name : 'one' }">one</router-link>

  <router-link :to="{ name :'two' }">two</router-link>


  <!-- 4. 出口 -->

  <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: `<div>one组件</div>`

  }

  const Two = {

    template: `<div>two组件</div>`,

    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');

}

})




转载请注明来自:https://www.qianyuthink.com/news/7307.html

填写您的项目需求给我们

或者直接拨打 7×12小时一对一咨询电话

175 2108 6175

请填写需求信息,我们会在10分钟内与您取得联系

请认真填写需求信息,我们会在10分钟内与您取得联系

×
客服二维码
咨询技术总监
175-2108-6175
客服二维码
技术总监微信
客服二维码