一、父组件传值子组件
Vue.component('login',{
template:'#login',
data(){
return{}
},
props:{
// 自己定义接收
type:String,
size:Number,
// 定义多个数据类型
// pageSize:[String,Number]
// 设置默认值
pageSize:{
type:[Number,String],
default(){
return 5
}
},
},
二、子组件传值父组件
子组件调用父组件的方法
- 在父组件中给引用的子组件注册一个事件(这个事件的名字是自定义的)
- 子组件可以触发这个事件$emit('事件名字')
子组件给父组件传递数据
- $emit方法第二个参数可以定义子组件给父组件传递的内容
- 在父组件中怎么拿到这内容
2.1 父组件这个方法没有自定参数,在父组件的方法直接加这个参数就可以拿到
2.2 父组件有自定义参数,可以传入$event也可以拿到子组件传递的数据。通过$event只能传递第一个参数。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>组件自定义事件</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<!-- 1.给组件添加事件 -->
<div id="app">
<son v-on:click-son='clickParent($event,"自定义参数")' v-on:click-son2='clickParent2'></son>
</div>
<template id='sonTemp'>
<div>
<button @click='clickSon'>点击事件</button>
<button @click='clickSon2'>点击事件2</button>
<h3>这是子组件的内容</h3>
</div>
</template>
<script>
var son = {
template: '#sonTemp',
methods: {
clickSon() {
console.log('子组件的方法');
// 2. 在子组件中触发这个事件
// 发射,触发
// 通过这种方式,子组件也可以给父组件传值
this.$emit('click-son', {
name: '张三'
})
},
clickSon2(){
console.log('子组件的方法2');
this.$emit('click-son2', 'nihao')
}
},
}
var vm = new Vue({
el: '#app',
data: {},
methods: {
// e是接受子组件传过来的参数,msg是这个方法自己参数
clickParent(e, msg) {
console.log(e);
console.log('父组件的方法,数据为:' + msg);
},
clickParent2(e) {
console.log(e);
}
},
components: {
son
}
})
</script>
</body>
</html>
三、ref的使用
1、获取dom节点
(1).给dom节点记上ref属性,可以理解为给dom节点起了个名字。
(2).加上ref之后,在$refs属性中多了这个元素的引用。
(3).通过vue实例的$refs属性拿到这个dom元素。
2、获取组件
(4).给组件记上ref属性,可以理解为给组件起了个名字。
(5).加上ref之后,在$refs属性中多了这个组件的引用。
(6).通过vue实例的$refs属性拿到这个组件的引用,之后可以通过这个引用调用子组件的方法,或者获取子组件的数据。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id='app'>
<div id="good" ref="good"> 好消息,距离国庆 还有7天 </div>
<div> 坏消息,下周一考试 </div>
<son id="myson" ref="myson"></son>
<button @click="changeSon">点我 </button>
</div>
<template id="son">
<div>
son --{{sonMsg}}
<button @click="log1"> 点我</button>
</div>
</template>
<script>
Vue.component("son",{
template: '#son',
data(){
return{
sonMsg:"sonmsg"
}
},
methods:{
log1(){
console.log(1);
}
}
})
console.log(document.getElementById("good"));
const vm = new Vue({
el: '#app',
data: {
},
methods: {
changeSon(){
this.$refs.myson.sonMsg = 'father'
}
},
beforeCreate(){},
created(){
console.log(this.$refs);
console.log(this.$refs.good);
// // dom操作
// this.$refs.good.style.color = 'red'
// this.$refs.good.style.fontSize = '50px'
},
beforeMount(){},
mounted(){
// console.log(this.$refs);
// dom操作
this.$refs.good.style.color = 'red'
this.$refs.good.style.fontSize = '50px'
console.log(document.getElementById("myson"));
console.log(this.$refs.myson.log1());
console.log(this.$refs.myson.sonMsg);
},
beforeUpdate(){},
updated(){},
beforeDestroy(){},
destroyed(){},
})
</script>
</body>
</html>
四、什么是路由
1、后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源
2、前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现
五、路由的基本使用
1、引入js文件,这个js需要放在vue的js后面,自动安装(提供了一个VueRouter的构造方法)
2、创建路由new VueRouter(),接受的参数是一个对象
3、在实例化的对象里配置属性routes:[],这个数组里的对象包含path属性和component属性
4、path属性是url的地址,component属性就是显示的组件(传组件的对象)
5、创建的路由需要和vue实例关联一下
6、路由到的组件显示在哪个位置<router-view></router-view>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 第一步 引入router的js文件 -->
<script src="https://unpkg.com/vue-router@3.0.0/dist/vue-router.js"></script>
<style>
.router-link-active{
font-size: 30px;
color: hotpink;
}
.myactive{
font-size: 40px;
color: red;
}
</style>
</head>
<body>
<div id='app'>
<router-link to="/index">首页1</router-link>
<router-link :to="{name: 'index'}">首页2</router-link>
<router-link to="/detail">去详情0</router-link>
<button @click="gotodetail">去详情</button>
<button @click="gotomine">去个人中心</button>
<!-- 预留的展示区 即被路由链接的显示区域-->
<router-view></router-view>
</div>
<!-- 组件的创建 -->
<template id="index">
<div>
首页
<!-- 普通跳转 -->
<router-link to="/detail">去详情1</router-link>
<!-- 跳转时路径传参 -->
<router-link to="/detail?id=104&name='zs'">
去详情2
</router-link>
<!-- <router-link :to="{path: '/detail',query:{id: 10000,name: 'zs'}}">去详情3</router-link> -->
<!-- <router-link :to="{name: 'my',params:{userid: 2222222}}">去个人中心</router-link> -->
<!-- 缺少params参数 -->
<!-- <router-link :to="{name:'my'}">错误示范</router-link> -->
</div>
</template>
<template id="detail">
<div>
详情页
</div>
</template>
<template id="mine">
<div>
个人页
</div>
</template>
<script>
// Vue.component('index',{
// template: '#index',
// });
// 简写声明组件
let index = {
template: '#index',
}
let detail = {
template: '#detail',
}
let mine = {
template: '#mine',
}
// 第二步 创建一个路由
const router = new VueRouter({
routes: [
// 路由重定向
{
path: '/',
redirect: '/index',
},
// 确定路由方向
{
// url地址
path:'/index',
// 配合的组件
component: index,
// 对应声明的组件
name:'index'
},
{
// url地址
path:'/detail',
// 配合的组件
component: detail,
// 对应声明的组件
name:'detail'
},
// 路径传参
{
path:'/mine/:userid',
component:mine,
name:'my'
}
],
// 自定义路由激活时高亮
linkActiveClass: 'myactive'
});
const vm = new Vue({
el: '#app',
// 挂载定义的路由到Vue实例上
router,
data: {
},
methods: {
// 点击进行函数式跳转
gotodetail(){
this.$router.push({path:'/detail'})
this.$router.push({path:'/mine',query:{id:104,name:'list'}});
},
gotomine(){
this.$router.push({path:'/my',params:{userid:666}});
},
},
// 监听 跳转的方向是否正确。。
// watch: {
// $route(){
// console.log(this.$route);
// if(this.$route.name == 'my'){
// alert('你好');
// }
// }
// },
created(){
},
beforeMount(){
},
mounted(){
},
beforeUpdate(){
},
updated(){
},
})
</script>
</body>
</html>
路由高亮:
1、使用默认的样式
直接设置router-link-active
2、自定义样式
配置 linkActiveClass:'自定义的类名'
路由重定向 :
通过redirected重定向
六、计算属性和监听器
1.watch:监听data中属性的改变
const vm = new Vue({
el: '#app',
data: {
firstName:"",
lastName:"",
// name:"",
},
// watch监听data中属性的改变
watch:{
firstName:function(value){
console.log(value);
this.name = this.firstName + '-' +this.lastName
},
lastName:function(value){
console.log(value);
this.name = this.firstName + '-' +this.lastName
},
},
})
2.computed:默认只有getter的计算属性,定义有getter和setter的计算属性
(1)getter:只要该表达式中含有的data中的数据发生改变时,该属性中的数据就会发生改变
(2)setter:只有当自身发生改变的时候才触发
const vm = new Vue({
el: '#app',
data: {
firstName:"",
lastName:"",
// name:"",
},
// 属性计算
computed: {
// 属性不能和data中重复
// name() {
// return this.firstName + '-' +this.lastName;
// },
name: {
get:function(){
return this.firstName + '-' +this.lastName;
},
// 只有当自身发生改变的时候才触发
set(value){
console.log(value);
console.log(value.split('-'));
if( value.split('-').length ==2){
this.firstName = value.split('-')[0]
this.lastName = value.split('-')[1]
}
}
},
},
})
method、computed和watch的区别
1.computed属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用,使用的时候不加();
2.methods方法表示一个具体的操作,主要书写业务逻辑;
3.watch一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;可以看作是computed和methods的结合体