npm install -g @vue/cli
vue craete XXX
npm run serve
<template>
<div>
<h1 v-text="msg" ref="title"></h1>
<button ref="btn" @click="showDOM">获取上方DOM</button>
<School ref="zj"></School>
</div>
</template>
<script>
import School from './components/School.vue'
export default {
name : "App",
data()
{
return {
msg:"学习Vue",
}
},
components:{
School
},
methods:{
showDOM(){
// console.log(document.getElementById("title").innerHTML)
console.log(this.$refs.title)
console.log(this.$refs.btn)
console.log(this.$refs.zj)
}
}
}
</script>
App.vue
<template>
<div>
<School name="张三" sex="男" :age="18"></School>
<hr>
<School name="李四" sex="女" :age="19"></School>
<hr>
<School name="王五" sex="男"></School>
</div>
</template>
<script>
import School from './components/Student.vue'
export default {
name : "App",
components:{
School
},
}
</script>
Student.vue
<template>
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{myage}}</h2>
<button @click="addAge">点击加一</button>
</div>
</template>
<script>
export default {
name: 'Student',
data(){
return {
myage:this.age,
}
},
//接受
//方法1:
props:["name","sex","age"],//先加载props,后加载data
methods:{
// props传入的属性值不要改动
addAge()
{
this.myage++;
}
},
//方法2:
// props:{
// name:String,
// sex:String,
// age:Number,
// }
// 方法3:
// props:{
// name:{
// type:String,
// required:true,
// },
// sex:{
// type:String,
// required:true,
// },
// age:{
// type:Number,
// default:99,
// }
// }
}
</script>
<template>
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{age}}</h2>
<button @click="show">点击提示姓名信息</button>
</div>
</template>
<script>
// import {hunhe,hunhe2} from "../mixin"
export default {
name: 'Student',
// mixins:[hunhe,hunhe2],
data(){
return{
name: '张三',
sex: '男',
}
},
mounted(){
console.log("mounted")
}
}
</script>
School.vue
<template>
<div class="school">
<h1>学校名称{{name}}</h1>
<h1>学校地址{{address}}</h1>
<button @click="show">点击提示学校名称信息</button>
</div>
</template>
<script>
// import {hunhe,hunhe2} from "../mixin"
export default {
name: 'School',
// mixins: [hunhe,hunhe2],
data(){
return {
name: '河南中医药大学',
address:"郑州",
}
}
}
</script>
<style>
.school{
background-color:orange
}
</style>
App.vue
<template>
<div>
<School></School>
<hr>
<Student></Student>
</div>
</template>
<script>
import School from './components/Student.vue'
import Student from './components/School.vue'
export default {
name : "App",
components:{
School,
Student,
},
}
</script>
mixin.js
//data数据重复:组件中data和mixin中data取交集,且以组件中data为主
const hunhe = {
data(){
return {
name: 'hunhe_name',
sex:"女",
age:18,
}
}
}
//同名钩子函数会叠加
//函数叠加
const hunhe2 = {
methods:{
show()
{
alert(this.name)
}
},
mounted() {
console.log('hunhe2_mounted')
}
}
export {hunhe, hunhe2}
main.js
//引入Vue
import Vue from 'vue';
//引入App组件
import App from './App.vue'
//关闭提示信息
Vue.config.productionTip = false
import {hunhe,hunhe2} from './mixin'
Vue.mixin(hunhe)
Vue.mixin(hunhe2)
new Vue({
el:"#app",
render: h => h(App),
})
两次hunhe2_mounted
四次hunhe2_mounted
export default {
install(Vue,x,y,z){
console.log(x,y,z)
//全局过滤器
Vue.filter('mySlice', function(value){return value.slice(0,4)})
//定义全局指令
Vue.directive('fbind',{
//指令与元素成功绑定时(一上来)
bind(element,binding){element.value = binding.value},
//指令所在元素被插入页面时
inserted(element,binding){element.focus()},
//指令所在的模板被重新解析时
update(element,binding){element.value = binding.value}
})
//定义混入
Vue.mixin({
data() {return {x:100,y:200}},
})
//给Vue原型上添加一个方法(vm和vc就都能用了)
Vue.prototype.hello = ()=>{alert('你好啊')}
}
}
School.vue
<template>
<div>
<h2>学校名称:{{ name | mySlice }}</h2>
<h2>学校地址:{{ address }}</h2>
<button @click="test">点我测试一个hello方法</button>
</div>
</template>
<script>
export default {
name:'School',
data() {
return {
name:'尚硅谷atguigu',
address:'北京',
}
},
methods: {
test(){
this.hello()
}
},
}
</script>
Student.vue
<template>
<div>
<h2>学生姓名:{{ name }}</h2>
<h2>学生性别:{{ sex }}</h2>
<input type="text" v-fbind:value="name">
</div>
</template>
<script>
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男'
}
},
}
</script>
一般在App组件中,控制所有子组件的样式[不用写sxoped]
App.vue
<template>
<div>
<h2>App组件中</h2>
<hr>
<School></School>
<hr>
<Student></Student>
</div>
</template>
<script>
import School from './components/Student.vue'
import Student from './components/School.vue'
export default {
name : "App",
components:{
School,
Student,
},
}
</script>
<style scoped>
h2{
color: red;
}
</style>
Student.vue
<template>
<div class="student">
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
</template>
<script>
export default {
name: 'Student',
data(){
return{
name: '张三',
sex: '男',
age:18,
}
},
}
</script>
<style scoped>
.student{
background-color:yellow;
}
</style>
School.vue
<template>
<div class="school">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</template>
<script>
export default {
name: 'School',
data(){
return {
name: '河南中医药大学',
address:"郑州",
}
},
}
</script>
<style>
.school{
background-color:grey;
}
</style>
1.父–>子【传入参数即可】
2.子–>父【子组件传数据给父组件做法:1.父组件定义函数 2.传给子组件 3.合适的时机调用函数】
3.子–>子【子–>父,父–>子】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LocalStroage</title>
</head>
<br>
<h1>LocalStorage</h1>
<button onclick="saveData()">点击我保存一个数据</button><br>
<button onclick="readData()">点击我读取一个数据</button><br>
<button onclick="deleteData()">点击我删除一个数据</button><br>
<button onclick="clearData()">点击我删除ALL数据</button><br>
<script type="text/javascript">
//1.存入
function saveData() {
let p = { name: "dyh", age: 18 }
// console.log(JSON.stringify(p))
//key[string类型] value[string类型]
//@@@@@@@@@@@@@@@@@@存入@@@@@@@@@@@@@@@@@@
localStorage.setItem("mgs", "hello!!")
localStorage.setItem("mgs2",666)
localStorage.setItem("mgs3",JSON.stringify(p))
}
// 2.取出
function readData() {
console.log(localStorage.getItem("mgs"))
console.log(localStorage.getItem("mgs2"))
let x =localStorage.getItem("mgs3")
console.log(JSON.parse(x))
}
// 删除
function deleteData(){
localStorage.removeItem("mgs2")
}
// 清空
function clearData(){
localStorage.clear()
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>sessionStroage</title>
</head>
<body>
<h1>sessionStorage</h1>
<button onclick="saveData()">点击我保存一个数据</button><br>
<button onclick="readData()">点击我读取一个数据</button><br>
<button onclick="deleteData()">点击我删除一个数据</button><br>
<button onclick="clearData()">点击我删除ALL数据</button><br>
<script type="text/javascript">
//1.存入
function saveData() {
let p = { name: "dyh", age: 18 }
// console.log(JSON.stringify(p))
//key[string类型] value[string类型]
//@@@@@@@@@@@@@@@@@@存入@@@@@@@@@@@@@@@@@@
sessionStorage.setItem("mgs", "hello!!")
sessionStorage.setItem("mgs2",666)
sessionStorage.setItem("mgs3",JSON.stringify(p))
}
// 2.取出
function readData() {
console.log(sessionStorage.getItem("mgs"))
console.log(sessionStorage.getItem("mgs2"))
let x =sessionStorage.getItem("mgs3")
console.log(JSON.parse(x))
}
// 删除
function deleteData(){
sessionStorage.removeItem("mgs2")
}
// 清空
function clearData(){
sessionStorage.clear()
}
</script>
</body>
</html>
<template>
<div id="root">
<div class="todo-container">
<div class="todo-wrap">
<MyHeader :addTodo="addTodo"/>
<MyList :todos="todos" :checkTodo="checkTodo" :deleteTodo="deleteTodo"/>
<MyFooter :todos="todos" :checkAllTodo="checkAllTodo" :clearAllTodo="clearAllTodo"/>
</div>
</div>
</div>
</template>
<script>
import MyHeader from './components/MyHeader'
import MyList from './components/MyList'
import MyFooter from './components/MyFooter.vue'
export default {
name:'App',
components:{MyHeader,MyList,MyFooter},
data() {
return {
// 从本地存储中获得数据,null就创建空数组[]
todos:JSON.parse(localStorage.getItem('todos')) || []
}
},
methods: {
//添加一个todo
addTodo(todoObj){
this.todos.unshift(todoObj)
},
//勾选or取消勾选一个todo
checkTodo(id){
this.todos.forEach((todo)=>{
if(todo.id === id) todo.done = !todo.done
})
},
//删除一个todo
deleteTodo(id){
this.todos = this.todos.filter( todo => todo.id !== id )
},
//全选or取消全选
checkAllTodo(done){
this.todos.forEach((todo)=>{
todo.done = done
})
},
//清除所有已经完成的todo
clearAllTodo(){
this.todos = this.todos.filter((todo)=>{
return !todo.done
})
}
},
// 数据发生改变就放到本地存储中,注意深度侦听,以及JSON转化为字符串
watch: {
todos:{
deep:true,
handler(value){
localStorage.setItem('todos',JSON.stringify(value))
}
}
},
}
</script>
<template>
<div class="app">
<h1>{{ msg }},学生姓名是:{{ studentName }}</h1>
<!-- 通过父组件给子组件传递函数类型的props实现子给父传递数据 -->
<School :getSchoolName="getSchoolName"/>
<!-- 通过父组件给子组件绑定一个自定义事件实现子给父传递数据(第一种写法,使用@或v-on) -->
<!-- <Student @atguigu="getStudentName" @demo="m1"/> -->
<!-- 通过父组件给子组件绑定一个自定义事件实现子给父传递数据(第二种写法,使用ref) -->
<Student ref="student" @click.native="show"/> <!-- native -->
</div>
</template>
<script>
import Student from './components/Student'
import School from './components/School'
export default {
name:'App',
components:{School,Student},
data() {
return {
msg:'你好啊!',
studentName:''
}
},
methods: {
getSchoolName(name){
console.log('App收到了学校名:',name)
},
getStudentName(name,...params){
console.log('App收到了学生名:',name,params)
this.studentName = name
},
m1(){
console.log('demo事件被触发了!')
},
show(){
alert(123)
}
},
mounted() {
this.$refs.student.$on('atguigu',this.getStudentName) // 绑定自定义事件
// this.$refs.student.$once('atguigu',this.getStudentName) // 绑定自定义事件(一次性)
},
}
</script>
<style scoped>.app{background-color: gray;padding: 5px;}</style>
Student.vue
<template>
<div class="student">
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>当前求和为:{{number}}</h2>
<button @click="add">点我number++</button>
<button @click="sendStudentlName">把学生名给App</button>
<button @click="unbind">解绑atguigu事件</button>
<button @click="death">销毁当前Student组件的实例(vc)</button>
</div>
</template>
<script>
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男',
number:0
}
},
methods: {
add(){
console.log('add回调被调用了')
this.number++
},
sendStudentlName(){
// 触发Student组件实例身上的atguigu事件
this.$emit('atguigu',this.name,666,888,900)
// this.$emit('demo')
// this.$emit('click')
},
unbind(){
// 解绑
this.$off('atguigu') //解绑一个自定义事件
// this.$off(['atguigu','demo']) //解绑多个自定义事件
// this.$off() //解绑所有的自定义事件
},
death(){
// 销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效
this.$destroy()
}
},
}
</script>
<style lang="less" scoped>
.student{background-color: pink;padding: 5px;margin-top: 30px;}
</style>
School.vie
<template>
<div class="school">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="sendName">点击获得学校名</button>
</div>
</template>
<script>
export default {
name: 'School',
props: ['getSchoolName'],
data(){
return {
name: '河南中医药大学',
address:"郑州",
}
},
methods: {
sendName()
{
console.log("触发了sendName",this.name)
this.getSchoolName(this.name)
}
}
}
</script>
<style scoped>
.school{
background-color:lawngreen;
}
</style>
//引入Vue
import Vue from 'vue';
//引入App组件
import App from './App.vue'
//关闭提示信息
Vue.config.productionTip = false
new Vue({
el:"#app",
render: h => h(App),
beforeCreate(){
Vue.prototype.$bus = this //$bus是当前的vm
}
})
App.vue
<template>
<div>
<h2>App组件中</h2>
<hr>
<School></School>
<hr>
<Student></Student>
</div>
</template>
<script>
import School from './components/School.vue'
import Student from './components/Student.vue'
export default {
name : "App",
components:{
School,
Student,
},
}
</script>
<style scoped>
div{
background-color: aqua;
}
</style>
school.vue
<template>
<div class="school">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</template>
<script>
export default {
name: 'School',
data(){
return {
name: '河南中医药大学',
address:"郑州",
}
},
methods:{
demo(data)
{
console.log("我是school组件,接受data:",data)
}
},
mounted(){
// 绑定[事件+回调函数]
this.$bus.$on('hello',this.demo)
},
beforeDestroy()
{
// 解绑
this.$bus.$off('hello')
}
}
</script>
<style scoped>
.school{
background-color:grey;
}
</style>
student.vue
<template>
<div class="student">
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{age}}</h2>
<button @click="sendStudentName">学生名传给school组件</button>
</div>
</template>
<script>
export default {
name: 'Student',
data(){
return{
name: '张三',
sex: '男',
age:18,
}
},
methods:{
sendStudentName()
{
//触发
this.$bus.$emit("hello",this.name)
}
}
}
</script>
<style scoped>
.student{
background-color:yellow;
}
</style>
<template>
<div>
<button @click="getStudents">获取学生信息</button>
<button @click="getCars">获取汽车信息</button>
</div>
</template>
<script>
import axios from 'axios'
export default {
name:'App',
methods: {
getStudents() {
axios.get('http://localhost:8080/students').then(
response => {
console.log('请求成功了',response.data)
},
error => {
console.log('请求失败了',error.message)
}
)
},
getCars() {
axios.get('http://localhost:8080/demo/cars').then(
response => {
console.log('请求成功了',response.data)
},
error => {
console.log('请求失败了',error.message)
}
)
}
},
}
</script>
//引入Vue
import Vue from 'vue';
//引入App组件
import App from './App.vue'
//关闭提示信息
Vue.config.productionTip = false
new Vue({
el:"#app",
render: h => h(App),
beforeCreate(){
Vue.prototype.$bus = this
}
})
<template>
<div class="container">
<Search/>
<List/>
</div>
</template>
<script>
import Search from './components/Search.vue'
import List from './components/List.vue'
export default {
name:'App',
components:{ Search, List },
}
</script>
<template>
<div class="row">
<!-- 展示用户列表 -->
<div class="card" v-for="user in info.users" :key="user.login">
<a :href="user.html_url" target="_blank">
<img :src="user.avatar_url" style="width: 100px" />
</a>
<p class="card-text">{{user.login}}</p>
</div>
<!-- 展示欢迎词 -->
<h1 v-show="info.isFirst">欢迎使用!</h1>
<!-- 展示加载中 -->
<h1 v-show="info.isLoading">加载中....</h1>
<!-- 展示错误信息 -->
<h1 v-show="info.errMsg">错误信息:{{info.errMsg}}</h1>
</div>
</template>
<script>
export default {
name: "List",
data() {
return {
info:{
isFirst: true,
isLoading:false,
errMsg:"",
users:[],
}
};
},
methods:{
getUsers(dataObj)
{
this.info = dataObj;
// console.log("触发事件,得到数据user",this.info)
}
},
mounted(){
// 绑定
this.$bus.$on('updateListUsers',this.getUsers);
},
beforeDestroy()
{
// 解绑
this.$bus.$off('updateListUsers');
}
};
</script>
<style scoped>
.album {min-height: 50rem; /* Can be removed; just added for demo purposes */
padding-top: 3rem;padding-bottom: 3rem;background-color: #f7f7f7;}
.card {float: left;width: 33.333%;padding: 0.75rem;margin-bottom: 2rem;
border: 1px solid #efefef;text-align: center;}
.card > img {margin-bottom: 0.75rem;border-radius: 100px;}
.card-text {font-size: 85%;}
</style>
<template>
<section class="jumbotron">
<h3 class="jumbotron-heading">Search Github Users</h3>
<div>
<input type="text" placeholder="enter the name you search" v-model="keyWord"/>
<button @click="searchUsers">Search</button>
</div>
</section>
</template>
<script>
import axios from "axios";
export default {
name: "Search",
data() {
return {
keyWord: "",
};
},
methods: {
searchUsers(){
// 1.请求前更新List数据
this.$bus.$emit('updateListUsers',{isFirst:false,isLoading:true,errMsg:"",users:[]})
axios.get(`https://api.github.com/search/users?q=${this.keyWord}`).then(
// 成功
response => {
// console.log("请求成功了!!",response.data.items);
// 2.请求成功更新List数据
this.$bus.$emit('updateListUsers',{isFirst:false,isLoading:false,errMsg:"",users:response.data.items})
},
// 失败
error => {
// console.log("请求失败了!!",error.message)
// 3.请求失败更新List数据
this.$bus.$emit('updateListUsers',{isFirst:false,isLoading:false,errMsg:error.message,users:[]})
}
)
},
},
};
</script>
App.vue
<template>
<div class="container">
<Category title="美食" >
<img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
</Category>
<Category title="游戏" >
<ul>
<li v-for="(g,index) in games" :key="index">{{g}}</li>
</ul>
</Category>
<Category title="电影">
<video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
</Category>
</div>
</template>
<script>
import Category from './components/Category'
export default {
name:'App',
components:{ Category },
data() {
return {
foods:['火锅','烧烤','小龙虾','牛排'],
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
films:['《教父》','《拆弹专家》','《你好,李焕英》','《尚硅谷》']
}
},
}
</script>
<style scoped>.container{display: flex;justify-content: space-around;}</style>
Categroy.vue
<template>
<div class="category">
<h3>{{ title }}分类</h3>
<!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) -->
<slot>我是一些默认值,当使用者没有传递具体结构时,我会出现</slot>
</div>
</template>
<script>
export default {
name:'Category',
props:['title']
}
</script>
<style scoped>
.category {background-color: skyblue;width: 200px;height: 300px;}
h3 {text-align: center;background-color: orange;}
video {width: 100%;}
img {width: 100%;}
</style>
App.vue
<template>
<div class="container">
<Category title="美食" >
<img slot="conter" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
<a slot="footer" href="http://www.atguigu.com">更多美食</a>
</Category>
<Category title="游戏" >
<ul slot="center">
<li v-for="(g,index) in games" :key="index">{{g}}</li>
</ul>
<div class="foot" slot="footer">
<a href="http://www.atguigu.com">单机游戏</a>
<a href="http://www.atguigu.com">网络游戏</a>
</div>
</Category>
<Category title="电影">
<video slot="center" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
<template v-slot:footer>
<div class="foot">
<a href="http://www.atguigu.com">经典</a>
<a href="http://www.atguigu.com">热门</a>
<a href="http://www.atguigu.com">推荐</a>
</div>
<h4>欢迎前来观影</h4>
</template>
</Category>
</div>
</template>
<script>
import Category from './components/Category'
export default {
name:'App',
components:{Category},
data() {
return {
foods:['火锅','烧烤','小龙虾','牛排'],
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
films:['《教父》','《拆弹专家》','《你好,李焕英》','《尚硅谷》']
}
},
}
</script>
<style scoped>
.container,.foot{display: flex;justify-content: space-around;}
h4{text-align: center;}
</style>
Categroy.vue
<template>
<div class="category">
<h3>{{title}}分类</h3>
<!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) -->
<slot name="center">我是一些默认值,当使用者没有传递具体结构时,我会出现1</slot>
<slot name="footer">我是一些默认值,当使用者没有传递具体结构时,我会出现2</slot>
</div>
</template>
<script>
export default {
name:'Category',
props:['title']
}
</script>
<style scoped>
.category{background-color: skyblue;width: 200px;height: 300px;}
h3{text-align: center;background-color: orange;}
video{width: 100%;}
img{width: 100%;}
</style>
App.vue
<template>
<div class="container">
<Category title="游戏">
<template scope="atguigu">
<ul>
<li v-for="(g,index) in atguigu.games" :key="index">{{g}}</li>
</ul>
</template>
</Category>
<Category title="游戏">
<template scope="{games}">
<ol>
<li style="color:red" v-for="(g,index) in games" :key="index">{{g}}</li>
</ol>
</template>
</Category>
<Category title="游戏">
<template slot-scope="{games}">
<h4 v-for="(g,index) in games" :key="index">{{g}}</h4>
</template>
</Category>
</div>
</template>
<script>
import Category from './components/Category'
export default {
name:'App',
components:{ Category },
}
</script>
<style scoped>
.container,.foot{display: flex;justify-content: space-around;}
h4{text-align: center;}
</style>
categroy.vue
<template>
<div class="category">
<h3>{{title}}分类</h3>
<slot :games="games" msg="hello">我是默认的一些内容</slot>
</div>
</template>
<script>
export default {
name:'Category',
props:['title'],
data() {
return {
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
}
},
}
</script>
<style scoped>
.category{background-color: skyblue;width: 200px;height: 300px;}
h3{text-align: center;background-color: orange;}
video{width: 100%;}
img{width: 100%;}
</style>
src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex' // 引入Vuex
Vue.use(Vuex) // 应用Vuex插件
const actions = {} // 准备actions——用于响应组件中的动作
const mutations = {} // 准备mutations——用于操作数据(state)
const state = {} // 准备state——用于存储数据
// 创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
})
src/main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store' // 引入store
Vue.config.productionTip = false
new Vue({
el: '#app',
render: h => h(App),
store, // 配置项添加store
beforeCreate() {
Vue.prototype.$bus = this
}
})
src/store/index.js
// 引入Vue
import Vue from 'vue';
// 引入Vuex插件
import Vuex from 'vuex';
// 使用插件
Vue.use(Vuex) //Vuex.use(Vuex)必须在new Vuex.store({})前面
// 准备actions——用于响应组件中的动作
const actions = {
//context是mini版的$store context = $store
// jia(context,value){
// // console.log(context,value)
// console.log("actions中的jia被调用了")
// context.commit('JIA',value)
// },
// jian(context,value){
// console.log("actions中的jian被调用了")
// context.commit('JIAN',value)
// },
jiaOdd(context,value){
if(context.state.sum % 2){
console.log("actions中的jiaOdd被调用了")
context.commit('JIA',value)
}
},
jiaWait(context,value){
setTimeout(() => {
console.log("actions中的jiaWait被调用了")
context.commit('JIA',value)
}, 1000);
}
}
// 准备mutations——用于操作数据(state) 响应actions
const mutations = {
JIA(state,value){
// console.log(state,value);
// console.log(this.state)
// state = this.state.sum [this = $store]
state.sum+=value;
console.log("mutations中的JIA被调用了");
},
JIAN(state,value){
state.sum-=value;
console.log("mutations中的JIAN被调用了");
},
}
// 准备state——用于存储共享数据
const state = {
sum:0,
}
// 创建并暴露store
export default new Vuex.Store({
actions: actions,
mutations: mutations,
state: state,
})
Count.vue
<template>
<div>
<h1>当前为{{$store.state.sum}}</h1>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<button @click="incrementOdd">奇数再加</button>
<button @click="incrementWait">等等再加</button>
</div>
</template>
<script>
export default {
name: "Count",
props:[],
data() {
return {
n:1,
}
},
methods:{
increment(){
console.log("increment被调用了")
this.$store.commit('JIA',this.n)
// console.log(this)
// console.log(this.$store.state)
// console.log(this.$store.state.sum)
},
decrement(){
console.log("decrement被调用了")
this.$store.commit('JIAN',this.n)
},
incrementOdd(){
console.log("incrementOdd被调用了")
this.$store.dispatch('jiaOdd',this.n)
},
incrementWait(){
console.log("incrementWait被调用了")
this.$store.dispatch('jiaWait',this.n)
}
}
}
</script>
<style scoped>
button{
margin: 5px;
}
</style>
Count.vue
<template>
<div>
<h1>当前为:{{sum}}</h1>
<h1>当前为放大十倍:{{bigSum}}</h1>
<h1>我在{{name}}的{{school}}上学</h1>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment(n)">+</button>
<button @click="decrement(n)">-</button>
<button @click="incrementOdd(n)">奇数再加</button>
<button @click="incrementWait(n)">等等再加</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapMutations,mapActions} from "vuex"
export default {
name: "Count",
props:[],
data() {
return {
n:1,
}
},
methods:{
// increment(){
// console.log("increment被调用了")
// this.$store.commit('JIA',this.n)
// // console.log(this)
// // console.log(this.$store.state)
// // console.log(this.$store.state.sum)
// },
// decrement(){
// console.log("decrement被调用了")
// this.$store.commit('JIAN',this.n)
// },
// ...mapMutations({increment:'JIA',decrement:'JIAN'}),
/*
*/
// 对象写法(生成对应的方法,会调用commit联系mutations)
...mapMutations({increment:'JIA',decrement:'JIAN'}),
/*
*/
// 数组写法
// ...mapMutations(['JIA','JIAN']),
// ============================================================================================
// incrementOdd(){
// console.log("incrementOdd被调用了")
// this.$store.dispatch('jiaOdd',this.n)
// },
// incrementWait(){
// console.log("incrementWait被调用了")
// this.$store.dispatch('jiaWait',this.n)
// }
/*
*/
// 对象写法(生成对应的方法,会调用dispatch联系Ations)
...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
/*
*/
// 数组写法
// ...mapActions(['jiaOdd','jiaWait']),
},
computed:{
// 对象写法
// ...mapState({sum:'sum',name:'name',school:'school'})
// 数组写法
...mapState(['sum','name','school']),
// =================================================================================================
// 对象写法
// ...mapGetters({bigSum:'bigSum'}),
// 数组写法
...mapGetters(['bigSum'])
},
}
</script>
<style scoped>
button{
margin: 5px;
}
</style>
const countAbout = {
namespaced: true, // 开启命名空间
state: {x:1},
mutations: { ... },
actions: { ... },
getters: {
bigSum(state){ return state.sum * 10 }
}
}
const personAbout = {
namespaced: true, // 开启命名空间
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
countAbout,
personAbout
}
})
<template>
<div>
<h1>当前为:{{sum}}</h1>
<h1>当前为放大十倍:{{bigSum}}</h1>
<h1>我在{{name}}的{{school}}上学</h1>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="increment(n)">+</button>
<button @click="decrement(n)">-</button>
<button @click="incrementOdd(n)">奇数再加</button>
<button @click="incrementWait(n)">等等再加</button>
<h1 style="color:red"> Person组件:{{personSum}} </h1>
</div>
</template>
<script>
import {mapState,mapGetters,mapMutations,mapActions} from "vuex"
export default {
name: "Count",
props:[],
data() {
return {
n:1,
}
},
methods:{
// 调用mutations
...mapMutations('countAoubt',{increment:'JIA',decrement:'JIAN'}),
// 调用actions
...mapActions('countAoubt',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'}),
},
computed:{
// 读取state
...mapState('countAoubt',['sum','name','school']),
// 读取getters
...mapGetters('countAoubt',['bigSum']),
...mapGetters('personAoubt',['personSum'])
},
}
</script>
<style scoped>
button{
margin: 5px;
}
</style>
<template>
<div>
<input type="text" placeholder="请输入" v-model="name"></input>
<button @click="addPerson">添加人员</button>
<button @click="addWang">添加一个姓王的人员</button>
<button @click="addAnyPerson">任意添加一个人员</button>
<h1 style="color:red">Count组件:{{sum}}</h1>
<h2>列表中的第一个人的名字:{{firstPersonName}}</h2>
<ul>
<li v-for="p in personList" :key="p.id">{{p.name}}</li>
</ul>
</div>
</template>
<script>
import {nanoid} from "nanoid"
import { mapGetters } from 'vuex';
export default {
name: "Person",
data(){
return {
name:'',
}
},
methods:{
addPerson(){
if(this.name === "") return alert("不能空格!!") ;
const personObj = {id:nanoid(),name:this.name}
// commit
this.$store.commit('personAoubt/ADDPERSON', personObj)
this.name = "";
},
addWang(){
// dispatch
const personObj = {id:nanoid(),name:this.name}
this.$store.dispatch('personAoubt/addPersonWang',personObj);
},
addAnyPerson(){
// dispatch
this.$store.dispatch('personAoubt/addAnyPersonServer')
}
},
computed:{
sum(){
// state
return this.$store.state.countAoubt.sum;
},
personList(){
// state
return this.$store.state.personAoubt.personList;
},
firstPersonName(){
return this.$store.getters['personAoubt/firstPersonName'];
}
},
}
</script>
<style scoped>
button{
margin: 5px;
}
</style>
// 引入Vue
import Vue from 'vue';
// 引入Vuex插件
import Vuex from 'vuex';
import countOptions from './Count';
import personOptions from './Person';
Vue.use(Vuex)
// 创建并暴露store
export default new Vuex.Store({
modules:{
countAoubt: countOptions,
personAoubt: personOptions,
}
})
const countOptions = {
namespaced:true,
actions : {
jiaOdd(context,value){
if(context.state.sum % 2){
console.log("actions中的jiaOdd被调用了")
context.commit('JIA',value)
}
},
jiaWait(context,value){
setTimeout(() => {
console.log("actions中的jiaWait被调用了")
context.commit('JIA',value)
}, 1000);
}
},
mutations : {
JIA(state,value){
state.sum+=value;
console.log("mutations中的JIA被调用了");
},
JIAN(state,value){
state.sum-=value;
console.log("mutations中的JIAN被调用了");
},
},
state : {
sum:0,
name:"河南",
school:"河南中医药大学",
},
getters : {
bigSum(state){
// console.log(state)
return state.sum*10;
},
},
}
export default countOptions;
import axios from "axios";
import {nanoid} from "nanoid";
const personOptions = {
namespaced:true,
actions : {
addPersonWang(context,value){
if(value.name[0]==="王"){
context.commit('ADDPERSON',value);
}
else{
alert("请写王姓!!")
}
},
addAnyPersonServer(context){
axios.get('http://api.uixsj.cn/hitokoto/get?type=social').then(
response =>{
// console.log("response.data");
context.commit('ADDPERSON',{id:nanoid(),name:response.data})
},
error =>{
// console.log("error.message");
alert(error.message);
}
)
}
},
mutations : {
ADDPERSON(state,personObj){
state.personList.unshift(personObj);
console.log("mutations中的ADDPERSON被调用了");
}
},
state : {
personList:[{id:"001",name:"Pjon"}],
},
getters : {
personSum(state){
return state.personList.length;
} ,
firstPersonName(state){
return state.personList[0].name;
}
},
}
export default personOptions;
<template>
<div>
<Count/>
<Person/>
</div>
</template>
<script>
import Count from "./components/Count.vue";
import Person from "./components/Person.vue";
export default {
name:'App',
components:{ Count , Person},
}
</script>
<style scoped>
</style>
//引入Vue
import Vue from 'vue';
//引入App组件
import App from './App.vue'
// 引入store
import store from './store/index.js';
//关闭提示信息
Vue.config.productionTip = false
new Vue({
el:"#app",
render: h => h(App),
// 配置store选项
store:store,
beforeCreate(){
Vue.prototype.$bus = this
}
})
npm i vue-router
import VueRouter from 'vue-router' // 引入VueRouter
import About from '../components/About' // 路由组件
import Home from '../components/Home' // 路由组件
// 创建router实例对象,去管理一组一组的路由规则
const router = new VueRouter({
routes:[
{
path:'/about',
component:About
},
{
path:'/home',
component:Home
}
]
})
//暴露router
export default router
src/components/About.vue
<template>
<div>
<h1>我是Aoubt页面展示的</h1>
</div>
</template>
<script>
export default {
name: "About",
}
</script>
<style scoped>
</style>
src/components/Home.vue
<template>
<div>
<h1>我是Home页面展示的</h1>
</div>
</template>
<script>
export default {
name: "Home",
}
</script>
<style scoped>
</style>
src/router/index.js
import VueRouter from "vue-router"
// 引入组件
import Home from "../components/Home"
import About from "../components/About"
// const router =
export default new VueRouter({
routes:[
{
path:"/about", //key
component:About,//value
},
{
path:"/home",
component:Home,
}
]
})
src/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> -->
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link class="list-group-item" active-class="active" to="/about">Aoubt</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'
}
</script>
src/main.js
//引入Vue
import Vue from 'vue';
//引入App组件
import App from './App.vue'
// 引入Vuerouter插件
import Vuerouter from 'vue-router';
// 引入路由器
import router from './router/index.js';
Vue.use(Vuerouter)//使用插件
//关闭提示信息
Vue.config.productionTip = false
new Vue({
el:"#app",
render: h => h(App),
router:router,
})
routes:[
{
path:'/about',
component:About,
},
{
path:'/home',
component:Home,
children:[ // 通过children配置子级路由
{
path:'news', // 此处一定不要带斜杠,写成 /news
component:News
},
{
path:'message', // 此处一定不要写成 /message
component:Message
}
]
}
]
<router-link to="/home/news">News</router-link>
<template>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header"><h2>Vue Router Demo</h2></div>
</div>
</div>
</template>
<script>
export default {
name: "Banner",
}
</script>
<style scoped>
</style>
About.vue
<template>
<div>
<h1>我是Aoubt页面展示的</h1>
</div>
</template>
<script>
export default {
name: "About",
}
</script>
<style scoped>
</style>
Home.vue
<template>
<div>
<h1>我是Home页面展示的</h1>
<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/messages">Message</router-link>
</li>
</ul>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: "Home",
}
</script>
<style scoped>
</style>
Messages.vue
<template>
<ul>
<li>
<a href="/message1">message001</a>
</li>
<li>
<a href="/message2">message002</a>
</li>
<li>
<a href="/message/3">message003</a>
</li>
</ul>
</template>
<script>
export default {
name:'Messages'
}
</script>
News.vue
<template>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</template>
<script>
export default {
name:'News'
}
</script>
router/index.js
import VueRouter from "vue-router"
// 引入组件
import Home from "../pages/Home"
import About from "../pages/About"
import News from "../pages/News"
import Messages from "../pages/Messages"
// const router =
export default new VueRouter({
routes:[
{
path:"/about", //key
component:About,//value
},
{
path:"/home",
component:Home,
children:[
{
path:"news",
component:News,
},
{
path:"messages",
component:Messages,
},
]
}
]
})
App.vue
<template>
<div>
<Banner></Banner>
<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> -->
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link class="list-group-item" active-class="active" to="/about">Aoubt</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>
import Banner from './components/Banner.vue';
export default {
name:'App',
components: { Banner }
}
</script>
main.js
//引入Vue
import Vue from 'vue';
//引入App组件
import App from './App.vue'
// 引入Vuerouter插件
import Vuerouter from 'vue-router';
// 引入路由器
import router from './router/index.js';
Vue.use(Vuerouter)//使用插件
//关闭提示信息
Vue.config.productionTip = false
new Vue({
el:"#app",
render: h => h(App),
router:router,
})
1.传递参数
<!-- 跳转并携带query参数,to的字符串写法 -->
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">跳转</router-link>
<!-- 跳转并携带query参数,to的对象写法(推荐) -->
<router-link
:to="{
path:'/home/message/detail',
query:{
id: m.id,
title: m.title
}
}"
>跳转</router-link>
2.接收参数
$route.query.id
$route.query.title
src/router/index.js
import VueRouter from "vue-router";
import Home from '../pages/Home'
import About from '../pages/About'
import News from '../pages/News'
import Message from '../pages/Message'
import Detail from '../pages/Detail'
// 创建并暴露一个路由器
export default new VueRouter({
routes:[
{
path:'/about',
component:About
},
{
path:'/home',
component:Home,
children:[
{
path:'news',
component:News
},
{
path:'message',
component:Message,
children:[
{
path:'detail',
component:Detail
}
]
}
]
}
]
})
src/pages/Messages.vue
<template>
<div>
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<!-- <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">
{{m.title}}
</router-link> -->
<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
path:'/home/message/detail',
query:{
id:m.id,
title:m.title
}
}">
{{m.title}}
</router-link>
</li>
</ul>
<hr/>
<router-view></router-view>
</div>
</template>
<script>
export default {
name:'News',
data(){
return{
messageList:[
{id:'001',title:'消息001'},
{id:'002',title:'消息002'},
{id:'003',title:'消息003'}
]
}
}
}
</script>
src/pages/Detail.vue
<template>
<ul>
<li>消息编号:{{ $route.query.id }}</li>
<li>消息标题:{{ $route.query.title }}</li>
</ul>
</template>
<script>
export default {
name:'Detail'
}
</script>
index.js
import VueRouter from "vue-router"
// 引入组件
import Home from "../pages/Home"
import About from "../pages/About"
import News from "../pages/News"
import Messages from "../pages/Messages"
import Detail from "../pages/Detail"
// const router =
export default new VueRouter({
routes:[
{
name:"guanyu",
path:"/about", //key
component:About,//value
},
{
name:"jia",
path:"/home",
component:Home,
children:[
{
name:"xinwen",
path:"news",
component:News,
},
{
name:"xiaoxi",
path:"messages",
component:Messages,
children:[
{
name:"xiangqing",
path:"detail/:id/:title",
component:Detail,
}
]
},
]
}
]
})
Messages.vue
<template>
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带params参数,to的字符串写法 -->
<router-link :to="`/home/messages/detail/${m.id}/${m.title}`"> {{m.title}} </router-link>
<!-- 携带params参数 必须是name,不能是path-->
<!-- 跳转路由并携带params参数,to的对象写法 -->
<!-- <router-link :to="{
name:'xiangqing',
params:{
id:m.id,
title:m.title,
}
}">
{{m.title}}
</router-link> -->
</li>
<router-view></router-view>
</ul>
</template>
<script>
export default {
name:'Messages',
data(){
return {
messageList:[
{id:"001",title:"消息1"},
{id:"002",title:"消息2"},
{id:"003",title:"消息3"},
]
}
}
}
</script>
Detail.vue
<template>
<ul>
<li>信息id:{{$route.params.id}}</li>
<li>信息title:{{$route.params.title}}</li>
</ul>
</template>
<script>
export default {
name: "Detail",
// mounted(){
// console.log(this.$route.query.id1,this.$route.query.title1)
// }
}
</script>
<style scoped>
</style>
{
name:'xiangqing',
path:'detail/:id',
component:Detail,
//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
// props:{a:900}
//第二种写法:props值为布尔值,为true时,则把路由收到的所有params参数通过props传给Detail组件
// props:true
//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
props($route){
return {
id: $route.query.id,
title: $route.query.title
}
}
}
index.js
import VueRouter from "vue-router"
// 引入组件
import Home from "../pages/Home"
import About from "../pages/About"
import News from "../pages/News"
import Messages from "../pages/Messages"
import Detail from "../pages/Detail"
// const router =
export default new VueRouter({
routes:[
{
name:"guanyu",
path:"/about", //key
component:About,//value
},
{
name:"jia",
path:"/home",
component:Home,
children:[
{
name:"xinwen",
path:"news",
component:News,
},
{
name:"xiaoxi",
path:"messages",
component:Messages,
children:[
{
name:"xiangqing",
path:"detail/:id/:title",
component:Detail,
//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件 【固定数据】
// props:{a:1,b:"hello"}
//第二种写法:props值为布尔值,为true时,则把路由收到的所有params参数通过props传给Detail组件【params】
// props:true,
//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件 【params,query】
props($route){
return {
id:$route.params.id,
title:$route.params.title,
// id:$route.query.id,
// title:$route.query.title,
}
}
}
]
},
]
}
]
})
Messages.vue
<template>
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带params参数,to的字符串写法 -->
<router-link :to="`/home/messages/detail/${m.id}/${m.title}`"> {{m.title}} </router-link>
<!-- 携带params参数 必须是name,不能是path-->
<!-- 跳转路由并携带params参数,to的对象写法 -->
<!-- <router-link :to="{
name:'xiangqing',
params:{
id:m.id,
title:m.title,
}
}">
{{m.title}}
</router-link> -->
</li>
<router-view></router-view>
</ul>
</template>
<script>
export default {
name:'Messages',
data(){
return {
messageList:[
{id:"001",title:"消息1"},
{id:"002",title:"消息2"},
{id:"003",title:"消息3"},
]
}
}
}
</script>
Detail.vue
<template>
<ul>
<li>信息id:{{id}}</li>
<li>信息title:{{title}}</li>
<!-- <li>{{a}}</li> -->
<!-- <li>{{b}}</li> -->
</ul>
</template>
<script>
export default {
name: "Detail",
// mounted(){
// console.log(this.$route.query.id1,this.$route.query.title1)
// }
props:['id','title',],
// computed:{
// id()
// {
// return this.$route.params.id;
// },
// title(){
// return this.$route.params.title;
// }
// }
}
</script>
<style scoped>
</style>
App.vue
<template>
<div>
<Banner></Banner>
<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> -->
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link :replace="true" class="list-group-item" active-class="active" to="/about">Aoubt</router-link>
<router-link replace 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>
import Banner from './components/Banner.vue';
export default {
name:'App',
components: { Banner }
}
</script>
this.$router.push({
name:'xiangqing',
params:{
id:xxx,
title:xxx
}
})
this.$router.replace({
name:'xiangqing',
params:{
id:xxx,
title:xxx
}
})
Banner.vue
<template>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header"><h2>Vue Router Demo</h2></div>
<button @click="back">后退</button>
<button @click="forward">前进</button>
<button @click="Any">any(-3)</button>
</div>
</div>
</template>
<script>
export default {
name: "Banner",
methods:{
back(){
this.$router.back();
},
forward(){
this.$router.forward();
},
Any(){
this.$router.go(-3)
}
}
}
</script>
<style scoped>
</style>
Messages.vue
<template>
<ul>
<li v-for="m in messageList" :key="m.id">
<router-link :to="{
name:'xiangqing',
params:{
id:m.id,
title:m.title,
}
}">
{{m.title}}
</router-link>
<button @click="pushShow(m)">push查看</button>
<button @click="replaceShow(m)">replace查看</button>
</li>
<router-view></router-view>
</ul>
</template>
<script>
export default {
name:'Messages',
data(){
return {
messageList:[
{id:"001",title:"消息1"},
{id:"002",title:"消息2"},
{id:"003",title:"消息3"},
]
}
},
methods:{
// push记录
pushShow(m){
this.$router.push({
name:'xiangqing',
params:{
id:m.id,
title:m.title,
}
})
},
// replace记录
replaceShow(m){
this.$router.replace({
name:'xiangqing',
params:{
id:m.id,
title:m.title,
}
})
}
}
}
</script>
// 缓存一个路由组件
<keep-alive include="News"> // include中写想要缓存的组件名,不写表示全部缓存
<router-view></router-view>
</keep-alive>
// 缓存多个路由组件
<keep-alive :include="['News','Message']">
<router-view></router-view>
</keep-alive>
Home.vue
<template>
<div>
<h1>我是Home页面展示的</h1>
<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/messages">Message</router-link>
</li>
</ul>
<!-- News组件名 -->
<!-- <keep-alive include="News"> -->
<keep-alive :include="['News']">
<router-view></router-view>
</keep-alive>
</div>
</div>
</template>
<script>
export default {
name: "Home",
}
</script>
<style scoped>
</style>
News.vue
<template>
<ul>
<li>news001<input></input></li>
<li>news002<input></input></li>
<li>news003<input></input></li>
</ul>
</template>
<script>
export default {
name:'News'
}
</script>
<template>
<ul>
<li :style="{opacity}">欢迎学习vue</li>
<li>news001 <input type="text"></li>
<li>news002 <input type="text"></li>
<li>news003 <input type="text"></li>
</ul>
</template>
<script>
export default {
name:'News',
data(){
return{
opacity:1
}
},
activated(){
console.log('News组件被激活了')
this.timer = setInterval(() => {
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
deactivated(){
console.log('News组件失活了')
clearInterval(this.timer)
}
}
</script>
// 全局前置守卫:初始化时、每次路由切换前执行
router.beforeEach((to,from,next) => {
console.log('beforeEach',to,from)
if(to.meta.isAuth){ // 判断当前路由是否需要进行权限控制
if(localStorage.getItem('school') === 'atguigu'){ // 权限控制的具体规则
next() // 放行
}else{
alert('暂无权限查看')
}
}else{
next() // 放行
}
})
// 全局后置守卫:初始化时、每次路由切换后执行
router.afterEach((to,from) => {
console.log('afterEach',to,from)
if(to.meta.title){
document.title = to.meta.title //修改网页的title
}else{
document.title = 'vue_test'
}
})
2.独享守卫
beforeEnter(to,from,next){
console.log('beforeEnter',to,from)
if(localStorage.getItem('school') === 'atguigu'){
next()
}else{
alert('暂无权限查看')
}
}
index.js
// 引入插件
import VueRouter from "vue-router"
// 引入组件
import Home from "../pages/Home"
import About from "../pages/About"
import News from "../pages/News"
import Messages from "../pages/Messages"
import Detail from "../pages/Detail"
// 引入router路由器
const router = new VueRouter({
routes:[
{
name:"guanyu",
path:"/about", //key
component:About,//value
meta:{isAuth:false,title:"关于"} //不需要校验
},
{
name:"jia",
path:"/home",
component:Home,
meta:{isAuth:false,title:"主页"},
children:[
{
name:"xinwen",
path:"news",
component:News,
meta:{isAuth:true,title:"新闻"},
// 独享守卫,特定路由切换之后被调用
beforeEnter:(to,from,next)=>
{
// console.log(to,from,next)
// 到达需要校验的组件, 判断当前路由是否需要进行权限控制
if(to.meta.isAuth)
{
if(localStorage.getItem('school')==="河南中医药大学")
{
next()
}
else
{
alert("学校不是河南中医药大学!!")
}
}
else
{
next()
}
}
},
{
name:"xiaoxi",
path:"messages",
component:Messages,
meta:{isAuth:true,title:"消息"},
children:[
{
name:"xiangqing",
path:"detail/:id/:title",
component:Detail,
//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件 【固定数据】
// props:{a:1,b:"hello"}
//第二种写法:props值为布尔值,为true时,则把路由收到的所有params参数通过props传给Detail组件【params】
// props:true,
//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件 【params,query】
props($route){
return {
id:$route.params.id,
title:$route.params.title,
// id:$route.query.id,
// title:$route.query.title,
}
}
}
]
},
]
}
]
})
// // 全局前置守卫:初始化时、每次路由切换前执行
// router.beforeEach((to,from,next)=>{
// // console.log(to,from,next)
// // 到达需要校验的组件, 判断当前路由是否需要进行权限控制
// if(to.meta.isAuth)
// {
// if(localStorage.getItem('school')==="河南中医药大学")
// {
// next()
// }
// else
// {
// alert("学校不是河南中医药大学!!")
// }
// }
// else
// {
// next()
// }
// })
// 全局后置守卫:初始化时、每次路由切换后执行
router.afterEach((to,from)=>{
// console.log(to,from)
document.title = to.meta.title || "前端vue学习"
})
export default router
About.vue
<template>
<div>
<h1>我是Aoubt页面展示的</h1>
</div>
</template>
<script>
export default {
name: "About",
//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next)
{
console.log("beforeRouteEnter进入了About")
// 到达需要校验的组件, 判断当前路由是否需要进行权限控制
if(to.meta.isAuth)
{
if(localStorage.getItem('school')==="河南中医药大学11111")
{
next()
}
else
{
alert("学校不是河南中医药大学!!")
}
}
else
{
next()
}
},
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next)
{
console.log("beforeRouteLeave离开了About")
next()
},
}
</script>
<style scoped>
</style>
const router = new VueRouter({
mode:'history',
routes:[...]
})
export default router