一、vue组件
1.1 子组件传值父组件
子组件调用父组件的方法
在父组件中给引用的子组件注册一个事件(这个事件的名字是自定义的)
子组件可以触发这个事件$emit('事件名字')
子组件给父组件传递数据
$emit方法第二个参数可以定义子组件给父组件传递的内容
在父组件中怎么拿到这内容
2.1 父组件这个方法没有自定参数,在父组件的方法直接加这个参数就可以拿到

2.2 父组件有自定义参数,可以传入$event也可以拿到子组件传递的数据。通过$event只能传递第一个参数。

<!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="./vue-2.4.0.js"></script>
<script src="./axios.js"></script>
</head>

<body>
<div id='app'>
<father></father>
</div>

<template id="father">
<div>
<!-- 子组件调用父组件的方法
1. 在父组件中给引用的子组件注册一个事件(这个事件的名字是自定义的)
2. 子组件可以触发这个事件$emit('事件名字',传递数据) -->


father
<br>
子传父:{{fromsondata}}
<br>
<son @myson="fromson"></son>
</div>
</template>

<template id="son">
<div>
son
<button @click="tofather"> 点我传参</button>
</div>
</template>


<script>
Vue.component("father", {
template: "#father",
data() {
return {
msg: 'hello',
fromsondata: ""
}
},
methods: {
// data就是子组件传的值
fromson(data) {
console.log(data);
this.fromsondata = data

}
}

})
Vue.component("son", {
template: "#son",
data() {
return {

}
},
created() {
// 触发子传父 this.$emit( ‘自定义事件’,传递参数)
// this.$emit('myson','这是来自子组件的参数')
},
methods: {
tofather() {
// 子传父
this.$emit('myson', '这是来自子组件的参数')
}
},
})


const vm = new Vue({
el: '#app',
data: {},
methods: {},
})
</script>
</body>

</html>

 

1.2 评论列表案例
将评论发表做成一个组件,发表后保存到localStorage中
获取用户输入的值
构造一个对象
把数据存起来(localStorage)
3.1 首先获取已经保存的数据(localStorage.getItem('key')).

3.2 把数据添加进去

3.3 在把数据保存到localStorage中(localStorage.setItem('key','value'))

子组件更新后父组件同步更新
子组件更新数据后,通知父组件
1.1 父组件引用子组件的时候注册一个事件

1.2子组件更新完数据之后调用$emit方法通知父组件

<!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>
<link rel="stylesheet" href="./bootstrap-3.4.1-dist/css/bootstrap.min.css">
<script src="./vue-2.4.0.js"></script>
</head>

<body>
<div id='app'>
<div class="container">
<!-- 引入子组件 -->
<son @getlist="fromson"></son>

<ul class="list-group">
<li class="list-group-item" v-for="(item,index) in list" :key="index">
{{item.comment}}
<span class="badge">评论人:{{item.name}}--{{item.ctime}}</span>
</li>
</ul>
</div>
</div>
<template id="son">
<div>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">留言板</h3>
</div>
<div class="panel-body">
<form action="" method="POST" role="form">
<div class="form-group">
<label for="">姓名</label>
<input type="text" v-model="name" class="form-control" id="" placeholder="Input field">
</div>
<div class="form-group">
<label for="">留言</label></label>
<input type="text" v-model="comment" class="form-control" id="" placeholder="Input field">
</div>
<!-- <button type="submit" class="btn btn-primary" @click.prevent="addComment">发布评论</button> -->
<button type="button" class="btn btn-primary" @click="addComment">发布评论</button>
</form>
</div>
</div>
</div>
</template>
<script>
Vue.component("son", {
template: "#son",
data() {
return {
name: '',
comment: '',
}
},
methods: {
addComment() {
// 子传父 子组件给父组件传值
this.$emit("getlist", {
name: this.name,
comment: this.comment,
// ctime: new Date().toLocaleDateString()
// ctime: new Date().toDateString()
ctime: new Date().toLocaleTimeString()
// ctime: new Date().toString()
// ctime: new Date().toTimeString()
})
}
}
})


const vm = new Vue({
el: '#app',
data: {

list: [],
},
methods: {
fromson(data) {
console.log(data);
// this.list.push(data)
this.list.unshift(data)
}
}
})
</script>
</body>

</html>

 

1.3 ref的使用
获取dom节点
给dom节点记上ref属性,可以理解为给dom节点起了个名字。
加上ref之后,在$refs属性中多了这个元素的引用。
通过vue实例的$refs属性拿到这个dom元素。
获取组件
给组件记上ref属性,可以理解为给组件起了个名字。
加上ref之后,在$refs属性中多了这个组件的引用。
通过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="./vue-2.4.0.js"></script>
</head>

<body>
<div id='app'>


<!-- ref 1.获取dom。操作dom 2.获取组件,拿到组件上的数据和方法 -->
<div id="box" ref="refdiv"> haha</div>
<div id="box2" ref="refdiv2"> haha</div>
<son id="son2" ref="son2"></son>


