Vue自己总结指令
Vue第一节课程
Vue作用
-
学习Vue框架的作用:
减少原生DOM操作的频繁性
-
使用框架开发:
只需要关注数据的变化,还是视图的变化
-
学习Vue需要具备的知识点:
html+css;
javaScript
DOM
Vue不支持IE8以下版本
Vue引入js文件:
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统-
{{}} 插值符号 里面可以写js的逻辑代码
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值
<span>Message: {{ msg }}</span>
如何创建一个Vue对象
<div id='app'>
{{message}} //显示Hello Vue!;
</div>
//创建一个Vue对象
var app = new Vue({
el:'#app', //挂载对象--> id名
//基本写法 data:保存数据
data:{
//message:
message:'Hello Vue!'
}
//ES5写法
data:function(){
}
//ES6写法
data(){
}
})
Vue指令
-
reverse() --> 反向方法
//当前对象反向后再赋值给本身
this = 当前.split('').reverse().join('');
例:
<div id="app-5">
<p>{{ message }}</p> //插入值
//点击按钮让 p标签的值反向排序
<button v-on:click="reverseMessage">反转消息</button>
</div>
//js代码
var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
//this.message.split('').reverse().join('') 反向方法及用法
this.message = this.message.split('').reverse().join('')
}
}
})
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-text指令 标签内的内容不会生效
<div>
//p标签内的内容不会显示 ,
<p v-text='Text'>我不会生效</p>
</div>
//只能解析文本,不能解析标签
<h2 v-text="Text"></h2> //显示 <i>这是文本内容</i>
new Vue({
el:'#app',
data(){
return{
//对应的键:值
Text:'<i>这是文本内容</i>'
}
}
})
3、v-html指令:
//使用v-html指令 标签内的内容不会生效
<div>
//p标签内的内容不会显示 ,
<p v-html='html'>我不会生效</p>
</div>
//可以解析标签
<h2 v-html="html"></h2> //显示 <i>这是文本内容</i>
//只能解析成变量
<h2 v-html=`html`></h2>
//如果要使用变量可以使用${} -->${html}
<h2 v-html=`${html}`></h2>
//Vue代码
new Vue({
el:'#app',
data(){
return{
//对应的键:值
html:'<i>这是文本内容</i>'
}
}
})
4、v-show指令
//DOM节点树占位置
<h3 v-show="vShow">控制是否显示</h3>
new Vue({
el:'#app',
data(){
return{
hi:'Hello Vue',
//值为true时:显示, 为false时:隐藏
vShow:true //或者的意思
}
}
})
5、v-if指令、v-if-else-if指令:
1.判断:true,false ,渲染当前的DOM节点,
相对应的6个假值:空字符串,0,NaN,null,undefined,false
这里,
v-if
指令将根据表达式islogin
的值的真假来插入/移除<p>
元素。
<div id="app">
<h1>{{des}}</h1>
<!-- 1.判断:true,false ,是否渲染当前的DOM节点 -->
<div v-if='islogin'>请输入你的爱好</div>
<!-- 2.v-if ,v-else-if,v-else的写法为兄弟选择器 -->
<div v-if="type === 'b'">女装</div>
<div v-else-if="type === '6'">小电影</div>
<!-- 最后一个else里面可以不用写值 -->
<div v-else="type===''">肾宝~~~</div>
</div>
new Vue({
el:'#app',
//ES6的写法
data(){
return{
des:'v-if',
islogin:false, //
type:'b'
}
}
})
6、v-for指令
遍历数组或者对象的一种
<ul>
<!-- 遍历数组 (item,index) item:值 ,index:下标 -->
<li v-for='(item,index) in arr' :key="item.id">{{item}} {{index}}</li>
<!-- 遍历对象 (value,key,index) value:值, key:键 ,index:下标-->
<li v-for="(value,key,index) in json1" :key="value.id">{{value}} {{key}} </li>
</ul>
扩展向后台请求数据
<ul>
<!-- 遍历数组 -->
<li v-for='item in todos' :key='item.id'>{{item.id}} {{item.title}}</li>
<li v-for="item in items" :key="item.id"></li>
</ul>
new Vue({
el:'#app',
// 请求后台发送过来的数据,进行渲染:【生命周期(钩子函数)】
// 1.解析顺序
created(){
//fetch请求网站的数据
fetch('http://jsonplaceholder.typicode.com/todos?_limit=10')
//fetch请求数据后 返回Promise
.then(res=>res.json()) //返回promise进行处理
.then(result=>{ //定义了一个result 结果集数组
//吧处理完的数组赋值给todos
this.todos = result
console.log(result)
})
},
data(){
return{
//定义一个空数组
todos:[]
}
}
})
8、v-on点击事件
用于指出一个指令应该以特殊方式绑定
<div id="app">
<h1>{{des}}</h1>
<p>{{num}}</p>
<button v-on:click='onAdd'>增加</button>
<button v-on:click='onReduce'>减少</button>
<!-- 简写 @click = '函数名' -->
<button @click='onAdd'>简写</button>
<!-- 绑定多个事件 {事件名:事件函数,事件名n:事件函数n.....} -->
<button v-on='{click:onEnter,mouseover:onAdd}'>绑定多个事件</button>
<!-- 响应键值的事件 @键盘事件名.值 如keyup:抬起/keyDown:按下/keypress:改变字符时 -->
<input type="text" value="键盘事件" @keyup.13='onEnter'>
<input type="text" value='键盘按下Enter触发事件' @keyup.enter='onEnter'>
</div>
new Vue({
el:'#app',
data:{
des:'v-on',
num:0
},
//点击事件写入
methods:{
//ES5写法
onAdd:function(){ //数字自增
this.num++;
},
//ES6写法
onReduce(){ //数字自减
this.num--;
},
onEnter(){ //键盘按键事件函数
this.num++;
}
}
})
-
v-once
只能执行一次
<button v-on:click.once='onReduce'>once</button>//按钮只能执行一次
9、阻止默认事件
<!-- @submit.stop.prevent:阻止默认事件以及冒泡事件 -->
<form action="http://www.baidu.com" @submit.stop.prevent>
<input type="submit" value="跳转百度">
</form>
10、v-bind绑定指令
v-bind:attr 动态绑定属性;加v-bind后,引号里面的内容变成变量名
属性名和变量名重复可以省略一个
<div id="app">
<h1>{{des}}</h1>
<h2>{{str}}</h2>
<!-- v-bind:动态绑定;;加v-bind后,引号里面的内容变成变量名 -->
<img v-bind:src="img" alt="">
<!-- 直接引用字符串 -->
<img v-bind:src="'./images/小图片.png'" alt="">
<!-- es5字符串拼接 -->
<img v-bind:src="'./images/'+idxImg" alt="">
<!-- 可以使用es6的反引号 ${值} -->
<img :src="`./images/${idxImg}`" alt="4">
<!-- v-bind:attr 可以简写为 :attr(属性) -->
<img :src="`${img}`" alt="5" :width='width'>
<!-- 动态绑定宽度/高度等~~~ -->
<img :src="`${img}`" alt="5" :width='width'>
<!-- 动态绑定class类名 -->
<div v-bind:class="{active,des}">动态绑定class类名</div>
<!--动态绑定json {class类名:布尔值 true显示,false消失} -->
<div :class='{xianshi:isShow,active:true}'>动态绑定class类名</div>
<!-- 使用数组绑定 -->
<div v-bind:class='["pink","red",{xianshi:isShow,active:true}]'>动态绑定class类名</div>
<!-- 绑定样式 -->
<div :style='cssObj'>动态绑定样式</div>
</div>
const str = '常量';
new Vue({
el:'#app',
//es5写法
data:{
des:'v-bind',
str,
img:'./images/小图片.png',
idxImg:'小图片.png',
width:'100',
active:'feifei',
isShow:true,
cssObj:'width:100px;height:100px;background-color:red;',
}
})
11、v-pre指令
跳过当前样式指令, 阻止Vue渲染
<div v-pre>
<p> {{des}}</p> //无法在DOM上渲染
<p v-text='hi'></p>
</div>
12、v-cloak指令
可以使用v-cloak指令 也可以自定义一个
<style>
/* 必须使用样式表的 display:none; */
/* 使用属性样式暂时隐藏 */
[v-cloak]{
display: none;
}
</style>
<!-- 防止页面未加载就显示数据 -->
<div id="app" v-cloak>
<h1>{{des}}</h1>
<p v-text="hi"></p>
<br>
</div>
全局APL
1、extend组件继承
通过extend()函数扩展一个新的组件,然后进行挂载(继承) $mount()
<div class="app">
<!-- 自定义标签 -->
<candy></candy>
</div>
const ext = Vue.extend({
//1.设定组件所需要的template模块内容
//一个对象只能写一个模块否则后面的覆盖前面的 使用反引号可以换行
template:`
<div class="div1">
<h1>这个是即将被挂载的组件</h1>
</div>
`
})
//进行挂载:
new ext().$mount('candy')
2、nextTick 延时器
延时器:相当于js中的window.load(){}
new Vue({
el:'#app',
data(){
return{
des:'nextTick',
}
}
})
//可以传入函数内容为回调函数
Vue.nextTick(function(){
//写入要执行的代码块
console.log('DOM已经渲染完成')
})
Vue.nextTick().then(()=>{
//写入要执行的代码块
console.log('DOM渲染完成,再次打印')
})
3、$set
this.$set(this.要修改的对象, 下标, 需要改变的value值) 修改相应的值
new Vue({
el:'#app',
data(){
return{
des:'$set',
arr:['天蝎座','射手座','魔蝎座','白羊座']
}
},
//点击事件写入的方法
methods:{
changClick(){
// this.$set(this.要修改的对象,下标,需要改变的value值)
this.$set(this.arr,0,'巨蟹座')
}
}
})
4、delete 删除数据
用于删除数据
new Vue({
el:'#app',
data(){
return{
des:'delete',
arr:['天蝎座','射手座','魔蝎座','白羊座'],
}
},
methods: {
changeClick() {
//调用Vue的delete方法删除
// Vue.delete(要删除的对象, index)
//this.$delete(对象,index)
Vue.delete(this.arr, 0)
},
},
})
5、directive 注册指令
directive:注册指令
<div id="app">
<h1>{{des}}</h1>
//自定义的指令名
<p v-abc='feifei'></p>
<p v-name='变量值'></p>
</div>
//directive:注册指令
//指令的自定义名称
Vue.directive('abc',function(el,bind){
console.log(el)
console.log(bind)
//原生的方法给标签赋值以及其他的样式操作
el.innerHTML = bind.value;
el.style.color='pink'
}),
Vue.directive('name',function(el,bind){
console.log(el)
console.log(bind)
//原生的方法给标签赋值以及其他的样式操作
el.innerHTML = bind.value;
el.style.color='pink'
})
new Vue({
el:'#app',
data(){
return{
des:'directive',
//给自定义的名称赋值
feifei:'feifei',
name:'需要的值'
}
}
})
6、filters筛选器
筛选器:根据需求选择合适的值
<div id="app">
<h1 v-html="des"></h1>
//通过筛选器{{msg | 函数}}来筛选条件
<h3>{{msg | myFilters}}</h3>
</div>
new Vue({
el:'#app',
data(){
return{
des:'filters筛选器',
msg:'50.22222'
}
},
//筛选器:根据需求选择合适的值
filters:{
//函数名
myFilters(value){
return parseFloat(value).toFixed(2);
}
}
})
7、component全局组件
1、注册组件的时候需要注意的事件
注册的组件名 驼峰式命名要用 ‘-’ 隔开
<div id="app">
<h1 v-text='des'></h1>
<!-- 可以都是小写 -->
<zujianming></zujianming>
<!-- 注册的组件名 驼峰式命名要用 ‘-’ 字母小写 -->
<side-bar></side-bar>
</div>
//注册组件: Vue.component('组件名',{组件的方法})
Vue.component('feifei',{
//组件的模板
template: `
<div>
<h2>要显示的全局组件 {{info}}</h2>
</div>
`,
data(){
return{
info:'全局组件的值'
}
}
})
8、components局部组件
局部组件是在Vue实例对象里面写的 , 需要加 s
局部组件如果要使用全局全局组件时要声明变量给Vue对象
<!-- 注册的组件名 驼峰是命名要用 ‘-’ -->
<a-bcd></a-bcd>
<username>字母小写<username>
let feifei; //全局中的标签名
new Vue({
el:'#app',
data(){
return{
des:'components局部组件',
}
},
//局部组件
components:{
//全局的标签名引用
feifei,
feiFei:{ //自定义的名字
template:` //模板的html标签及代码
<div>
<h2>挂载的局部组件</h2>
<p>{{info}}</p>
<feifei></feifei> //输出全局的标签信息
</div>
<a-bcd></a-bcd>
`,
data(){ //局部自身的值
return{
info:'这个是组件内部的值'
}
}
}
})
9、template模板
模板内容些HTML代码块
<template id="tpl"> //引用模板
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
</template>
//下面的内容和上面的是一样的,必须写类型,里面可以一直嵌套
<script type='text/x-template' id= 'tpl'>
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
</script>
new Vue({
el:'#app',
template:'#tpl' //挂载模板的属性
})
10、computed计算事件
用于计算数值的操作,调用时不需要加括号
computed:{
zongjia(){
var sum =0;
for(var i=0;i<this.Book1.length;i++){
sum+= parseInt(this.Book1[i].price)*parseInt(this.Book1[i].Number);
}
console.log(sum)
return sum;
}
}
11、props:父子传值
父子组件传值的关键字
HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:
以字符串数组形式列出的 props传值
<h-nav :feifei='des' :title='title' pig='猪猪'></h-nav>
//模板中传值,只能写在自己的模板中进行传值
template:`
<div>
<h2 style='color:red'>
这是h-nav组件 {{msg}}
</h2>
//相当于父组件传给子组件的值
<c-com :qiyan="qiyan"></c-com>
</div>
`,
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
使用json对象类型传值, 每个props 都有指定的值类型
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
let componentA = { //声明一个变量
template:`
<div>
<h1>这是componentA组件</h1>
</div>
`
}
let componentB = {....}
new Vue({
el:'#app',
data(){
return {
des:'component根据不同的值,显示对应的组件',
}
},
components:{
componentA, //键值和键名如果一致, 按照ES6规则 可以简写
componentB:componentB, //意思同上
}
})
12、is 判断
判断要显示的值
//componentId:变量
<component :is="componentId"></component>
new Vue({
el:'#app',
data(){
return {
des:'component根据不同的值,显示对应的组件',
componentId:componentA, //找到componentA所对应的的代码块并显示在页面中
}
},
components:{
componentA,
}
})
13、Vue引入jQuery
<script src="js/jquery-1.12.4.js"></script>
<script src="../Vue/Vue.js"></script>
<script>
//将jQuery对象引入到Vue的原型链上
Vue.prototype.$ = $;
let vm = new Vue({
el:'#app',
data(){
return{
des:'vue引入jQuery',
todos:[], //创建一个空数组的变量
}
},
//挂载过程, 挂载对象
created(){
console.log(this.$) //可以打印出Vue实例的jQuery对象
//使用 jquery 数据交互
this.$.get('http://jsonplaceholder.typicode.com/todos?_limit=10')
//接收数据
.then(res=>{
console.log(res)
this.todos = res
})
}
})
14、watch监听数据
watch:侦听检测数据:一般用于计算属性
//数据监听;和data同级
watch: {
//newValue :新的值, oldValue:旧的值
count(newValue, oldValue) {
if(newValue<0){
this.count = 0;
}
},
},
15、computed计算属性
<!-- 引用自定义名字 -->
<h4 v-text="abc"></h4>
<p v-text="res"></p>
//计算属性
computed:{
//自定义名字,并把结果返回出去
abc(){
return this.name1 + ','+this.name2
},
res(){
return this.reverse.split('').reverse().join('')
}
}
16、propsData测试检查数据
//此方法常用语测试
//写在Vue实例对象的后面
let extend = Vue.extend({
template:`
<h1>这个是生成的组件 {{count}},{{abc}}</h1>
`,
props:['count','abc'] //接收传入的实参,并渲染
})
//要在extend里面传入实参,
new extend({propsData:{count:666,abc:"自定义"}}).$mount('#app')
17、slot插槽
插槽:组件标签,原本写入内容是不显示的,可以通过slot标签来引入,
会在对象的slot标签内去显示组件定义的值
只写slot标签,没有给定名字的 叫做匿名插槽
name结合slot属性 给插槽定义有名插槽
<div id="app">
<h1>{{des}}</h1>
//自定义的组件
<feifei>
<span slot="name">飞飞</span>
<span slot="age">18</span>
<span slot="obj">object</span>
</feifei>
</div>
<template id="tpl1">
<div>
<p>我是<slot name='name'></slot></p>
<p>今年<slot name='age'></slot></p>
<p>对象:<slot name='obj'></slot></p>
</div>
</template>
18、$emit 子组件给父组件传值
需要使用$emit(‘自定义事件’,‘携带的数据’)进行子传父
//父组件
template:`
<div style="font-size:30px;">
这是父组件的模板,{{data1}}
{{name1}}
//@自定义的事件名称,后面的feifie为保存的数据内容,点击时触发的方法
<Child @handleVal="feifei"/> //子组件挂载
</div>
`,
methods:{
//触发的事件函数
//形参为 子组件传过来的值 , 并赋值给父级的一个变量
feifei(data){
console.log(data)
this.name1=data
}
},
//定义孩子的组件
components:{
Child:{
data(){
return{
data1:"子组件的数据"
}
},
//子组件的模板数据
//在子组件中定义点击事件
//@emit("自定义事件","携带的数据")
//点击的时候,发送数据
template:`
<div style="font-size:30px;">
这是子组件的模板,{{data1}}
<button @click='$emit("handleVal","传递的数据")'>儿子触发事件的按钮</button>
</div>
`,
methods: {
//发射传递的一个载体函数体
add() {
//handleVal:自定义的事件
//吧数据发射出去,
this.$emit('handleVal', value);
},
},
}
}
生命周期、UI组件的安装
1、生命周期
8个函数,4个周期,两两相对应
let vm = new Vue({
el:"#app",
data(){
return{
des:"生命周期"
}
},
//实例化组件刚创建,元素DOM和数据都还没初始化,暂时不知道能在这个周期里面进行生命操作
beforeCreate(){
console.log('实例化刚刚被创建1');
},
//数据data已经初始化完成,方法也已经调用,但是DOM没渲染,在这个周期里如果进 行请求是可以改变数据
//并渲染,由于DOM未挂载,请求过多或者占用时间过长会导致页面上空白
//此阶段一般用于请求后台的数据
created(){
console.log('实例已经创建完成2')
},
//DOM未完成挂载,数据也初始化完成,但是数据的双向绑定还是显示{{}},这是因为 Vue采用了virtual
//DOM(虚拟DOM)技术,先站住一个坑。
beforeMount(){
console.log("模板编译之前3")
},
//数据和DOM都完成挂载,在上一个周期占位的数据吧值给渲染进去,一般请求数据会 放在这个地方,
//因为请求过来的数据可以直接进行渲染。
mounted(){
console.log('模板编译完成4')
},
//只要在页面数据改变都会触发,数据更新之前,页面数据还是原来的数据,当你请求 赋值一个数据时,
//会执行这个周期的函数,如果没有数据改变不会执行。
beforeUpdate(){
console.log('数据更新之前')
},
//只要页面数据改变都会触发,数据更新完毕,这两个谨慎使用。
//在这里操作数据很影响性能,和容易死循环
updated(){
console.log('数据更新完毕')
},
//这个周期是在组件销毁之前执行
beforeDestroy(){
console.log('实例销毁之前')
},
//更换页面时执行
destroyed(){
console.log('实例销毁完成')
}
})
2、安装vue-resource
指令: cnpm install vue-resource -S 或者 cnpm install vue-resource --save
在实例对象的main.js引入包
import VueResouce from ‘vue-resouce’
Vue.use(VueResouce)
methods:{
getData(){
var apl = '请求地址'
this.$http.get(apl).then(response =>{
//给data的一变量赋值
this.dataValue = response.body;
},err=>{
console.log(err) //打印报错信息
})
}
}
3、安装axios
指令: npm install axios --save
引入模块: import Axios from ‘axios’
使用 和vue-resource一样
4、安装Mint Ui框架
指令安装: npm install mint-ui -S
引入CSS样式: import ‘mint-ui/lib/style.css’
引入Vue模板: import 自定义名 from ‘@/components/Swipe.vue(文件名后缀 .vue)’ ——@:为绝对路径的根;
5、安装element框架
指令安装: npm i element-ui -S
// 引入对象 并挂载
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
//Vue实例挂载elementUi对象
Vue.use(ElementUI);
6 .路径的引入方式
1、@默认是去src 里面找相应的路径
//例子:
import helloWorld from '@/components/HelloWorld';
2、图片的路径引入时,如果为动态变量,需要使用 require 进行引入
<img alt="vue logo" :src="img" />
//动态引入请求路径
img:require(路径);
3、波浪线的引入方法, 去module模块里面引入路径,一般不会这么写入的。
<img alt="vue logo" :src="~/abc/1.jpg" />
4、/ 斜杠 根目录到项目的public /static 的文件中找相应的路径
<img alt="vue logo" :src="/abc/1.jpg" />
5、通过import引入CSS样式
import 'element-ui/lib/theme-chali/index.css'
6、事件车;非父子组件的传值
在使用非父子组件传值的时候,如果是数据比较小的时候,使用事件车传值;
如果是企业大型开发, 使用 vuex;
//自定义的模板里面的内容 如:VueEvent.js
import Vue from 'vue';
var VueEvent = new Vue();
//事件暴露出去供其他部件使用
export default VueEvent;
import VueEvent from '@model/VueEvent.js'; //引入文件的路径
//使用发射器发送数据; $emit('自定义事件',携带的数据)
VueEvent.$emit('to-about',this.msg)
//接收发送过来的数据 $on('事件名',回调函数)
VueEvent.$on('to-about',function(data){
console.log(data)
})
路由
有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在
routes
配置中给某个路由设置名称。
//1、安装Vue-router
cnpm install vue-router --save
//安装Vue-resource
cnpm i vue-resource -S
//2、引入 vue-router
import VueRouter from 'vue-router' //引入包
Vue.use(VueRouter); //挂载到实例Vue对象中
import vueResource from 'vue-resource'
Vue.use(vueResource)
//3、引入相应的组件
import Home(自定义的名字) from './components/HelloWorld.vue';//组件的路径
import News from './components/News.vue'
//4、需要进行配置路由
let routes = [
//path:路径, component:对应的组件名
{path:'/home',component:Home},
{path:'/News',component:News},
//默认路由地址home组件; * 相当于通配符; redirect: 重定向;
{path:'*',redirect:'/home'},
//aid 自定义的 动态路由
{path:'/News/:aid',component:News},
]
//5、实例化VueRouter
let router = new VueRouter({
routes
})
//6、Vue实例中挂载路由
new Vue({
render:h=>h(App),
router //挂载VueRouter对象 router:router 可以简写
}).$mount('#app')
//7、路由在页面中进行渲染
<router-view></router-view> //简写 <router-view/>
动态路由获取 get请求值 获取 ?后面参数的值
要链接到一个命名路由,可以给
router-link
的to
属性传一个对象:
//1、相当于 a 标签的路由跳转标签<router-link to="/home">首页</router-link>
<router-link to="路由地址?aid=123"></router-link>
//2、数据加载完毕执行;生命周期函数
mounted(){
//获取aid的值
console.log(this.$route.query) //123
}
获取动态路由的值
<router-link :to='"/home"+index'>首页</router-link>
//、 aid 自定义的 动态路由要配置
<router-link :to='"/home/123"'>首页</router-link>
{path:'/News/:aid',component:News},
mounted(){
//获取动态aid的值
console.log(this.$route.params.adi)
}
1、编程式导航
除了使用
<router-link>
创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。想要导航到不同的 URL,则使用
router.push
方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。当你点击
<router-link>
时,这个方法会在内部调用,所以说,点击<router-link :to="...">
等同于调用router.push(...)
。
声明式 编程式 <router-link :to="...">
router.push(...)
//跳转一级路由
this.$router.push({path:'/news'})
//跳转二级路由
this.$router.push({path:'content/487'})
//使用name 定义路由地址
例:{path:'/news' name:'news' component:News}
//跳转路由
this.$router.push({name:'news'})
2、HTML5 History 模式
vue-router
默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用
history.pushState
API 来完成 URL 跳转而无须重新加载页面。
const router = new VueRouter({
//Vue默认为hash模式;可以手动修改为 history
mode: 'history',
routes: [...]
})
3、嵌套路由
要在嵌套的出口中渲染组件,需要在
VueRouter
的参数中使用children
配置:要注意,以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。
: 放到渲染页面的组件中
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
//嵌套路由
children: [
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 <router-view> 中
path: 'profile',
component: UserProfile
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 <router-view> 中
path: 'posts',
component: UserPosts
}
]
}
]
})
4、路由守卫
正如其名,
vue-router
提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察
$route
对象来应对这些变化,或使用beforeRouteUpdate
的组件内守卫。
-
全局守卫
全局守卫 写入在main.js中
你可以使用
router.beforeEach
注册一个全局前置守卫:当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
router.beforeEach((to, from, next) => { //判断name的值 if(to.name == 'home' || to.name== 'login'){ next() //放行 }else{ alert('请充值vip') } })
每个守卫方法接收三个参数:
- to: Route: 即将要进入的目标 路由对象
- from: Route: 当前导航正要离开的路由
-
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖
next
方法的调用参数。- next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
-
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到
from
路由对应的地址。 -
next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向
next
传递任意位置对象,且允许设置诸如replace: true
、name: 'home'
之类的选项以及任何用在router-link
的to
prop 或router.push
中的选项。 -
next(error): (2.4.0+) 如果传入
next
的参数是一个Error
实例,则导航会被终止且该错误会被传递给router.onError()
注册过的回调。
确保要调用 next 方法,否则钩子就不会被 resolved。
-
全局后置守卫
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受
next
函数也不会改变导航本身:router.afterEach((to, from) => { console.log(to); //to : 当前路由 console.log(from) //from:前一个路由 })
-
路由独享的守卫
你可以在路由配置上直接定义
beforeEnter
守卫:const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, //路由独享:哪个需要拦截 放哪个配置路由内 beforeEnter: (to, from, next) => { } } ] })
-
组件内的守卫
可以在路由组件内直接定义以下路由导航守卫:
-
beforeRouteEnter
-
beforeRouteUpdate
(2.2 新增) -
beforeRouteLeave
-
beforeRouteEnter
守卫 不能 访问this
,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当守卫执行前,组件实例还没被创建 }, beforeRouteUpdate (to, from, next) { // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 // 可以访问组件实例 `this` }, beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` } }
你可以通过传一个回调给
next
来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。beforeRouteEnter (to, from, next) { next(vm => { // 通过 `vm` 访问组件实例 }) }
注意
beforeRouteEnter
是支持给next
传递回调的唯一守卫。对于beforeRouteUpdate
和beforeRouteLeave
来说,this
已经可用了,所以不支持传递回调,因为没有必要了。beforeRouteUpdate (to, from, next) { // just use `this` this.name = to.params.name next() }
这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过
next(false)
来取消beforeRouteLeave (to, from , next) { const answer = window.confirm('Do you really want to leave? you have unsaved changes!') if (answer) { next() } else { next(false) } }
-
Vuex的使用
1、安装
npm install vuex --save
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
安装 Vuex 之后,让我们来创建一个 store。创建过程直截了当——仅需要提供一个初始 state 对象和一些 mutation:
方法都要加上 s
//2、引入Vuex的组件包 代码都存入在一个 .js的文件内
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//3、state 要用于存储数据
var state ={
count:0
}
1、mutations的方法
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
//4、mutations
用于放方法,主要用于改变state里面的值
var mutations = {
increment(){
state.count++
}
}
//5、vuex提供的store的方法,(类似于仓库)
var store = new Vuex.Store({
//挂载
state:state,
mutations:mutations,
})
//6、暴露出去
export default store
//this.$store.state.count : 获取定义的vuex的属性值
<h2>{{this.$store.state.count}}</h2>
//哪个组件内使用就直接引用
//引入vuex的store(库)的文件
import store from 'vuex/store.js'//路径
//1、进行挂载
export default{
data(){
return{
}
},
store,//挂载
//点击事件
methods:{
increment(){
//commit('传入要调用的方法名字')
this.$store.commit('increment');
}
}
}
2、getters 的方法 挂载对象
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
getters: {
computedCount: (state) => {
return state.count*5; //返回 count *5的值
}
}
var store = new Vuex.Store({
//挂载
state:state,
mutations:mutations,
getters:getters
})
//获取计算后返回的值 computedCount:getters定义的方法
this.$store.getters.computedCount
3、actions 的方法
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
actions: {
increment (context) {
//监控 mutations里面的方法, 传入参数 :increment
context.commit('increment')
}
}
var store = new Vuex.Store({
//挂载
state:state,
mutations:mutations,
getters:getters,
actions:actions,
})
//在对应的组件内的方法体里面 尽兴 分发Action的方法
Action 通过 store.dispatch 方法触发:
store.dispatch('increment') //传入actions里面的方法
//main.js内 引入数据处理的方法
import VueResource from 'vue-resource'
Vue.use(VueResource)
//引入路由模块化 。。。。。。
。。。
4、防止多次请求数据,优化服务器
var state = {
count =0,
list=[]
}
//请求数据内的代码
mounted(){
var listData = this.$store.state.list;
if(listData.length > 0){
this.list = listData;
}else{
//调用请求数据
。。。。
}
}
扩展向后台请求数据
使用 fetch(‘路径’) 请求数据
<ul>
<!-- 遍历数组 -->
<li v-for='item in todos' :key='item.id'>{{item.id}} {{item.title}}</li>
<li v-for="item in items" :key="item.id"></li>
</ul>
new Vue({
el:'#app',
// 请求后台发送过来的数据,进行渲染:【生命周期(钩子函数)】
// 1.解析顺序
created(){
//fetch请求网站的数据
fetch('http://jsonplaceholder.typicode.com/todos?_limit=10')
//fetch请求数据后 返回Promise
.then(res=>res.json()) //返回promise进行处理
.then(result=>{ //定义了一个result 结果集数组
//吧处理完的数组赋值给todos
this.todos = result
console.log(result)
});
},
data(){
return{
//定义一个空数组
todos:[]
}
}
})
使用$http.jsonp(‘路径’) 请求数据
mounted(){
console.log( this.$route.params )
// 1.保存每次传入进来的***;
let aid = this.$route.params.aid
// 2.执行,携带参数
this.requestData(aid)
},
methods:{
//3.请求数据
requestData(aid){
let api = "http://www.phonegap100.com/appapi.phpa=getPortalArticle&aid="+aid;
console.log( api )
this.$http.jsonp( api )
.then(res => {
// get body data
// this.someData = response.body;
console.log( res.body.result[0] )
this.list = res.body.result[0]
}, err => {
// error callback
console.log( err )
});
}
},
使用axios(路径) 请求数据
axios('http://jsonplaceholder.typicode.com/todos?_limit=10')
//({ data }) 结构用法, 可以省去 data.data 不必要的步骤
.then(({ data })=>{
console.log(data) //data的数据
})
下一篇: 判断一棵二叉树是否是平衡二叉树