快速入门
环境配置
获取vue.js文件
前往 官网 下载vue2
去除浏览器提示
1.浏览器下载开发者工具
2.html中js脚本关闭生产提示
<script>
Vue.config.productionTip = false //关闭生产vue提示
</script>
基本使用
创建容器
el的其他写法
<script>
Vue.config.productionTip = false //关闭生产vue提示
const v = new Vue({
// el:"#app",
data: {
name: "miaolme"
}
})
// 1s后执行
setTimeout(() => {
v.$mount("#app") //设置el
}, 1000);
</script>
data的两种写法
函数式
//1. 创建vue核心对像
new Vue({
el:"#app",
data: function(){
return {
username:""
}
}
});
简写
//1. 创建vue核心对像
new Vue({
el: "#app",
data() {
return {
username: ""
}
}
})
例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue使用</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<div id="app">
<input v-model="username">
<!-- 插值表达式 -->
{{username}}
</div>
</body>
<script>
//1. 创建vue核心对像
new Vue({
el: "#app",
data() {
return {
username: ""
}
}
})
</script>
</html>
Vue常用指令
指令:HTML标签上带有V-前缀的特殊属性,不同指令具有不同含义
指令 | 作用 |
---|---|
v-bind | 为HTML标签绑定属性值,如设置href ,css 样式等 |
v-model | 在表单元素上创建双向数据绑定 |
v-on | 为HTML标签绑定事件 |
v-if v-else v-else-if | 条件性的渲染某元素,判定为true时渲染,否则不渲染 |
v-show | 根据条件展示某元素,区别在于切换的是display属性的值 |
v-for | 列表渲染,遍历容器的元素或者对象的属性 |
v-model
v-model 在表单元素上创建双向数据绑定
表单的变化会影响整个vue的设定值
v-bind
修改href,css
等样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue使用</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<div id="app">
<a v-bind:href="url">点击一下</a>
<br>
<a :href="url">简化格式</a>
</div>
</body>
<script>
//1. 创建vue核心对像
new Vue({
el: "#app",
data() {
return {
username: "",
url: "https://baidu.com"
}
}
})
</script>
</html>
v-on
定义事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue使用</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<!-- 这个div中的id决定了下方vue是否可用 -->
<div id="app">
<input type="button" value="一个按钮" v-on:click="show()">
<br>
<!-- 简化书写 -->
<input type="button" value="第二个按钮" @click="show()">
</div>
</body>
<script>
//1. 创建vue核心对像
new Vue({
el: "#app",
data() {
return {
username: "",
url: "https://baidu.com"
}
},
methods: {
show() {
alert("我被点中了",number)
}
}
/*
methods: {
show(number) { //可以传参
alert("我被点中了",number)
}
}
*/
})
</script>
</html>
<input type="button" value="一个按钮" v-on:click="show()">
<!-- 简化书写 -->
<input type="button" value="第二个按钮" @click="show()">
v-for
列表渲染,遍历容器的元素或者对象的属性
v-for:
<div v-for='addr in addrs'>
{{addr}}<br>
</div>
加索引
<div v-for="(addr,i) in addrs">
<!-- i表示索引,从0开始 -->
{{i + 1}}:{{addr}}<br>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<div id="app">
<div v-for="addr in addrs">
{{addr}} <br>
</div>
<hr>
<div v-for="(addr,i) in addrs">
{{i+1}}--{{addr}} <br>
</div>
</div>
</body>
<script>
new Vue({
el: "#app",
data() {
return {
addrs: ["北京", "上海", "天津"]
}
}
})
</script>
</html>
Vue数据代理
对象添加数据
Object.defineProperty
<script>
let person = {
name: "张三",
sex: "男"
}
Object.defineProperty(person, 'age', {
value: 18 //往person对象中添加一个新的键值对 age:18
enumerable: true //控制属性是否可枚举,默认false
writable: true //控制属性是否可用被修改,默认false
configurable: true //控制属性是否可被删除,默认false
})
console.log(person) //{name: '张三', sex: '男', age: 18}
</script>
默认:不可枚举,不可遍历,不可修改,不可删除
let person = {
name: "张三",
sex: "男"
}
let number = 18
Object.defineProperty(person, 'age', {
/*
get: function () {
return number //每次调用age的值会返回number
}
*/
//简写
get(){
return number //每次调用age的值会返回number
},
//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value){
console.log('有人修改了age属性,且修改的值是',value)
number = value
}
})
console.log(person)
事件处理
new Vue({
el: "#App",
data: {
name: 'xingli'
},
methods: {
showInfo(e) {
console.log(e.target.value)
}
},
})
方法写入method中
v-on
用于事件绑定,可以用@代替 例如@click
@click.stop 停止事件冒泡
Vue中的事件修饰符: 1.prevent:阻止默认事件(常用); 2.stop:阻止事件冒泡(常用); 3.once:事件只触发一次(常用); 4.capture:使用事件的捕获模式; 在事件捕获阶段进行事件处理,自上而下 5.self:只有event.target是当前操作的元素是才触发事件; 6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
键盘事件
绑定vue按键事件的@
常用@keydown
@keyup
Vue中常用的按键别名:
- 回车=>enter
- 删除=>delete(捕获“删除”和“退格”键)
- 退出=>esc
- 空格=>space
- 换行=>tab
- 上=>up
- 下=>down
- 左=>left
- 右=>right
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<div id="App">
<input type="text" placeholder="按下回车提示输入" @keyup="showInfo">
</div>
</body>
<script>
new Vue({
el: "#App",
data: {
name: 'xingli'
},
methods: {
showInfo(e) {
if (e.keyCode !== 13) return //设置按下回车返回输入值
console.log(e.target.value)
}
},
})
</script>
</html>
2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
showInfo(e) {//使用该代码可以得到key值
console.log(e.key)
console.log(e.keyCode)
}
**4.也可以使用keyCode去指定具体的按键(不推荐)**不同键盘的keyCode不同 5.Vue.config.keyCodes.自定义键名=键码,可以去定制按键别名
3.系统修饰键(用法特殊):ctrl、alt、shift、meta (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。 (2).配合keydown使用:正常触发事件。
修饰符可用.连接连续写
@keyup.ctrl.y
按下ctrl+y触发事件
@click.prevent.stop
先阻止默认事件,再停止冒泡
计算属性与监视
计算属性 computed
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<div id="App">
姓<input type="text" v-model="firstName"> <br> <br>
名<input type="text" v-model="lastName"> <br> <br>
姓名: <span>{{fullName}}</span>
</div>
</body>
<script>
new Vue({
el: '#App',
data: {
firstName: '张',
lastName: '三'
},
computed: {
fullName: {//最后存在data中
get() {
console.log('get被调用了')
return this.firstName + '-' + this.lastName
},
/* set(value) {
console.log('set被调用了',value)
const arr = value.split('-') // 数组之间有一个-
this.firstName = arr[0]
this.lastName = arr[1]
} */
}
},
})
</script>
</html>
计算属性简写
computed: {
fullname:function(){//只考虑读取不考虑修改
console.log('get被调用了')
return this.firstName + '-' + this.lastName
}
}
监视属性 watch
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<div id="app">
<!-- <h2>今天天气很{{ishot ? '炎热' : '凉爽'}}</h2> -->
<h2>今天天气很{{info}}</h2>
<br>
<button @click="gaiTian">切换天气</button> <br>
提示: <h3>{{tip}}</h3>
</div>
</body>
<script>
const vm = new Vue({
el: '#app',
data: {
ishot: true,
tip: '多喝凉水',
},
computed: {
info() {
return this.ishot ? '炎热' : '凉爽'
}
},
watch: {
ishot: {
immediate: true,//布尔值 初始化时是否执行函数
handler() { //这里只能使用handler函数
console.log('ishot被修改了')
}
}
},
methods: {
gaiTian() {
if (this.ishot)
this.ishot = false; else this.ishot = true
}
},
})
// 另一种监视方法
/* vm.$watch('ishot', {//,前写监视的对象 ,后写函数和配置 监视对象不存在时不会报错
immediate: true,//布尔值 初始化时是否执行函数
handler() { //这里只能使用handler函数
console.log('ishot被修改了')
}
}) */
</script>
</html>
深度监视
Vue自身可以检测对象内部值的改变,但Vue提供的watch默认不可以 根据实际情况觉得是否开启watch的深度监视
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<div id="app">
<!-- <h2>今天天气很{{ishot ? '炎热' : '凉爽'}}</h2> -->
<h2>今天天气很{{info}}</h2>
<br>
<button @click="gaiTian">切换天气</button> <br>
<button @click="numbers.a++">点我让a+1</button>
<h3>a的值是{{numbers.a}}</h3> <br>
<br>
<button @click="numbers.b++">点我让b+1</button> <br>
<h3>b的值是{{numbers.b}}</h3>
</div>
</body>
<script>
const vm = new Vue({
el: '#app',
data: {
ishot: true,
numbers: {
a: 1,
b: 2
}
},
computed: {
info() {
return this.ishot ? '炎热' : '凉爽'
}
},
watch: {
ishot: {
handler() { //这里只能使用handler函数
console.log('ishot被修改了')
}
},
/* //监视多层结构中某个属性的变化
'numbers.a': {// 该写法是原始写法
handler() {
console.log('a改变了')
}
} */
//监视多级结构中所有属性的变化 不开器只有numbers中所有值发生改变函数才会生效
numbers: {
deep: true,
handler() {
console.log('numbers的值改变了')
}
}
},
methods: {
gaiTian() {
if (this.ishot)
this.ishot = false; else this.ishot = true
}
},
})
</script>
</html>
监视的简写
watch: {
/*ishot: { //正常写法
handler(newValue, oldValue) { //这里只能使用handler函数
console.log('ishot被修改了', newValue, oldValue)
}
}, */
ishot(newValue, oldValue) {
console.log('ishot被修改了', newValue, oldValue)
},
},
样式绑定
绑定class样式
<div id="app">
<div class ="basic" :class="a">
<!--最后上面这个div的class是"basic normal"-->
</div>
<!--添加多个样式"-->
<div class ="basic" :class="addr">
<!--最后上面这个div的class是"basic class1 class2 class3"-->
</div>
</div>
<script>
new Vue({
el:'#app',
data:{
a:'normal',
addr:['class1','class2','class3']
},
methods: {
change:{
}
},
})
</script>
Math.floor(Math.random()*3) //随机数 范围0-3
//floor 四舍五入向下取整
//Math.random()生成0-1的数 不包含1 *3代表生成0-3的数 不包括3 生成的是小数
绑定style样式
<body>
<div id="app">
<div class="" :style="{fontSize: fsize + 'px'}">{{name}}</div>
<!--:style 表示等号后内容为表达式 上方代码可改变字体大小"-->
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
a: 'normal',
name: 'miaolme',
fsize: 40
},
})
</script>
另一种写法
<body>
<div id="app">
<div class="" :style="styleObj">{{name}}</div>
<!--:style 表示等号后内容为表达式 上方代码可改变字体大小"-->
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
a: 'normal',
name: 'miaolme',
styleObj:{
fontSize:'40px',
backgroundColor: 'orange',
color: 'red'
}
},
})
</script>
数组写法
<body>
<div id="app">
<div class="" :style="[styleObj,styleObj2]">{{name}}</div>
<!--:style 表示等号后内容为表达式 上方代码可改变字体大小"-->
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
a: 'normal',
name: 'miaolme',
styleObj: {
fontSize: '40px',
backgroundColor: 'orange',
color: 'red'
},
styleObj2: {
color: 'red'
}
},
})
</script>
条件渲染
v-show 和 v-if
<body>
<div id="app">
<!-- v-show等号后写表达式 结果是布尔值
v-if和v-show用法一样 -->
<!-- <h2 v-show="false">欢迎学习vue{{name}}</h2> -->
<!-- <h2 v-show="1===1">欢迎学习vue{{name}}</h2> -->
<h2 v-if="false">欢迎学习vue{{name}}</h2>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
name: 'miaolme'
}
})
</script>
v-else-if和v-else
用法和常规编程的else if用法相同
if执行后 else if的代码不执行
所有条件不满足,执行else里的代码
v-show适用于切换频率高的场景 v-if适用于切换频率低的场景可以嵌套div使用
列表渲染
v-for
<body>
<div id="app">
<h2>人员列表</h2>
<ul>
<!-- 根据persons数组长度生成li -->
<!-- key代表节点标识 -->
<li v-for="ren in persons" :key="ren.id">
<!-- in可以用of代替 -->
{{ren.name}}-{{ren.age}}
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
persons: [
{ id: '001', name: '张三', age: 18 },
{ id: '002', name: '李四', age: 19 },
{ id: '003', name: '王五', age: 20 }
]
}
})
</script>
<body>
<div id="app">
<h2>人员列表</h2>
<ul>
<!-- 根据persons数组长度生成li -->
<!-- key代表节点标识 -->
<!-- index可以用其他词替换 是索引 可以拿到这个数据 -->
<li v-for="(ren,index) in persons" :key="ren.id">
<!-- in可以用of代替 -->
{{ren.name}}-{{ren.age}}-{{index}}
</li>
</ul>
</div>
</body>
v-for可以遍历其他数据
<body>
<div id="app">
<h2>人员列表</h2>
<ul>
<!-- 根据persons数组长度生成li -->
<!-- key代表节点标识 -->
<!-- index可以用其他词替换 是索引 可以拿到这个数据 -->
<li v-for="(value,key) in neko" :key="key.id">
{{key}}-{{value}}
<!-- 类似键值对 -->
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
neko: {
mao: '粉毛',
eye: '大眼',
tile: '大尾巴'
}
}
})
</script>
v-for可以遍历字符串
<body>
<div id="app">
<h2>人员列表</h2>
<ul>
<!-- 根据persons数组长度生成li -->
<!-- key代表节点标识 -->
<!-- index可以用其他词替换 是索引 可以拿到这个数据 -->
<li v-for="(char,index) in str" :key="index.id">
{{index}}-{{char}}
<!-- 类似键值对 -->
</li>
</ul>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
str: 'Hello'
}
})
</script>
用的少
v-for可以遍历指定次数
<body>
<div id="app">
<h2>人员列表</h2>
<ul>
<!-- 根据persons数组长度生成li -->
<!-- key代表节点标识 -->
<!-- index可以用其他词替换 是索引 可以拿到这个数据 -->
<li v-for="(number,index) in 5" :key="index.id">
{{number}}-{{index}}
<!-- 类似键值对 -->
</li>
</ul>
</div>
</body>
列表功能
过滤
1 双向绑定
2 判断+改色
.indexOf()
该方法判断点前的数是否包含()内的字符
包含会给出在第几位,第一位是0
,不包含返回-1
this.persons = this.persons.filter((p) => {
return p.name.indexOf(val) !== -1
})
// filter 过滤方法
数组.filter((变量) => {
return 布尔值
})
//返回一个新数组
完整watch方法
<body>
<div id="app">
<div>
<input type="text" placeholder="请输入名字" v-model="keyWord">
<button>这是按钮</button>
<ul>
<li v-for="(p, index) in fillPersons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
persons: [
{ id: '001', name: '马冬梅', age: 19, sex: '女' },
{ id: '002', name: '周冬雨', age: 20, sex: '女' },
{ id: '003', name: '周杰伦', age: 21, sex: '男' },
{ id: '004', name: '温兆伦', age: 22, sex: '男' }
],
keyWord: '',
fillPersons: []
},
watch: {
keyWord: {
immediate: true,
handler(val) {
this.fillPersons = this.persons.filter((p) => {
return p.name.indexOf(val) !== -1
})
}
}
}
})
</script>
</html>
用computed实现
<body>
<div id="app">
<div>
<input type="text" placeholder="请输入名字" v-model="keyWord">
<button>这是按钮</button>
<ul>
<li v-for="(p, index) in fillPersons" :key="p.id">
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
persons: [
{ id: '001', name: '马冬梅', age: 19, sex: '女' },
{ id: '002', name: '周冬雨', age: 20, sex: '女' },
{ id: '003', name: '周杰伦', age: 21, sex: '男' },
{ id: '004', name: '温兆伦', age: 22, sex: '男' }
],
keyWord: '',
},
computed: {
fillPersons() {
return this.fillPersons = this.persons.filter((p) => {
return p.name.indexOf(this.keyWord) !== -1
})
}
},
})
</script>
</html>
排序
vue的数据检测原理
懒得学
看这里:
033_尚硅谷Vue技术_更新时的一个问题_哔哩哔哩_bilibili
看到037
收集表单数据
v-model 默认双向绑定 value值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<div id="app">
<form @submit.prevent="demo">
<!-- 点击按钮触发表单提交 prevent阻止默认行为 -->
<!-- <label for="demo"> -->
<!-- label 和id可以连接两个对象 -->
<!-- 账号:<input type="text" id="demo"> -->
<!-- </label> -->
账号: <input type="text" v-model="account"> <br>
密码: <input type="password" v-model="password"> <br>
性别: <br>
男<input type="radio" name="sex" value="male" v-model="sex">
<!-- 通过name可以为radio单选框分组 -->
女<input type="radio" name="sex" value="femal" v-model="sex">
<br>
爱好: <br>
<!-- vue默认读取多选框 checked的布尔值 -->
学习<input type="checkbox" v-model="hobby" value="study">
打游戏<input type="checkbox" v-model="hobby" value="game">
吃饭<input type="checkbox" v-model="hobby" value="eat"> <br>
所属校区 <br>
<select v-model="city">
<option value="">请选择校区</option>
<option value="beijing">北京</option>
<option value="shenzhen">深圳</option>
<option value="shanghai">上海</option>
<option value="wuhan">武汉</option>
<br>
</select> <br>
其他信息: <br>
<textarea v-model="other"></textarea> <br>
<input type="checkbox" v-model="agree"> 阅读并接收<a href="http://baidu.com">《用户协议》</a> <br>
<button>提交信息</button>
</form>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
account: '',
password: '',
sex: 'femal',// 双向绑定 会默认选中性别
hobby: [],//hobby所获得的多选框的值是个字符串
city: '',
other: '',
agree: 'false',
},
methods: {
demo() {
alert(1)
}
},
})
</script>
</html>
vue基础
过滤器
效果:显示格式化后的时间
现在是:2021-01-09
现在是:2021-01-09 22:53:47
意义不大,vue3移除
<script src="./js/vue2.js"></script>
<script src="./js/dayjs.min.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="root">
<h2>显示格式化后的时间</h2>
<h3>现在是{{fmtTime}}</h3>
</div>
</body>
<script>
new Vue({
el: '#root',
data: {
time: 1621561377603 //时间戳
},
computed: {
fmtTime() {
return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss')
}
}
})
</script>
</html>
时间格式化可以借助第三方库实现
内置指令
学过的指令
v-bind : 单向绑定解析表达式,可简写为:xxx
v-model : 双向数据绑定
v-for : 遍历数组/对象/字符串
v-on : 绑定事件监听,可简写为@
v-if : 条件渲染(动态控制节点是否存在)
v-else : 条件渲染(动态控制节点是否存在)
v-show : 条件渲染(动态控制节点是否展示)
v-text指令
<body>
<div id="app">
<div>{{name}}</div> <br>
<div v-text="name"></div> <!-- v-text会替换到整个div内容 -->
<!-- v-text插入文本 会替换节点内容 插值语法不会 -->
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
name: '小猫'
}
})
</script>
v-html指令
用法:和v-text用法相同,但是可以解析带标签的字符串 如<h2>呵呵</h2>
<div v-html="name"></div>
安全性问题 用于输入可无视屏蔽插入危险html语句
v-cloak指令
用在标签中,在vue挂载后,标签会消失
可单独设置样式 本质是一个id 可以设置携带改id的内容不显示 diskplay
,可以防止因网速过慢导致vue未加载产生{{}}
内容
v-once指令
1.v-once所在节点在初次动态渲染后,就视为静态内容了。 2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
标签加入改内容 {{}}
内代表的内容只会显示初始值
v-pre指令
1.v-prt.除过其所在节点的编译过程。 2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译
自定义指令
目前用不到
生命周期
原理图
下方所有字段都和vue中的data:{}
平级
new Vue({
el: '#app',
data: {
name: '小猫'
}
})
mounted
mounted(){
// 此函数内的代码只会在vue挂载完后执行
// 可以在内部添加定时器函数等用于初始化的代码
}
template
用法1:不换行
template:'<h2>当前的n值是:{{n}}/h2><button@click="add">点我n+1</button>'
用法2:换行
template:`<h2>当前的n值是:{{n}}/h2>
<button@click="add">点我n+1</button>`
作用,替换容器内容即 <div id="app">
内的所有内容
<div id="app">
<div>{{name}}</div> <br>
<div v-text="name"></div> <!-- v-text会替换到整个div内容 -->
<!-- v-text插入文本 会替换节点内容 插值语法不会 -->
</div>
vue中使用template会覆盖原有容器所有内容。
模板可为空,但是必须包含template
(根节点)
beforeUpdate
更新流程前的函数
beforeUpdate(){
// 写在内部的函数会在vue的值即将发生更新前执行
}
update
update(){
// 写在内部的函数会在vue的值发生更新后执行
}
beforeDestory
beforeDestory(){
// 写在内部的函数会在vue即将销毁前执行
// 主要用来写各项服务的终止函数,例如定时器函数的结束等
//一般在此阶段:关闭定时器、取消订阅消息,解绑自定义事件等收尾操作
}
非单文件组件
基本案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<!-- 定义容器 -->
<div id="app">
<h1>{{msg}}</h1>
<hr>
<school />
</div>
</body>
<script>
//定义组件
const school = Vue.extend({
template: `
<div>
<h2>我的学校:{{name}}</h2>
<h2>地址:{{address}}</h2>
</div>`,
data() {
return {
name: '喵校',
address: '喵娘乐园'
}
}
})
new Vue({
el: '#app',
data: {
msg: '你好Vue!'
},
//注册组件 (局部)
components: {
school: school //调用<school/>标签来使用 标签的内容由:左侧决定
}
})
</script>
</html>
全局注册组件
//全局注册组件
Vue.component('使用标签名',定义的组件名)
全局注册例子
Vue.component('xuexiao',school)
//使用<xuexiao/>即可调用改组件
const school = Vue.extend({
template: `
<div>
<h2>我的学校:{{name}}</h2>
<h2>地址:{{address}}</h2>
</div>`,
data() {
return {
name: '喵校',
address: '喵娘乐园'
}
}
})
局部注册和全局注册的区别:
局部注册的组件只能在其所规定的容器可用,全局注册的组件可用在任意的容器中调用组件。
组件可套娃
但是执行顺序必须自上而下,否则报错
构造函数
057_尚硅谷Vue技术_VueComponent构造函数_哔哩哔哩_bilibili
先跳过,以后学
脚手架
安装脚手架
- 安装node.js
- 配置 淘宝源
npm config set registry=http://registry.npm.taobao.org
- 全局安装脚手架
npm install -g @vue/cli
创建脚手架文件
vue create 文件名 #(自己自定义)最好不要出现中文,可能会出错
单文件组件
文件后缀.vue
起名规范
school.vue my-school.vue
School.vue MySchool.vue
结构
<template>
<!--组件的结构 -->
</template>
<script>
//组件交互相关代码(数据、方法等)
</script>
<style>
/*组件的样式*/
</style>
例子
<template>
<div class="demo">
<h2>我的学校:{{name}}</h2>
<h2>地址:{{address}}</h2>
</div>
</template>
<script>
const school = Vue.extend({
data() {
return {
name: '喵校',
address: '喵娘乐园'
}
}
})
</script>
<style>
.demo{
background-color: pink;
}
</style>
暴露方法
类似public 公开访问方法 共3种
<script>
export const school = Vue.extend({ //分别暴露
data() {
return {
name: '喵校',
address: '喵娘乐园'
}
}
})
</script>
<script>
const school = Vue.extend({
data() {
return {
name: '喵校',
address: '喵娘乐园'
}
}
})
export default school //默认暴露 常用
</script>
<script>
/*或者*/
export default {
name:'school',
data() {
return {
name: '喵校',
address: '喵娘乐园'
}
}
}
</script>
<script>
const school = Vue.extend({
data() {
return {
name: '喵校',
address: '喵娘乐园'
}
}
})
export {school} //统一暴露
</script>
App.vue 汇总组件
<template lang="">
<div>
<school></school>
</div>
</template>
<script>
//引入组件
import school from 'vue1/school'
export default {
name: 'App',
components: {
school: school
}
}
</script>
<style lang="">
</style>
vm main.js
import App from 'vue1/App'
new Vue({
template:'<App></App>',
el:'#root',
components:{App}
})
入口文件 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root">
</div>
<script src="../js/vue2.js"></script>
<script src="./main.js"></script>
</body>
</html>
常用属性
render函数
main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App), // h可替换成其他内容 下方是例子
//render: test => test(App), 同样的,App代表组件 也可以替换为模板结构
//render: test => test('h1','hello') 类似于template效果 不常用
}).$mount('#app') // 这个相当于 el:'#app'
ref元素
作用: 类似于id选择器 用于获取组件的vm对象或者是某个元素的对象
例子:
<h1 ref="sch">你好vue!</h1>
console.log(this.$refs.sch)
ref属性
被用来给元素或子组件注册引用信息(id的替代者) 被应用在html标签上获取的是真实dom元素,应用在组件上是组件实例对象(vc)
props配置
用法:
props:['name','address','age']
用在script中与data平级
不能与data中值相同.用于外部数据传入.
可以通过内部写函数来控制传入的数值.
num+(){
this.age++ //需要用到this
}
mixin混入
例子
mixin.js
// 分别暴露
export const mixin = {
methods: {
showName() {
alert(this.name)
}
},
}
MyStudent.vue
<template>
<div>
<h3 @click="showName">姓名:{{ name }}</h3>
<h3>地址:{{ address }}</h3>
<h3>年龄:{{ age }}</h3>
</div>
</template>
<script>
//引入 混合 mixin
import { mixin } from '../mixin'
export default {
name: 'MyStudent',
data() {
return {
name: '喵喵',
address: '樱花校园',
age: '18'
}
},
//启用混合 会自动根据结构判断 进行调用自定义的mixin中的方法
mixins: [mixin],
methods: {
}
}
</script>
组件内的方法代码执行优先
mounted函数都会执行。 mixin中的代码优先执行
全局混合
只需要修改main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
//引入混合
import { mixin } from './mixin'
//应用混合
Vue.mixin(mixin)
new Vue({
render: h => h(App),
}).$mount('#app')
作用域限制和插件
作用域限制
scoped
用于style中
<style scoped>
.title{
color: red;
}
</style>
作用:限制style内的样式仅在当前组件生效。
vue内的样式会覆盖组件的同名样式
插件
使用方法: script.js
定义插件
export default { //默认暴露
install(Vue,x,y){ //可接收传入值x,y
//全局过滤器
Vue.filter('mySlice',function(value){...})
//定义全局指令
Vue.directive('fbind',{...})
//定义全局混入
Vue.mixin({...})
}
//给vue原型添加方法
Vue.prototype.hello = ()=>{alert('你好vue')}
}
应用插件在App.vue
<script>
//引入插件
import plugins from './plugins'
//使用插件
Vue.use(plugins)
</script>
组件信息交互
全局事件总线
没学 084_尚硅谷Vue技术_全局事件总线1_哔哩哔哩_bilibili
消息订阅与发布
1 订阅消息 2 发布消息
安装第三方库
npm install [email protected]
引入 school.vue
<script>
import pubsub from 'pubsub-js'
//定义
mounted(){ //不写箭头函数需要把执行函数定义在methods中
this.pubId = pubsub.subscribe('hello',(msgName,data)=>{ //订阅消息
console.log(this) //hello是消息名
})
}
//取消订阅
beforeDestory(){
pubsub.unsubscribe(this.pubId)
}
</script>
另一种方式
<script>
import pubsub from 'pubsub-js'
methods(){
demo(data){...}
}
mounted(){ //不写箭头函数需要把执行函数定义在methods中
this.pubId = pubsub.subscribe('hello',this.demo) //订阅消息
//检测到 hello为事件名发布消息时会执行回调函数
}
//取消订阅
beforeDestory(){
pubsub.unsubscribe(this.pubId)
}
</script>
发布消息
<script>
import pubsub from 'pubsub-js'
methods(){
sendStudentName(){
pubsub.publish('hello',666) //调用方法后会创建一个名为hello的消息,数据是666
}
}
</script>
methods: $nextTick
this.$nextTick(function(){
//会在dom节点更新完毕后执行 vue模板编译完成后执行
this.$refs.inputTitle.focus()//自动获取焦点
})
setTimeout(){
this.$refs.inputTitle.focus()//自动获取焦点
//定时器函数会在vue模板编译完成后执行
}
过度与动画
vue动画
<template>
<div>
<!--isShow = !isShow代表按钮切换isShow的true和false-->
<Button @click="isShow = !isShow">显示/隐藏</Button>
<transition name="v" appear>
<!-- :appear="true" 等同于appear 加上后会在刷新后播放动画 -->
<!-- 过渡标签 设置好后自动播放来去的动画 -->
<h1 v-show="isShow">你好啊!</h1>
</transition>
</div>
</template>
<script>
export default {
name: 'MyTest',
data() {
return {
isShow: true
}
}
}
</script>
<style scoped>
h1 {
background-color: pink;
}
/*come和够为需要的元素添加class就可以播放设定的动画*/
.come {
/*来时动画*/
animation: dongHua 1s;
}
.go {
/*走时动画*/
animation: dongHua 1s reverse;
/*reverse反转*/
}
/*过度动画标签类型 v是动画的name*/
.v-enter-active {
/*来时动画*/
animation: dongHua 1s;
}
.v-leave-active {
/*走时动画*/
animation: dongHua 1s reverse;
/*reverse反转*/
}
@keyframes dongHua {
/*定义动画关键帧 和动画名*/
from {
transform: translateX(-100%);
/*单位是px*/
}
to {
transform: translateX(0px);
}
}
</style>
vue过度
例子
<div>
<!--isShow = !isShow代表按钮切换isShow的true和false-->
<Button @click="isShow = !isShow">显示/隐藏</Button>
<transition-group name="v">
<!-- :appear="true" 等同于appear 加上后会在刷新后播放动画 -->
<!-- 过渡标签 设置好后自动播放来去的动画 -->
<h1 v-show="isShow" key="1">你好啊!</h1>
<h1 v-show="isShow" key="2">Vue</h1>
</transition-group>
</div>
group中的所有元素必须有唯一的key值
name用于区分不同类型动画
集成第三方动画
animate.css - 第三方动画 (npmjs.com)
安装:
需要cmd进入在所需项目内执行
npm install animate.css --save
引入
<script>
import 'animate.css';
</script>
例子
<template>
<div>
<!--isShow = !isShow代表按钮切换isShow的true和false-->
<Button @click="isShow = !isShow">显示/隐藏</Button>
<transition-group
name="animate__animated animate__bounce"
appear
enter-active-class="animate__rubberBand"
leave-active-class="animate__bounceOut">
<!-- :appear="true" 等同于appear 加上后会在刷新后播放动画 -->
<!-- 过渡标签 设置好后自动播放来去的动画 -->
<h1 v-show="isShow" key="1">你好啊!</h1>
<h1 v-show="isShow" key="2">Vue</h1>
</transition-group>
</div>
</template>
<script>
//引入动画css
import 'animate.css'
export default {
name: 'MyTest2',
data() {
return {
isShow: true
}
}
}
</script>
<style scoped>
h1 {
background-color: pink;
}
</style>
enter-active-class=“”
和leave-active-class=“”
“”内需要填入动画库所需动画的名称。 name=“”
必须填入 animate__animated animate__bounce
不同动画库的要求略有差别
group中的所有元素必须有唯一的key值
插槽
默认插槽
使用方法:
- 组件写双标签
- 标签内填组件里额外需添加的元素
- 在组件中用slot双标签标记所放置位置
slot标签内写的内容会在组件双标签内的内容为空时展示
viedo想播放必须添加controls标签才能播放
具名插槽
使用:
- 组件双标签内写
solt="定义的name名称"
solt
标签中添加name=“自定义名称”
属性
不同元素使用相同的solt
名字不会发生覆盖,会自动追加
另一种写法
使用<template>
双标签包裹,类似于div
但是不会产生dom
结构
使用该标签包裹后可以用 v-solt:自定义名称
来定义dom
生成位置
作用域插槽
104_尚硅谷Vue技术_作用域插槽_哔哩哔哩_bilibili
因为感觉没啥用,先不学了
Vuex
理解vuex
原理图
vuex 是什么
1.概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中 多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适 用于任意组件间通信。 2.Github地址: https://github.com/vuejs/vuexe
什么时候使用Vuex
1.多个组件依赖于同一状态 2.来自不同组件的行为需要变更同一状态
安装vuex
npm i vuex@3
动态路由
路由基本使用
- 需安装vue-router3
npm i vue-router@3
插件库
使用方法
main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
//关闭Vuee生产提示
Vue.config.productionTip = false
//应用插件
Vue.use(VueRouter)
new Vue({
render: h => h(App),
}).$mount('#app')
创建路由
router/index.js
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
// 创建一个路由器并暴露在外部
export default new VueRouter({
routes: [
{
path: '/about',
component: MyAbout
},
{
path: '/home',
component: MyHome
}
]
})
引入路由器
main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
//引入路由器
import router from './router'
//关闭Vuee生产提示
Vue.config.productionTip = false
//应用插件
Vue.use(VueRouter)
new Vue({
render: h => h(App),
router: router //引入路由
}).$mount('#app')
调整App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<h2>Vue Router Demo</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- 原始html中我们使用a标签实现页面的跳转 -->
<!-- <a class="list-group-item active" href="./about.html">About</a>
<a class="list-group-item" href="./home.html">Home</a> -->
<!-- 路由跳转 router-link 和 to 标签 最终转成a标签 active-class 元素激活时的样式-->
<router-link class="list-group-item" active-class="active" to="/about">About</router-link>
<router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
</div>
</div>
<div class="col-xs-6">
<div class="panel">
<div class="panel-body">
<!-- 此处到底展示什么组件,得看用户点击的是哪个导航项 -->
<!-- 指定组件的呈现位置 -->
<router-view></router-view>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
}
},
components: {
}
}
</script>
<style>
</style>
建议把路由组件放在单独的文件夹中
嵌套(多级)路由
router/index.js
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
import MyNews from "../comments/news"
import MyMessage from "../comments/message"
// 创建一个路由器并暴露在外部
export default new VueRouter({
routes: [
{
path: '/about',
component: MyAbout
},
{
path: '/home',
component: MyHome,
//二级路由
children: [
{
path: 'news',
component: MyNews
},
{
path: 'message',
component: MyMessage
}
]
}
]
})
home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
</li>
<li>
<router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
</li>
</ul>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'MyHome'
}
</script>
<style>
</style>
路由传参
query参数
可以通过to
后写?…
传递参数
跳转路由并携带query参数,to的字符串写法
<router-link class="list-group-item" active-class="active" to="/home/message?id=666&title=你好啊!">Message</router-link>
取参数
{{$route.query.id}} //666
{{$route.query.title}} //你好啊!
使用v-if
可以插入指定内容
<li v-for="m in messageList" :key="m.id">
<router-link class="list-group-item" active-class="active" :to="`/home/message?id=${m.id}&title=${m.title}`">Message</router-link>
</li>
跳转路由并携带query参数,to的对象写法
<li v-for="m in messageList" :key="m.id">
<router-link :to="{
path:'/home/message/detail',
query:{
id:m.id,
title:m.title
}
}"
</li>
命名路由
添加方法 router/index.js
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
import MyNews from "../comments/news"
import MyMessage from "../comments/message"
// 创建一个路由器并暴露在外部
export default new VueRouter({
routes: [
{
name:'guanyu', //给谁起名就在哪里填写name:
path: '/about',
component: MyAbout
},
{
path: '/home',
component: MyHome,
//二级路由
children: [
{
path: 'news',
component: MyNews
},
{
name:'xiangqing', //给谁起名就在哪里填写name:
path: 'message',
component: MyMessage
}
]
}
]
})
可以简化操作
仅支持下列两种
<li v-for="m in messageList" :key="m.id">
<router-link :to="{
name:'xiangqing',
query:{
id:m.id,
title:m.title
}
}"
</li>
<router-link class="list-group-item" active-class="active" :to="{name:'guanyu'}">关于</router-link>
params参数
配置路由
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
import MyNews from "../comments/news"
import MyMessage from "../comments/message"
import MyDetail from "../comments/detail"
// 创建一个路由器并暴露在外部
export default new VueRouter({
routes: [
{
name:'guanyu', //给谁起名就在哪里填写name:
path: '/about',
component: MyAbout
},
{
path: '/home',
component: MyHome,
//二级路由
children: [
{
path: 'news',
component: MyNews
},
{
name:'xiangqing', //给谁起名就在哪里填写name:
path: 'message',
component: MyMessage,
children:{
{
name:'xiangqing',
path:'detail/:id/:title'
component: MyDetail,
}
}
}
]
}
]
})
携带方式1
<li v-for="m in messageList" :key="m.id">
<router-link class="list-group-item" active-class="active" :to="`/home/message/detail/${m.id}/${m.title}`">Message</router-link>
</li>
携带方式2
不可使用path
<li v-for="m in messageList" :key="m.id">
<router-link :to="{
name:'xiangqing',
params:{
id:m.id,
title:m.title
}
}"
</li>
路由的props配置
配套的Detail
组件
<template>
<ul>
<li>消息编号:{{ id }}</li>
<li>消息标题:{{ title }}</li>
</ul>
</template>
<script>
export default {
name: 'Detail',
props: ['id', 'title']
}
</script>
<style>
</style>
第二种写法
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
import MyNews from "../comments/news"
import MyMessage from "../comments/message"
// 创建一个路由器并暴露在外部
export default new VueRouter({
routes: [
{
path: '/about',
component: MyAbout
},
{
path: '/home',
component: MyHome,
//二级路由
children: [
{
path: 'news',
component: MyNews
},
{
path: 'message',
component: MyMessage,
//props的第二种写法,值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数
//,以props的形式传给Detail组件
props:true
}
]
}
]
})
另一种写法
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
import MyNews from "../comments/news"
import MyMessage from "../comments/message"
// 创建一个路由器并暴露在外部
export default new VueRouter({
routes: [
{
path: '/about',
component: MyAbout
},
{
path: '/home',
component: MyHome,
//二级路由
children: [
{
path: 'news',
component: MyNews
},
{
path: 'message',
component: MyMessage,
//props的第三种写法,值为函数
//1.
/*props({ query: { id, title } }) {
return { id, title }
} */
//2.
/* props({ query }) {
return { id: query.id, title: query.title }
} */
//3.
props($route) {
return {
id: $route.query.id,
title: $route.query.title
}
}
}
]
}
]
})
编程式路由导航
push查看
按钮传递参数
<button> @click="pushShow(m)"push查看</button>
按钮绑定点击事件对应的函数
pushShow(m){ //m 是接收的参数
this.$router.push({
name:'xiangqing',
query:{
id:m.id,
title:m.title
}
})
}
replace查看
按钮传递参数
<button> @click="replaceShow(m)"push查看</button>
按钮绑定点击事件对应的函数
replaceShow(m){ //m 是接收的参数
this.$router.replace({
name:'xiangqing',
query:{
id:m.id,
title:m.title
}
})
}
区别:
- push查看浏览器可以回退,有历史记录
- replace查看浏览器的记录会被覆盖,无法正常回退
前进和后退
按钮绑定下列对应函数就能实现前进和后退
back(){ //后退
this.$router.back()
}
forward(){ //前进
this.$router.forward()
}
test(){
this.$router.go() // ()内为正数前进对应步数,填写负数则后退对应的步数.
}
缓存路由
作用:可以防止在切换路由组件时导致填写的对应数据丢失.
<keep-alive include="组件名">
<router-view></router-view>
</keep-alive>
include 填写的是要缓存的组件名,如果不填写则默认缓存所有的路由导航。
<!--缓存多个路由组件-->
<keep-alive :include = "['News','Message']">
<router-view></router-view>
</keep-alive>
新的生命周期钩子
例子:闪烁文本 (透明度随时间变化的文本)
路由组件独有
写在组件里
activated(){
//切入组件时激活
},
deactivated(){
//切走组件时激活
}
路由守卫
要求:每个路由都要有一个名字
全局前置路由守卫
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
// 创建一个路由器并暴露在外部
const router = new VueRouter({
routes: [
{
name: 'miao',
path: '/about',
component: MyAbout
},
{
name: 'cao',
path: '/home',
component: MyHome,
}
]
})
//全局前置路由守卫
router.beforeEach((to, from, next) => { //传入参数包含路由信息
//在每次切换路由前调用,初始化时调用
// to 去处(目标路由); from 来处(目前所处路由); next 放行
//判断前往的路由路径是否为下方两个 是 则放行
if (to.path === '/home/news' || to.path === '/home/message') {
//判断本地存储中的school(key)的值是否是(ying) 如果是 则放行
if (localStorage.getItem('school') === 'ying') {
next()
}
}else{
alert('无权限访问') //不符合上述条件 提示无权限访问
}
})
//暴露路由
export default router
meta:{}
可以传入自定义参数(路由源信息)
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
// 创建一个路由器并暴露在外部
const router = new VueRouter({
routes: [
{
name: 'miao',
path: '/about',
component: MyAbout,
meta: { pass: 'true' },//权限表示符 来确定是否进行权限校验
},
{
name: 'cao',
path: '/home',
component: MyHome,
meta: { pass: 'false' }, //false 按照下方的规则无法通过校验
}
]
})
//全局前置路由守卫
router.beforeEach((to, from, next) => { //传入参数包含路由信息
//在每次切换路由前调用,初始化时调用
// to 去处(目标路由); from 来处(目前所处路由); next 放行
//判断前往的路由路径是否为下方两个 是 则放行
if (to.meta.pass) {
next()
} else {
alert('无权限访问') //不符合上述条件 提示无权限访问
}
})
//暴露路由
export default router
全局后置路由守卫
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
// 创建一个路由器并暴露在外部
const router = new VueRouter({
routes: [
{
name: 'miao',
path: '/about',
component: MyAbout,
meta: { pass: 'true',title:'关于' },
},
{
name: 'cao',
path: '/home',
component: MyHome,
meta: { pass: 'false',title:'主页' },
}
]
})
//全局前置路由守卫
router.beforeEach((to, from, next) => { //传入参数包含路由信息
//在每次切换路由前调用,初始化时调用
// to 去处(目标路由); from 来处(目前所处路由); next 放行
//判断前往的路由路径是否为下方两个 是 则放行
if (to.meta.pass) {
next()
} else {
alert('无权限访问') //不符合上述条件 提示无权限访问
}
})
//全局后置路由守卫
router.afterEach((to,from,next)=>{
//在每次切换路由后调用,初始化时调用
//主要用于修改跳转后的页面标题
document.title = to.meta.title || '喵喵系统'
})
//暴露路由
export default router
独享路由守卫
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
// 创建一个路由器并暴露在外部
const router = new VueRouter({
routes: [
{
name: 'miao',
path: '/about',
component: MyAbout,
meta: { pass: 'true', title: '关于' },
},
{
name: 'cao',
path: '/home',
component: MyHome,
meta: { pass: 'false', title: '主页' },
beforeEnter: (to, from, next) => {
//用法和全局路由守卫相同,仅在进入该组件前调用
}
}
]
})
//全局后置路由守卫
router.afterEach((to,from,next)=>{
//在每次切换路由后调用,初始化时调用
//主要用于修改跳转后的页面标题
document.title = to.meta.title || '喵喵系统'
})
//暴露路由
export default router
只有前置没有独享后置路由守卫 路由守卫可自行按需搭配
组件内路由守卫
<template>
<ul>
<li>消息编号:{{ id }}</li>
<li>消息标题:{{ title }}</li>
</ul>
</template>
<script>
import { title } from 'process';
export default {
name: 'Detail',
props: ['id', 'title'],
//通过路由规则,进入该组件时被调用
beforeRouteEnter: () => {
},
//通过路由规则,离开该组件时被调用
beforeRouteLeave: () => {
}
}
</script>
<style>
</style>
路由工作模式
- hash模式 携带# 兼容好
- history模式 不携带#
更换模式方法
// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";
//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
// 创建一个路由器并暴露在外部
const router = new VueRouter({
//mode: 'history',
mode: 'hash',
routes: [
{
name: 'miao',
path: '/about',
component: MyAbout,
meta: { pass: 'true', title: '关于' },
},
{
name: 'cao',
path: '/home',
component: MyHome,
meta: { pass: 'false', title: '主页' },
beforeEnter: (to, from, next) => {
//用法和全局路由守卫相同,仅在进入该组件前调用
}
}
]
})
//全局后置路由守卫
router.afterEach((to,from,next)=>{
//在每次切换路由后调用,初始化时调用
//主要用于修改跳转后的页面标题
document.title = to.meta.title || '喵喵系统'
})
//暴露路由
export default router