<h1>{{sonmsg}}</h1>

</div>
<template id="son">
<div>
son
<button @click="log1">按钮</button>
</div>
</template>


<script>
Vue.component("son",{
template:"#son",
data(){
return{
msg:"hello"
}
},
methods:{
log1(){
console.log(1);
}
}
})


var box = document.getElementById("box")
var son = document.getElementById("son2")
// console.log(son.innerHTML);
// console.log(box);
const vm = new Vue({
el: '#app',
data: {
sonmsg:""
},
methods: {},
mounted() {
// console.log(box);
box.style.color = "red"
console.log(this.$refs);
this.$refs.refdiv.style.color = 'red'
this.sonmsg = this.$refs.son2.msg
this.$refs.son2.log1()
},
})
</script>
</body>

</html>

 

二. Vue中路由的使用
2.1 什么是路由
后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源
前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;
在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由)
2.2 如何使用路由
1、路由的安装
直接引用官网提供的cdn

路由的基本使用

引入js文件,这个js需要放在vue的js后面,自动安装(提供了一个VueRouter的构造方法)
创建路由new VueRouter(),接受的参数是一个对象
在实例化的对象里配置属性routes:[],这个数组里的对象包含path属性和component属性
path属性是url的地址,component属性就是显示的组件(传组件的对象)
创建的路由需要和vue实例关联一下
路由到的组件显示在哪个位置<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>
<!-- 1.引入 放在vue后面 -->
<script src="https://unpkg.com/vue-router@3.0.0/dist/vue-router.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id='app'>
<!-- 5/展示区域 -->
<router-view></router-view>
</div>
<template id="index">
<div>
index首页
</div>
</template>

<template id="detail">
<div>
详情页
</div>
</template>
<script>

let index = {
template:"#index"
}
let detail = {
template:"#detail"
}
// 2.创建vuerouter实例
const router = new VueRouter({
// 3.创建映射关系
routes:[
{
// 路径
path:'/',
// 对应组件
component:index
},
{
path:"/detail",
component:detail
}
]

})


const vm = new Vue({
el: '#app',
data: {
},
methods: {
},
// 4.将路由挂载在vue实例上
// router:router,
router
})
</script>
</body>
</html>

 

路由的跳转
router-link标签可以设置to属性
默认是a标签,可以通过tag设置包裹标签

<router-link to="/"> 首页</router-link>
<router-link to="/detail">详情页</router-link>

<a href="#/">首页</a>
<a href="#/detail">详情页</a>

 

路由重定向
redirect可以进行路由的重定向

routes: [
// 重定向
{
path: '/',
redirect: "/index"
},

{
// 路径
path: '/index',
// 对应组件
component: index
},
{
path: "/detail",
component: detail
}
]

 

选中路由高亮
使用默认的样式
直接设置router-link-active

自定义样式
配置 linkActiveClass:'自定义的类名'

组件的嵌套
声明路由的时候设置children,这是children是一个数组,数组里是路由对象
这个children的组件就会渲染在它父组件的<router-view>中
命名视图
我们之前只能一个地址对应一个组件,现在可以一个地址对应多个组件
components属性设置的
给router-view设置名字,这个名字和components组件名字是对应的
设置默认值default对应组件可以设置名字也可以访问
3. 计算属性和监听器
名称案例

获取完整的名字,需要把姓和名字拼接在一起
什么时候去拼接在一起(input值改变的时候)
监听keyup知道input什么时候改变了,在这里就可以获取完整的名字
3.1 Method实现
3.2 Watch用法
3.3 Computed用法

<!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="./vue-2.4.0.js"></script>
</head>

<body>
<div id='app'>
<input type="text" v-model='firstname'>+
<input type="text" v-model="lastname"> <button @click="getname">=</button>
<input type="text" v-model="name">
</div>


<script>
const vm = new Vue({
el: '#app',
data: {
firstname: "",
lastname: "",
name: ''
},
methods: {
getname() {
this.name = this.firstname + this.lastname
}
},
//属性监听
watch: {
"firstname": function(newvalue, oldvalue) {
this.name = this.firstname + this.lastname
},
"lastname": function(newvalue, oldvalue) {
this.name = this.firstname + this.lastname
}
},
// 属性计算 不能和data里面数据冲突
// 计算属性中所依赖的任何一个 data 属性改变之后,都会重新触发 本计算属性 的重新计算,从而更新 fullName 的值
// computed:{
// // name:function(){
// // return this.firstname + '-' + this.lastname
// // }
// // 2
// name:{
// get:function(){
// return this.firstname + '-' + this.lastname
// },
// // 只有修改自身时会触发
// set:function(value){
// console.log(value);
// this.firstname = value.split("-")[0]
// this.lastname = value.split("-")[1]
// }
// }
// }

})
</script>
</body>

</html>