一、生命周期
参考网址:https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA
二、定义Vue组件
- 组件基础
参考网址:https://cn.vuejs.org/v2/guide/components.html
* 案例:列表评论
<!DOCTYPE html>
<html lang="zh">
<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 href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
[v-cloak]{
display:none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
//调用组件模板
<discuss @func="flash"></discuss>
<ul class="list-group">
<li class="list-group-item" v-for="item in list" :key="item.id">
<span class="badge">{{item.name}}</span>
{{item.content}}
</li>
</ul>
</div>
//调用组件
<template id="el">
<form action="">
<div class="form-group">
<label for="author">作者:</label>
<input type="text" id="author" class="form-control" v-model:value="author">
</div>
<div class="form-group">
<label for="content">内容:</label>
<textarea name="" id="content" class="form-control" v-model:value="content"></textarea>
</div>
<div class="form-group">
<input type="button" class="form-control btn-primary" @click="add" value="发表">
</div>
</form>
</template>
<script src="./js/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
list:[],
},
//localstorage实现本地存储的方法
methods:{
flash(){
this.list=JSON.parse(localStorage.getItem('discuss-list') || '[]');
}
},
// components创建一个局部组件
components:{
//创建一个组件的模板
discuss:{
//template设置一个组建
template:'#el',
//data必须是一个函数return返回的必须是一个对象
data(){
return{
author:'',
content:'',
};
},
methods:{
add(){
let list =JSON.parse(localStorage.getItem('discuss-list') || '[]');
list.push({id:Math.random(100),name:this.author,content:this.content});
localStorage.setItem('discuss-list',JSON.stringify(list));
this.author=this.content='';
this.$emit('func');
}
}
}
},
created:function(){
this.flash();
},
});
</script>
</body>
</html>
* 父组件与子组件相互调用复习案例:
<!DOCTYPE html>
<html lang="zh">
<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>
</head>
<body>
<div id="app" v-cloak>
{{msg}}
<ccom v-bind:qian="msg" v-on:func="call"></ccom>
</div>
<template id="el">
<div>
<h1>这里是内部组件</h1>
<button v-on:click="say">点击触发VUE实例中的方法</button>
<p>{{qian}}</p>
</div>
</template>
<script src="../js/vue.js"></script>
<script type="text/javascript">
//创建一个全局组件
Vue.component('viw',{
template:"<h1>这是全局组件</h1>",
//data 必须是一个函数,返回值必须是一个对象
data(){
return {};
}
});
new Vue({
el:"#app",
data:{
msg:"我有200块钱,儿子 你想要吗?",
money:''
},
components:{
ccom:{
template:"#el",
data(){
return {
msg:"爸爸 给你10块钱去挥霍吧"
};
},
props:['qian'],//父组件调用子组件----->先在全局标签内绑定一个函数,再在js局部组件中使用props调用,
/*
//这里使用pros接受的数据的名称与组件传递的时候绑定的名称是一模一样的
*/
methods:{//子组件传向父组件----->先在组件标签里绑定一个函数,再在js局部组件中使用$emit调用,
say(){
//对于父组件传递的方法而言,其实并不是将这个方法传递给子组件,而是要求子组件将这个方法进行触发.
//$emit 函数触发的函数如果是需要传递参数,那么按照参数的顺序从第二个参数开始进行传递
this.$emit('func',this.msg);
}
}
}
},
methods:{
call(i){
// console.log(i)
this.money = i;
}
}
});
</script>
</body>
</html>
三、插槽
参考网址:https://cn.vuejs.org/v2/guide/components-slots.html
1、Vue中插槽的作用和使用方法
参考网址:https://blog.csdn.net/willard_cui/article/details/82469114
定义一个名child子组件,为该子组件添加内容应该在子组件的template中定义,直接在父组件的<child>标签中定义的内容不会被渲染,
<div id="root">
<child>
需要插槽才能渲染的内容
<p>Dell</p>
<p>Lee</p>
</child>
</div>
<script>
Vue.component('child',{
template: `<div>
<p>这是子组件中正常渲染的内容</p>
<slot></slot>
</div>`
}
)
var vm=new Vue({
el:'#root'
})
</script>
2、插槽默认内容
插槽可以提供一个默认内容,如果如果父组件没有为这个插槽提供了内容,会显示默认的内容。如果父组件为这个插槽提供了内容,则默认的内容会被替换掉
父组件提供插槽内容
<div id="root">
<child>
<p>Hello</p>
</child>
</div>
<script>
Vue.component('child',{
template:'<div><slot>defalut value</slot></div>
}
)
var vm=new Vue({
el:'#root'
})
</script>
3、具名插槽
当需要多个插槽时,可以使用<slot>的特性:name。这个特性可以用来定义额外的插槽。
<div id="root">
<child>
<header slot="header">header</header>
<footer slot="footer">footer</footer>
</child>
</div>
<script>
Vue.component('child',{
template:`<div>
<slot name="header">default header</slot>
<div>content</div>
<slot name="footer">default footer</slot>
</div>`
}
)
var vm=new Vue({
el:'#root'
})
</script>
4、作用域插槽
可以先看一个例子,以便更好的理解作用域插槽的作用
在子组件中使用v-for创建一个列表循环,然后在父组件中通过子组件标签child调用,
<div id="root">
<child></child>
<child></child>
</div>
<script>
Vue.component('child',{
data: function(){
return {
list:[1,2,3,4]
}
},
template: '<div><ul><li v-for="value in list">{{value}}</li></ul></div>',
})
var vm=new Vue({
el: '#root'
})
</script>
调用了两次child组件,因为调用的是同一个子组件,所以显示的内容完全一样。如何在每次调用时能有各自的渲染效果?这就是作用域插槽的用武之地。
作用域插槽就是父组件在调用子组件的时候给子组件传了一个插槽,这个插槽为作用域插槽,该插槽必须放在template标签里面,同时声明从子组件接收的数据放在一个自定义属性内,并定义该数据的渲染方式。通过下列展示作用域插槽的使用方式:
<div id="root">
<child>
<template slot-scope="props"><!--定义一个插槽,该插槽必须放在template标签内-->
<li>{{props.value}}</li><--!定义使用渲染方式-->
</template>
</child>
<child>
<template slot-scope="props">
<h1>{{props.value}}</h1><!--定义不同的渲染方式-->
</template>
</child>
</div>
<script>
Vue.component('child',{
data: function(){
return {
list:[1,2,3,4]
}
},
template: `<div>
<ul>
<slot v-for="value in list" :value=value>//使用slot占位
</slot>
</ul>
</div>`
})
var vm=new Vue({
el: '#root'
})
</script>
* 插槽案例:
<!DOCTYPE html>
<html lang="zh">
<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>
</head>
<body>
<div id="app" v-cloak>
<com>
<!-- 插槽机制也能够帮助我们实现数据的传递,只是这种传递是停留在视图层的,并没有进入到代码层 -->
here is the best place!---{{pm}}
</com>
</div>
<template id="el">
<div>
<h1>这里是组件</h1>
{{msg}}
<slot></slot>
</div>
</template>
<script src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
pm:'my name is pm'
},
components:{
com:{
template:"#el",
data(){
return {
msg:"这是组件数据"
};
}
}
}
});
</script>
</body>
</html>
四、路由
参考网址https://cn.vuejs.org/v2/guide/routing.html
什么是路由?
- 我们认识的路由:
进入到网站的根目录,然后根据文件夹的名称或者文件名去找到对应的文件,然后运行
后端的路由
指网络上的某一个资源URL
后端框架的出现,以及安全性的考虑,后端一般做单一的入口
例如:http://localhost/vue_api/index.php?m=api&a=getlist
单一的入口是指在这个入口文件中,通过路由参数的方式(m=api&a=getlist)将请求分发给不同的资源或者文件处理
前端路由
锚点实现的路由
前端的路由是不会发生页面的刷新或者页面的重启请求的
hash值的变化是不会造成页面重新请求的
* 路由案例:登录注册
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
/* mint-active */
.router-link-active{
background: #00FFFF;
color:lightseagreen;
font-size: 20px;
}
.v-enter,
.v-leave-to{
opacity: 0;
transform: translateX(200px);
}
.v-enter-active,
.v-leave-active{
transition: all 1s ease;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<!-- 使用router-link的标签实现路由的连接 -->
<router-link to="/login" tag="span">登录</router-link>
<router-link to="/register" tag="span">注册</router-link>
<!-- <router-link to="/guanggai" tag="span">逛街</router-link> -->
<!-- <a href="#/login">登录</a>
<a href="#/register">注册</a> -->
<transition mode="out-in">
<router-view></router-view>
</transition>
</div>
<script src="../lib/vue.js"></script>
<script src="../lib/vue-router.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
const login = {
template:`
<div>
这是登录组件
</div>
`,
};
const register = {
template:`
<div>
这是注册组件
</div>
`,
}
new Vue({
el:"#app",
data:{
},
components:{
guanggai:{
template:'<div>这是逛街</div>'
}
},
//路由规则
router: new VueRouter({
routes:[
//redirect重定向,将符合规则的路由发送到指定的路由
{path:'/',redirect:'/login'},
{path:'/login',component:login},
{path:'/register',component:register},
// {path:'/guanggai',component:guanggai}
],
linkActiveClass:'is_selected'
})
});
</script>
</body>
</html>