<div id="app">
<h1>你好,我是{{name}}</h1>
</div>
<script>
// Vue.config.productionTip = false;
const x = new Vue({
el: '#app', //el指定当前Vue为实例化哪个对象
data() {
return {
name: '张三',
age: 20
};
},
});
</script>
//分析,一个容器交给一个vue实例去处理,他们之间的关系是一一对应,他们分别对应第一个
//{{}}之间可以写入的是什么,{{}}里边只可以写js代码0】
//(1)表达式 a a+b x==y?'a':'b'
//(2)js代码 if(){} for(){}
总结
Vue模板语法分为2大类:
<div id="root">
单向绑定:<input type="text" v-bind:value="school.name">
双向绑定:<input type="text" v-model:value="school.name">
简写
单向绑定:<input type="text" :value="school.name">
双向绑定:<input type="text" v-model="school.name">
</div>
<script>
// Vue.config.productionTip = false;
const x = new Vue({
el: '#root', //el指定当前Vue为实例化哪个对象
data() {
return {
uname: '张三',
age: 20,
url: "https://www.baidu.com/",
school: {
name: '河南科技学院'
}
};
},
});
</script>
Vue中有两种数据绑定
el有两种写法
data有两种写法
对象式
函数式
如何选择:目前用哪种都可以,在学习函数组件时,data必须要用函数式,否则会报错
一个重要原则
由Vue管理的函数一定不要用箭头函数,箭头函数没有自己的this
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YT8rVA4B-1666772187950)(img/image-20220906213326911.png)]
let number = 13;
let person = {
name: '张三',
sex: '男',
adress: '郑州'
}
Object.defineProperty(person, 'age', {
// value: 19,
// enumerable: true, //控制属性是否可可以枚举,默认值式false
// writable: true, //控制属性是否可以被修改,默认值式false
// configurable: true //控制属性是否被删除
//get函数,当读取person的age属性时,get函数自动会被调用
get() {
return number
},
//set函数,当修改person的age属性时,set函数自动会被调用
set(value) {
number = value;
console.log('有人修改了person的age值是' + value);
}
})
console.log(person);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CmqzKqIH-1666772187951)(img/image-20220907092507149.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nH42stzQ-1666772187952)(img/image-20220907153424087.png)]
<div id="app">
<h1>开始练习</h1>
<button @click="showInfo1">点我提示信息(不传参)</button>
<!-- 采用占位符号$ -->
<button @click="showInfo2(18,$event)">点我提示信息(传参)</button>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
property: 'value',
};
},
methods: {
showInfo1(event) {
console.log(event.target);
},
showInfo2(number, e) {
console.log(number, e.target);
}
}
})
</script>
Vue常用的事件修饰符,修饰符可以连续写
<div id="app">
<h1>开始练习</h1>
<!-- 阻止事件默认行为,a标签的默认行为是跳转 -->
<a href="http://www.baidu.com" @click.prevent="a">点我进行页面跳转</a>
<!-- 阻止事件冒泡 -->
<div class="box1" @click.stop="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<!-- 事件只触发一次 -->
<div id="demo" @click="showInfo">
<button @click.once="showInfo">点击触发事件</button>
</div>
<!-- 使用事件捕获模式 -->
<div class="box1" @click.="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<!-- 使用事件捕获模式 -->
<div class="box1" @click.capture="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<!-- 点击div1才触发 -->
<div class="box1" @click.self="showMsg(1)">
div1
<div class="box2" @click="showMsg(2)">
div2
</div>
</div>
<!-- 两种滑动滚轮的方式,scroll和wheel;
scoll默认事件和回调函数一起执行
wheel是执行回调函数后执行默认事件
-->
<ul class="ull" @scroll="move">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
property: 'value',
};
},
methods: {
a() {
alert('我可以跳转到百度')
},
showInfo(event) {
alert('Hello World ')
},
showMsg(number) {
alert('输出的值是' + number)
},
move() {
console.log('滚动了');
}
}
})
</script>
<div id="app">
<h1>开始练习</h1>
<input type="text" placeholder="按下回车提示输入信息" @keyup.enter="showInfo">//事件按键,只有按下回车键才会触发
</div>
<script>
new Vue({
el: '#app',
data() {
return {
property: 'value',
};
},
methods: {
showInfo(e) {
console.log(e.key, e.keyCode);
}
}
})
</script>
Vue中常见的按键别名:
回车(enter)
删除(delete)
退出(esc)
空格(space)
换行(tab)
上(up)
下(down)
左(left)
右(right)
<div id="app">
<h1>开始练习</h1>
姓:<input type="text" v-model="fistName"><br/><br/> 名:
<input type="text" v-model="lastName"><br/><br/> 全名:
<span>{{fullName}}</span>
</div>
<script>
const vm = new Vue({
el: '#app',
data() { //只要data中的数据改变,vue一定会重新解析模板
return {
fistName: '张',
lastName: '三'
};
},
// 计算属性
computed: {
fullName: {
//get有什么用,当有人调用或者修改fullName中的属性时会调用
get() {
console.log('get被调用了');
return this.fistName + '-' + this.lastName;
},
//当修改fullName属性时,set方法被调用
set(value) {
console.log('set方法被调用');
let arr = value.split('-');
this.fistName = arr[0];
this.lastName = arr[1];
}
}
}
})
</script>
计算属性:
<div id="app">
<h1>开始练习</h1>
<h2>今天天气很{{weather}}</h2>
<button @click="changWeather">点击我更改天气</button>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
isHot: true
}
},
computed: {
weather: function() {
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
changWeather() {
this.isHot = !this.isHot
}
},
//配置监视,完整形式
watch: {
//当isHot别修改时触发函数
isHot: {
immediate:true,//初始化时让handler调用一下
deep:true,//深度监视
handler() {
console.log('isHot被修改了');
}
}
}
//简写监视
watch: {
//如果配置项中只有handler,可以用简写
isHot(newValue,oldValue){
console.log('isHot被修改了');
}
}
})
</script>
监视属性watch:
<div id="app">
<h1>开始练习</h1>
<h2>
a的值是:{{number.a}}
</h2>
<button @click="number.a++">点我让a++</button>
<h2>
b的值是:{{number.b}}
</h2>
<button @click="number.b++">点我让b++</button>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
number: {
a: 1,
b: 2
}
}
},
//配置监视
watch: {
//当isHot别修改时触发函数
'number.a': {
//监视多级结构中所有属性的变化
deep: true,
handler() {
console.log('a改变了');
}
}
}
})
</script>
深度监视:
备注:
computed 和 watch之间的区别:
两个小原则:
<div id="app">
<h1>开始练习</h1>
<input type="text" :value="fullName"><br>
<button @click="changMood">点击更换姓名</button>
<!--class绑定样式字符串法,适用于:样式的类名不确定,需要动态指定 -->
<div class="basic" :class="color" @click="changeColor">点击更换颜色</div>
<!-- class绑定样式数组法,适用于要绑定的个数不确定,名字也不确定 -->
<div class="basic" :class="arr" >更换颜色</div>
<!-- class绑定样式对象法,适用于要绑定的个数不确定,名字也不确定 -->
<div class="basic" :class="classObj" >更换颜色</div>
<!-- style绑定样式对象法,适用于要绑定的个数不确定,名字也不确定 -->
<div class="basic" :style="styleObj" >更换颜色</div>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
fullName: '张三',
color: 'normal',
arr: ['style1', 'style2', 'style3'],
classObj: {
style1: false,
style2: false
},
styleObj: {
//根据系统的改变,系统的有font-size等
fontSize: '50px',
backgroundColor: 'yellow',
fontColor: 'gray'
}
}
},
methods: {
changMood() {
this.fullName = '王五'
},
changeColor() {
const arr = ['happy', 'sad', 'normal']
let index = Math.floor(Math.random() * 3)
this.color = arr[index];
},
}
})
</script>
<div id="app">
<h1>开始练习</h1>
<h2>a={{a}}</h2>
<button @click="a++">点击我实现a++</button>
<h2 v-show="false">我来自{{adress}}1</h2>
<!-- 中间结构不能够打断 -->
<h2 v-if="a==1">第一</h2>
<h2 v-else-if="a==2">第二</h2>
<h2 v-else-if="a==3">第三</h2>
<h2 v-else>第四</h2>
<!-- template只能和v-if配合使用 -->
<template v-if="n==1">
<h3>北京</h3>
<h3>上海</h3>
<h3>广州</h3>
</template>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
adress: '河南省',
a: 0
}
},
})
</script>
react、vue、中的key什么用
虚拟DOM中key的作用
新虚拟DOM与旧虚拟DOM对比原则
用index和key可能引发的问题
若对数据进行:逆序添加、逆序删除等破坏顺序的操作:
会产生没有必要的真实DOM更新==>界面效果没问题,但效率低
如果结构还包含输入类的DOM:
会产生错误DOM更新==》界面有问题
开发中如何选用key?
<div id="app">
<h1>开始测试</h1>
<input type="text" placeholder="进行筛选" v-model="keyWord">
<button @click="sortType=2">年龄升序</button>
<button @click="sortType=1">年龄降序</button>
<button @click="sortType=0">原顺序</button>
<ul>
<li v-for="p in filPersons">
{{p.name}}--{{p.age}}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
keyWord: '',
sortType: 0,
persons: [
{id: '001',name: '周杰伦',age: 23},
{id: '002',name: '张望伦',age: 18},
{id: '003',name: '张三丰',age: 35},
{id: '003',name: '周找天',age: 19}
],
}
},
//computed实现
computed: {
filPersons() {
const arr = this.persons.filter((p) => {
return p.name.indexOf(this.keyWord) != -1
})
if (this.sortType) {
arr.sort((p1, p2) => {
return this.sortType == 2 ? p1.age - p2.age : p2.age - p1.age
})
}
return arr
}
},
})
</script>
数据更改==》set()调用,set里写了个调用重新解析模板==》生成新的虚拟DOM==》新旧虚拟DOM对比==》生成真实页面
vue会监视data中所有层次的数据
如何仅是对象中的数据
如何检测数组中的数据
通过包裹数组更新元素的方式实现
Vue中修改数组中某个元素一定用到如下方法:
API:push(),pop(),shift(),unshift(),splice(),sort(),reverse()
Vue.set()或者vm.$set()
<div id="app">
<form @submit.prevent="demo">
<label for="account">账号</label><input type="text" id="account" v-model.trim="account">
<label for="ps">密码</label><input type="text" id="ps" v-model="password">
<label for="age">年龄</label><input type="number" id="age" v-model.number="age">
性别:
男<input type="radio" name="sex" value="male" v-model="sex">
女<input type="radio" name="sex" value="female" v-model="sex">
爱好:
学习<input type="checkbox" v-model="hobby" value="study">
打游戏<input type="checkbox" v-model="hobby" value="game">
吃饭<input type="checkbox" v-model="hobby" value="eat">
所属校区
<select v-model="city">
<option value="beijing" >北京</option>
<option value="shenzhen" >深圳</option>
<option value="wuhan" >武汉</option>
</select><br><br> 其他信息
<textarea v-model.lazy="other"></textarea>
<input type="checkbox" v-model="agree">
阅读并接受<a href="http://www.baidu.com">《用户协议》</a>
<button>提交</button>
</form>
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
account: '',
password: '',
age: '',
sex: '',
hobby: [],
city: 'beijing',
other: '',
agree: ''
}
},
methods: {
demo() {
console.log(JSON.stringify(this._data));
}
},
})
</script>
若: , 则v-model收 集的是value值,用户输入的就是value值。
若: , 则v-model收 集的是value值,且要给标签配置value值。
若:
1.没有配置input的value属性,那么收集的就是checked (勾选or未勾选,是布尔值)
2.配置input的value属性:
(1 )v - model的初始值是非数组,那么收集的就是checked (勾选or未勾选,是布尔值)
(2 )v- model的初始值是数组,那么收集的的就是value组成的数组
备注: v-model的 三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过
v-once在初次动态渲染后就视为静态内容了
以后数据的改变不会引起v-once所在结构的更新
v-pre可以跳过节点的编译过程
可以用它跳过:没用使用指令的语法,没用使用插值的语法节点,会加快编译
需求1:定义一个v-big指令, 和v-text功能类似,但会把绑定的数值放大10倍。
需求2:定义-一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
自定义指令总结:
定义语法:
局部指令:
new Vue({
directives:{指令名:配置对象}
})//或者
new Vue({
directives:{指令名,回调函数}
})//或者
2.全局指令:
Vue.directive(指令名,配置对象)或Vue . directive(指令名,回调函数)
配置对象中常用的3个回调:
备注:
div id="app">
<h1>当前数字是:{{n}}</h1>
<button @click="n++"></button>
</div>
<script>
const vm = new Vue({
el: '#app',
//vue完成真实的解析并把真实的DOM元素放入页面之后,调用mounted
data() {
return {
n: 1,
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted', this);
},
//数据和页面未保持同步
beforeUpdate() {
console.log('beforeUpdate');
},
updated() {
console.log('updated');
},
//数据所做的所有操作不做更新
beforeDestroy() {
console.log('beforeDestroy');
},
destroyed() {
console.log('destroyed');
},
})
</script>
常用的生命周期函数
关于销毁Vue实例
Vue中使用组件的三大步骤
如何定义一个组件
如何注册组件?
编写组件标签
<div id="app1">
<h1>{{msg}}</h1>
<hr>
//第三步,调用组件
<xuexiao></xuexiao>
<hr>
<div id="app2">
<hello></hello>
</div>
</div>
<script>
//第一步,定义组件
const school = Vue.extend({
template: `
学校名称:{{schoolName}}
学校地址:{{address}}
`,
data() {
return {
schoolName: '科技学院',
address: '新乡',
}
},
})
//全局注册组件
Vue.component('hello', hello)
new Vue({
el: '#app1',
data() {
return {
msg: '你好啊'
}
},
components: {
//第二步,配置组件
xuexiao: school,
}
})
</script>
<div id="app1">
<app></app>
</div>
<script>
const student = {
name: 'student',
template: `
学生姓名:{{studentName}}
`,
data() {
return {
studentName: '小明',
}
},
}
const school = Vue.extend({
template: `
学校名称:{{schoolName}}
学校地址:{{address}}
`,
data() {
return {
schoolName: '科技学院',
address: '新乡',
}
},
components: {
student,
}
})
const app = Vue.extend({
template: `
`,
components: {
school
}
})
new Vue({
el: '#app1',
data() {
return {
msg: '你好啊'
}
},
components: {
//school:school
app
}
})
</script>
school组件的本质时一个名为VueComponent的构造函数,且不是程序员定义的,时Vue.extend生成的
我们只需要写或者,Vue解析时会帮助我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)
特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent!!!
关于this的指向
组件配置中:
data函数,methods中的函数,watch中的函数,computed中的函数 他们的this是VueComponent实例对象
new Vue()配置中
data函数,methods中的函数,watch中的函数,computed中的寒素,他们的this是Vue实例对象
vueComponent实例对象,简称vc
class Student {
constructor(name, score) {
this.name = name;
this.score = score;
}
introduce() {
console.log(`我是${this.name},考了${this.score}分。`);
}
}
const student = new Student('张三', '99');
console.log(student.__proto__ === Student.prototype);
实例对象(student)的隐式原型对象 === 构造函数(Student)的显示原型对象
统统指向原型对象
vue.component.prototype.(proto)==Vue.prototype
结论:让VueComponent的实例对象(vc)可以使用Vue原型上的属性和方法
学校名称:{{schoolName}}
学校地址:{{address}}
Vue.config.productionTip = false
//使用vue的插件
new Vue({
el: '#app',
render: h => h(App),
// render :q =>q('h1','你好啊')
// render :createElentment =>createElement('h1','你好啊')
// render :createElentment =>{
// return createElement('h1','你好啊')
// }
// render(createElement){
// return createElement('h1','你好啊')
// }
})
一种通信的方式:适用于子组件传给父组件
注意:父传子props最方便
使用场景:A是父组件,B是子组件,B想给A传数据那么需要在A中给B绑定自定义事件
绑定自定义事件:
第一种方式,父组件中:
第二种方式,在父组件中
<School ref="school" />
mounted () {
this.$refs.school.$on('dizhi', this.sendSchoolAddress)
},
若想让自定义事件只触发一次可以用once修饰符,或者$once方法
出发绑定事件:this.$emit(‘haha’,数据)
解除绑定自定义事件this.$off(‘haha’)
组件想使用原生的DOM事件(指原有的事件例如@click)需要使用native修饰符
安装全局事件总线
//在main文件中
new Vue({
el: '#app',
render: h => h(App),
/*
在vue的实例对象对象上放置一个$bus来作为传输数据的对象
$bus书写规范
*/
beforeCreate() {
Vue.prototype.$bus = this; //在vue的实例对象对象上放置一个$bus来作为传输数据的对象
},
})
使用全局时间总线
//绑定这个时间
methods(){
this.$bus.$emit('changeTodo', id)
}
//使用这个时间
mounted(){
this.$bus.$on('changeTodo', this.demo)
}
安装第三方库 npm i pubsub-js
引入: import pubsub from ‘pubsub-js’
//发送数据
sendStudentAge () {
pubsub.publish('hello', 666)
},
//订阅(接受)数据
mounted () {
pubsub.subscribe('hello', (a, b) => {
console.log('我是订阅函数,它的数据是' + a, b);
console.log(this);
})
},
元素准备样式
元素进入
v-enter:进入的起点
v-enter-active:进入的过程
v-enter-to:进入的终点
元素的离开
v-leave:进入的起点
v-leave-active:进入的过程
v-leave-to:进入的终点
使用包裹过度的元素,并经行name配置
如果有多个元素需要过度,则需要用,且每哥元素需要用key指定
在vue.config.js中添加如下配置
devServer: {
proxy: {
'/api': {//匹配有所以'/api'开头的路径
target: 'http://localhost:8081',//代理请求的端口
pathRewrite:{'^/api':''}//将第一个匹配的标识改为空
ws: true,
changeOrigin: true //告诉请求地址自己的路径,true代表和他的路径一样
},
'/foo': {
target: ''
}
}
}
在标签内部放入内容(默认插槽)
//输入内容
<template>
<div class="contain">
//当需要指定位置的时候需要定义插槽标签
<Category solt="center" title="美食" :listData="foods">
<input type="text" value="我是小李子" />
</Category>
</div>
</template>
//告诉放置的位置,在Category中
<template>
<div class="card">
<h2>{{ title }}</h2>
<ul>
<li v-for="(item, index) in listData" :key="index">
{{ item }}
</li>
//定义插槽的名称,一一对应
<slot name="center"></slot>
</ul>
</div>
</template>
在components中
<template>
<div class="card">
<h2>{{ title }}</h2>
<ul>
<li v-for="(item, index) in listData" :key="index">
{{ item }}
</li>
//从插槽中向调用插槽的传递数据
<slot :games="games"></slot>
</ul>
</div>
</template>
<script>
export default {
name: 'Category',
data() {
return {
games:['游戏1','游戏2','游戏3']
}
},
props: ['title', 'listData']
}
</script>
调用插槽者
<template>
<div class="contain">
<Category title="美食" :listData="foods">
<template scope='data'>//新版版为slot-scope
<ul>
<li v-for=" (g,index) in data.games" :key="index"></li>
</ul>
</template>
</Category>
</div>
</template>
##窗口执行
npm install -g @vue/cli
Vue中的配置对象(以pages举例)
module.exports = {
pages: {
index: {
// page 的入口
entry: 'src/index/main.js',
// 模板来源
template: 'public/index.html',
// 在 dist/index.html 的输出
filename: 'index.html',
// 当使用 title 选项时,
// template 中的 title 标签需要是 <%= htmlWebpackPlugin.options.title %>
title: 'Index Page',
// 在这个页面中包含的块,默认情况下会包含
// 提取出来的通用 chunk 和 vendor chunk。
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
// 当使用只有入口的字符串格式时,
// 模板会被推导为 `public/subpage.html`
// 并且如果找不到的话,就回退到 `public/index.html`。
// 输出文件名会被推导为 `subpage.html`。
subpage: 'src/subpage/main.js'
}
}
别用来给元素或子组件注册引用的信息(id的替换者)
应用在html标签上获取的真实DOM元素,应用在组件标签上的组件实例对象(vc)
使用方式
打标识:
获取:this.$refs.xxx
<template>
<div>
<h1 ref="title">点我展示上方元素</h1>
<button @click="showDom">展示上方元素</button>
<Add ref="add"></Add>
</div>
</template>
<script>
import Add from './components/Add'
export default {
name: 'App',
components: { Add },
methods: {
showDom () {
console.log(this.$refs.title);
console.log(this.$refs);
console.log(this.$refs.add);
}
},
}
</script>
//-------定义组件
<template>
<div>
<!-- 组件的结构 -->
<h1>我的个人信息是</h1>
<h2>学生名称:{{ name }}</h2>
<h2>学生年龄:{{ age }}</h2>
<h2>学生学校:{{ school }}</h2>
·
</div>
</template>
<script>
export default {
name: 'student-name',
// props: ['name', 'age', 'school'],第一种
/*第二种
props: {
name: String,
age: Number,
school: String
}, */
//对接受数据的同时对数据进行限制
props: {
name: {
type: String,//类型String
required: true,//必须要填写
},
age: {
type: Number,
default: 99
},
school: {
type: String,//类型String
required: true,//必须要填写
}
},
}
</script>
//----------使用组件
<template>
<div>
<student-name name="李华" :age="15" school="科技学院"></student-name>
</div>
</template>
<script>
import StudentName from './components/Student.vue'
export default {
name: 'App',
components: {
'student-name': StudentName
}
}
</script>
功能:让组件接受外部传入的数据
备注:props是只读属性,Vue底层会检测你对props的修改,如果进行了修改,就会发出警报,若业务需要对数据的修改,那么请复制props的内容一份送到data中,让后去修改data中的数据
功能:可以把多个组件共有的配置提供成一个混入对象
使用方式:
第一步定义混合
{
data(){
},
methods:{
}
}
第二步使用混入
(1)全局的混入,Vue.mixin(xx)
(2)局部的混入,mixins:['xxx']
//定义
export const m = {
methods: {
showName() {
alert(this.name)
}
},
mounted() {
console.log('你好啊')
},
}
//使用
<script>
import { m,number } from "../mixin"
export default {
name: "xue-xiao",
data () {
return {
// 传入的值不能修改
name: "科技学院",
address: "新乡市",
}
},
mixins: [m,number]
};
</script>
功能:用于增强Vue
本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传入的数据。
定义插件:
export default {
//shi'yong'hsi
install(Vue, x) {
console.log(x);//传入的参数,可以是多个
Vue.filter('mySlice', function(value) {
return value.slice(0, 5)
})
Vue.directive('fbind', {
})
//Vue混入方法
Vue.mixin({
})
Vue.prototype.hello = () => {
}
}
}
使用插件
概念:专门在Vue中实现集中式状态管理的一个Vue插件,对vue应用中多个组件的共享进行集中式的管理(读与写),依旧是一种通信的方式,且适用于任意组件间的通信
什么时候用(共享)
使用路由
//在main.js中
import VueRouter from 'vue-router'
import router from './router/index'//引入路由配置文件
Vue.use(VueRouter)
new Vue({
el: '#app',
render: (h) => h(App),
router: router, //!!!!!
beforeCreate() {
Vue.prototype.$bus = this;
}
})
配置路由(也可以用懒加载的方式)
import VueRouter from 'vue-router'
export default new VueRouter({
routes: [
{//路由重定向
path: '/',
redirect: '/Login/User'
},
{
path: '/Login',
name: 'Login',
component: Login,
children: [{//子路由
path: 'User',
component: User
},
{
path: 'Register',//注意这里没有'/'
component: Register
},
]
},
{
path: '/Todo/:name',
name: 'Todo',
component: Todo,
},
]
})
路由标签
<router-link to="/Login/User" class="select" active-class="active">登录区</router-link\>
//标签最后会被解析为a标签
//to为跳转的路径
//active-class为选中当前路径标签所具有的样式
<router-view></router-view>
//可以展示选中标签中的nei'rong
传递参数
Params传参
//一、声明式
//子路由配置
{
path: '/child/:id',
component: Child
}
//父路由组件
<router-link :to="/child/123">进入Child路由</router-link>
//二、编程式
//子路由配置
{
path: '/child/:id',
component: Child
}
//父路由编程式传参(一般通过事件触发)
this.$router.push({
path:'/child/${id}',//这里是es6表达方式
})
//三、对象传递(这种方式地址中不显示参数)
<router-link :to="{name:'Child',params:{id:123}}">进入Child路由</router-link>
//获取
{{this.$route.params.id}}
query传参
//这种传参不需要更改路由配置
//一、声明式
{
path: '/child',
component: Child
}
<router-link :to="{path:'/child',query:{id:123}}">进入Child路由</router-link>
//二、编程式
this.$router.push({
name:'Child',
query:{
id:123
}
})
//获取参数
{{this.$route.query.id}}
注意对象传参中path配query; name配params;!!!否则接收不到参数
即使用params参数时,若使用to对象写法,则不能使用path配置项,必须使用name配置
路由的两个钩子函数
//路由仅有的两个钩子
//当路由组件激活的时候触发(从没有到有)
activated(){}
//当路由组件失活的时候触发(从有到没有)
deactivated(){}
对于一个url来说什么是hash值?——#以及后必拿的内容时hash值
hash值不会包含在http请求中,即:hash值不会带给服务器
hash模式:
history模式:
地址干净,美观
兼容性和hash模式相比略差
应用部署上线时需要后端人员支持,解决页面服务器404的问题
},
{
path: '/Todo/:name',
name: 'Todo',
component: Todo,
},
]
})
路由标签
<router-link to="/Login/User" class="select" active-class="active">登录区</router-link\>
//标签最后会被解析为a标签
//to为跳转的路径
//active-class为选中当前路径标签所具有的样式
<router-view></router-view>
//可以展示选中标签中的nei'rong
传递参数
Params传参
//一、声明式
//子路由配置
{
path: '/child/:id',
component: Child
}
//父路由组件
<router-link :to="/child/123">进入Child路由</router-link>
//二、编程式
//子路由配置
{
path: '/child/:id',
component: Child
}
//父路由编程式传参(一般通过事件触发)
this.$router.push({
path:'/child/${id}',//这里是es6表达方式
})
//三、对象传递(这种方式地址中不显示参数)
<router-link :to="{name:'Child',params:{id:123}}">进入Child路由</router-link>
//获取
{{this.$route.params.id}}
query传参
//这种传参不需要更改路由配置
//一、声明式
{
path: '/child',
component: Child
}
<router-link :to="{path:'/child',query:{id:123}}">进入Child路由</router-link>
//二、编程式
this.$router.push({
name:'Child',
query:{
id:123
}
})
//获取参数
{{this.$route.query.id}}
注意对象传参中path配query; name配params;!!!否则接收不到参数
即使用params参数时,若使用to对象写法,则不能使用path配置项,必须使用name配置
路由的两个钩子函数
//路由仅有的两个钩子
//当路由组件激活的时候触发(从没有到有)
activated(){}
//当路由组件失活的时候触发(从有到没有)
deactivated(){}