父子组件间通信
ref 获取 DOM 元素 和 组件
路由
<div id="app">
<com1 v-bind:parentmsg="msg">com1>
div>
<script>
let vm = new Vue({
el: '#app',
data: {
msg: '123 父组件中的数据'
},
methods: {},
components: {
com1: {
//props中的数据,都是只读的,无法重新赋值。
props: ['parentmsg'],//把父组件传递过来的 parentmsg 属性,先在 props 数组中,先定义一下,这样才能使用这个数据
template: '这是子组件---{{parentmsg}}
'
}
}
})
script>
<div id="app">
<com1 @func="show">com1>
div>
<template id="tmp1">
<div>
<h1>这是子组件h1>
<button @click="myclick">这是子组件的中的按钮button>
div>
template>
<script>
let com2 = {
template: '#tmp1',
methods: {
myclick() {
// emit 英文原意:是触发,调用,发射的意思
this.$emit('func')
}
}
}
let vm = new Vue({
el: '#app',
data: {},
methods: {
show() {
console.log('调用父组件身上的show方法')
}
},
components: {
com1: com2
}
})
script>
<div id="app">
<com1 @func="show">com1>
div>
<template id="tmp1">
<div>
<h1>这是子组件h1>
<button @click="myclick">这是子组件的中的按钮button>
div>
template>
<script>
let com2 = {
template: '#tmp1',
data () {
return {
list: [{'id': '1', 'age': '18'}]
}
},
methods: {
myclick() {
// emit 英文原意:是触发,调用,发射的意思
this.$emit('func', this.list)
}
}
}
let vm = new Vue({
el: '#app',
data: {},
methods: {
show(data) {
console.log(data)
}
},
components: {
com1: com2
}
})
script>
发表评论案例
所需知识点: 父子组件传值,localStorage 本地储存
代码:
<div id="app">
<comment-box @func="loadlocalStorage">comment-box>
<ul class="list-group">
<li class="list-group-item" v-for="item in list" :key="item.id">
<span class="badge">{{item.user}}span>
{{item.content}}
li>
ul>
div>
<template id="tmp1">
<div>
<div class="form-group">
<label for="exampleInputEmail1">user:label>
<input type="search" class="form-control" id="exampleInputEmail1" placeholder="user" v-model="user">
div>
<div class="form-group">
<label for="exampleInputEmail2">content:label>
<textarea class="form-control" id="exampleInputEmail2" v-model="content" placeholder="发表留言">textarea>
div>
<button type="button" class="btn btn-primary" style="margin-bottom: 15px" @click="Postcomment">发表
div>
template>
<script>
let commentBox = {
template: '#tmp1',
data() {
return {
user: '',
content: ''
}
},
methods: {
Postcomment() {
//分析:发表评论的业务逻辑
//1.评论数据存到哪里去? 存放到 localStorage 中 localStorage.setItem('cmts','')
//2.先组织出一个最新的评论数据对象
//3.想办法,把 第二步中,得到的评论对象。保存到 localStorage 中
// 3.1 localStorage 只支持存放字符串数据,要先调用 JSON.stringify
// 3.2 在保存最新的 评论数据之前,要先从 localStorage 获取之前的评论数据 (string),转换为一个数组对象然后把最新的评论,push到这个数组
// 3.3 如果获取到的localStorage中 的评论字符串,为空不存在,则 可以 返回一个'[]' ,让JSON.parse 去转换
// 3.4 把 最新的 评论列表数组,再次调用 JSON.stringify 转换为 数组字符串,然后调用 localStorage.setItem()
let comment = {id: Date.now(), user: this.user, content: this.content}
//从 localStorage 获取所有的评论
let list = JSON.parse(localStorage.getItem('cmts') || '[]')
list.unshift(comment)
//重新保存 最新的评论数据
localStorage.setItem('cmts', JSON.stringify(list))
this.user = this.content = ''
this.$emit('func')
}
}
}
let vm = new Vue({
el: '#app',
data: {
list: [{id: Date.now(), user: '李白', content: '天生我材必有用'},
{id: Date.now(), user: '张三', content: '锄禾日当午'},
{id: Date.now(), user: '李四', content: '白日依山尽'}]
},
created() {
//从本地的 localStorage 中加载评论列表
this.list = JSON.parse(localStorage.getItem('cmts') || '[]')
},
methods: {
loadlocalStorage() {
this.list = JSON.parse(localStorage.getItem('cmts') || '[]')
}
},
components: {
commentBox: commentBox
}
script>
<div id="app">
<button @click="getElement">获取元素button>
<h3 id="myh3" ref="myh3">今天阳光明媚h3>
div>
<script>
let vm = new Vue({
el: '#app',
data: {},
methods: {
getElement() {
// console.log(document.getElementById('myh3').innerText)
console.log(this.$refs.myh3.innerText)
}
}
})
script>
<div id="app">
<button @click="getElement">获取元素button>
<h3 id="myh3" ref="myh3">今天阳光明媚h3>
<hr>
<login ref="mylogin">login>
div>
<script>
let login = {
template: '这是组件
',
data() {
return {
msg: '这是子组件的数据'
}
},
methods: {
show() {
console.log('这是子组件的show方法')
}
}
}
let vm = new Vue({
el: '#app',
data: {},
methods: {
getElement() {
// console.log(document.getElementById('myh3').innerText)
// console.log(this.$refs.myh3.innerText)
console.log(this.$refs.mylogin.msg)
}
},
components: {
login
}
})
script>
可以参考
后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源;
前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;
在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由);URL中的hash(井号)
Vue Router
实用小文档
<script src="../../vue.min.js">script>
<script src="../vue-router.js">script>
<div id="app">
<a href="#/login">登陆a>
<a href="#/register">注册a>
<router-view>router-view>
div>
<script>
//组件模板对象
let login = {
template: '登陆组件
'
}
let register = {
template: '注册组件
'
}
//2. 创建 一个路由对象,当 导入 vue-router 包之后,在window 全局对象中,就有了一个 路由的构造函数,叫做 VueRouter
// 在new 路由对象的时候,可以为 构造函数,传递一个配置对象
let routerobj = new VueRouter({
// routes :这个配置对象中的 route 表示 【路由匹配规则】 的意思
routes: [//路由匹配规则
//每个路由规则,都是一个对象,这个规则对象身上,有两个必须的属性
//属性1 是 path ,表示哪个路由链接地址;
//属性2 是 component ,表示,如果 路由是前面匹配到的 path,则展示 component 属性对应的那个组件
{path: '/login', component: login},
{path: '/register', component: register}
]
})
let vm = new Vue({
el: '#app',
data: {
msg: 'sadsad'
},
router: routerobj //将路由规则对象,注册到 vm 实例上,用来监听 URL 地址的变化,然后展示对应的组件
})
script>
<div id="app">
<router-link to="/login?id=10">登陆router-link>
<router-link to="/register">注册router-link>
<router-view>router-view>
div>
<script>
//组件模板对象
let login = {
template: '登陆组件
',
created() {
console.log(this.$route)
}
}
let register = {
template: '注册组件
'
}
let routerobj = new VueRouter({
routes: [ //路由匹配规则
{path: '/', redirect: '/login'},//这里的 redirect 和 Node 中 的redirect 完全是两回事
{path: '/login', component: login},
{path: '/register', component: register}
]
})
let vm = new Vue({
el: '#app',
data: {
msg: 'sadsad'
},
router: routerobj //将路由规则对象,注册到 vm 实例上,用来监听 URL 地址的变化,然后展示对应的组件
})
script>
或者:==>更简洁,直观!
<div id="app">
<router-link to="/account">accountrouter-link>
<router-view>router-view>
div>
<template id="tmp1">
<div>
<h1>这是account组件h1>
<router-link to="/account/login">登录router-link>
<router-link to="/account/register">注册router-link>
<router-view>router-view>
div>
template>
<script>
let account = {
template: '#tmp1'
}
let login = {
template: 'login
'
}
let register = {
template: 'register
'
}
let router = new VueRouter({
routes: [{
path: '/account',
component: account,
/*使用 children 属性,实现子路由,同时,子路由的 path 前面,不要带 / ,
否则永远以根路径开始请求,这样不方便我们用户去理解URL地址*/
children: [
{path: 'login', component: login},
{path: 'register', component: register}
]
}]
})
let vm = new Vue({
el: '#app',
data: {
msg: '哈哈'
},
router
})
script>
<style>
*{
margin: 0;
padding: 0;
}
.header{
height: 80px;
background: orange;
}
.container{
display: flex;
height: 400px;
}
.left{
background: #2b542c;
flex: 2;
}
.main{
background: red;
flex: 8;
}
style>
<div id="app">
<router-view>router-view>
<div class="container">
<router-view name="left">router-view>
<router-view name="main">router-view>
div>
div>
<script>
let header = {
template: 'Header头部区域
'
}
let leftBox = {
template: 'leftBox区域
'
}
let mainBox = {
template: 'mainBox区域
'
}
let router = new VueRouter({
routes: [
// {path:'/',component:header},
// {path:'/left',component:leftBox},
// {path:'/main',component:mainBox}
{
path: '/', components: {
default: header,
left: leftBox,
main: mainBox
}
}
]
})
let vm = new Vue({
el: '#app',
data: {
msg: '哈啊哈'
},
router
})
script>