# .natvie
>能够在使用组件的时候,将事件传递到组件的根元素上面。(默认在调用组件的时候,写的一些事件,是不会被触发比如:click。)
# $listeners实例属性是干什么的。
>在我们调用组件的时候,可以给组件上面写上一些个事件。但是默认这个事件是不会被执行的。如果我想让他执行。需要给事件加上.native的属性。这个时候,我这个事件是绑定在组件的根元素的。。如果我需要将这个事件不绑定在根元素上。这时就需要$listeners。他里面的内容。就是你在组件调用的时候,定义的那个事件。。
#组件需要可复用性高。灵活性高。(代码不要写死)
#有时需要对组件的prop进行双向绑定
# slot
base-layout
#组件的作用域
PS:
1.组件有自己的作用域,里面的数据只能在里面自己找。找不到就报错了。
2.父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
#作用域插槽
#对象解构
```js
varprop= {h:'msg',s:'哈哈哈哈'};
var{h} =prop; =>varh=prop.h;
var{h,s} =prop;=>varh=prop.h;vars=prop.s;
```
# keep-alive vue默认提供的一个内置组件。用于缓存当前不活动|失活|看不见的的组件或路由或。。。。
#组件动态切换会使组件被销毁。。再次出现会重建。
#如果想实现缓存组件的话,就只需要将keep-alive内置组件做为容器将他们给包裹起来。
1.原生事件
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<metahttp-equiv="X-UA-Compatible"content="ie=edge">
<title>Document</title>
</head>
<body>
<divid="app">
<!--
子组件调用根元素自己的方法
默认情况下我们在组件的标签上绑定的事件是不会执行的
我们组件调用最终渲染是渲染template
如果我们需要让事件执行的话就在后面加上一个
.active就能让这个时间绑定到这个组件的根元素上
-->
<l-p@click.native="fn1"v-if="isShow"></l-p>
<l-c@click="fn2"@keyup="fn2"></l-c>
</div>
</body>
</html>
<scriptsrc="../js/vue.js"></script>
<script>
//如何让根组件的方法绑定在子组件的元素上
// 在元素上添加v-on="$listeners"
// 在组件的外侧调用事件
// 作用是在我们调用组件的时候可以给我们的的组件协商一些事件
// 但是默认这个组件是不会执行的,如果我们想要他执行,就要给
// 这个事件加上.native的属性,这个事件是我们绑定在根元素上的事件
// 如果我们需要将这个事件绑定在元素上的时候,.active就不能绑定
// 就需要使用v-on="$listeners",他里面的内容就是你在组件调用的时候
// 定义的事件
Vue.component('l-c', {
template:`
<div style="width:100px;height:100px;border:1px solid #000;">
<input type="text" v-on="inputEvent" />
<button @click="$listeners.click">我要调用fn2</button>
</div>
`,
computed: {
//第一个参数空对象,根元素的事件对象,自己组件的事件
inputEvent() {
returnObject.assign({},this.$listeners, {
'keydown': ()=>{
this.fn1();
}
})
}
},
methods:{
fn1(){
console.log("我是自己定义的fn1")
}
},
mounted() {
console.log(this.$listeners)
}
});
Vue.component('l-p', {
template:`
<div>
<h1 @click.stop="fn1">我是l-p的组件</h1>
</div>
`,
methods: {
fn1() {
alert("我是l-p自己的方法,我用了阻止")
}
}
});
varvm=newVue({
el:'#app',
data: {
isShow:true
},
methods: {
fn1() {
this.isShow=false;
},
fn2() {
console.log("点击到了l-c的根元素上")
}
}
})
</script>
2.sync修饰符
<body>
<divid="app">
<!--这种操作有些复杂,需要同过$emit自定义事件去触发-->
<!-- <l-p :msg="msg" @update="msg=$event"></l-p> -->
<!--
提供了一个灵活的sync的修饰符,也是相当于一个语法糖
完成了双向的一个数据传递
-->
<l-p:msg.sync="msg"></l-p>
<!--单项传递数据-->
<!-- <input type="text" v-model="msg"> -->
<!--双向数据绑定-->
<!--
页面刷新不存在了,如果要保存数据需要本地数据或者是保存到数据库
-->
<inputtype="text"placeholder="用户名"v-model="username">
<inputtype="password"placeholder="密码"v-model="password">
<button@click="fn1">提交</button>
</div>
</body>
</html>
<scriptsrc="../js/vue.js"></script>
<script>
Vue.component('l-p', {
props: ['msg'],
template:`
<h1 @click="fn1">{{ msg }}</h1>
`,
methods: {
fn1(){
this.$emit('update:msg','王五')
}
}
})
varvm =newVue({
el:'#app',
data:{
msg:"我的天",
username:localStorage.getItem('username')||"",
password:"",
},
methods:{
fn1(){
localStorage.setItem('username',this.username);
}
}
})
</script>
3.slot插槽,以及插槽作用域
<body>
<divid="app">
<!--
template在标签里面使用就是一个默认
提供的内置组件
在组件里使用就是一个模板
-->
<!--
编译作用域
1.组件没有作用域链,组件只能调用自己的数据没有就会报错
2.父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
-->
<base-layout>
<template>
<divslot="header">我是头部</div>
<div>我是二级头部</div>
</template>
<div>我是内容</div>
<!-- <div slot="footer">我是底部</div> -->
</base-layout>
</div>
</body>
</html>
<scriptsrc="../js/vue.js"></script>
<script>
Vue.component('base-layout', {
template:`
<div>
<header>
<slot name="header"></slot>
</header>
<section>
<slot></slot>
</section>
<footer>
<!--默认内容可以直接在插槽中写就好了-->
<slot name="footer">
我是底部的默认内容
</slot>
</footer>
</div>
`
})
varvm =newVue({
el:'#app',
data:{
msg:'编译作用域'
}
})
</script>
4.slot插槽,结构赋值
<body>
<divid="app">
<l-p>
<!--
slot-scope="prop"
得到的是一个对象
只想输出一个的时候可以{{ prop.s }}
按照对象使用即可
这就是作用域插槽
可以把组件的数据放出来个大家使用
-->
<h1slot-scope="prop">我是一个l-p组件的插槽内容{{ prop.s }}</h1>
<!--
结构赋值
用法
-->
<h1slot-scope="{ h }">我是一个l-p组件的插槽内容{{ h }}</h1>
</l-p>
</div>
</body>
</html>
<scriptsrc="../js/vue.js"></script>
<script>
Vue.component('l-p', {
data () {
return{
title:'我的天'
}
},
template:`
<div>
<!--
我们直接绑定插槽是拿不到这个title中的值
我们需要在页面标签上插入slot-scope="prop"
在需要渲染的地方输出{{ prop }}
-->
<slot h="title" s="hahahaha"></slot>
</div>
`
})
varvm =newVue({
el:'#app'
})
</script>
5.动态组件keep-alive
<body>
<divid="app">
<button@click="curPage='l-home'">首页</button>
<button@click="curPage='l-list'">列表</button>
<button@click="curPage='l-about'">关于</button>
<!--
动态组件
组件动态切换会使组件被销毁,再次会出现重建
如果想实现缓存组件的话,就只需要keep-alive内置组件
作为容器将他们给包括起来。
还可以配置三个组件
include -字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude -字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max -数字。最多可以缓存多少组件实例。(:max="2")
-->
<keep-alive>
<component:is="curPage"></omponent>
</keep-alive>
</div>
</body>
</html>
<scriptsrc="../js/vue.js"></script>
<script>
Vue.component('l-home', {
data () {
return{
name:'张胜男'
}
},
template:`
<div style="border:1px solid #000;width:400px;height:400px;overflow:auto">
我是首页
<div style="height:4000px;">
{{ name }}
<button @click='name="张三"'>修改名字</button>
</div>
</div>
`,
created () {
console.log("我回来啦")
}
,
beforeDestroy () {
console.log('啊!!~~啊~~~aaa~~~我被销毁了')
},
//如果做了缓存之后会多两个生命周期函数
activated () {
//激活缓存,并显示
console.log("activated")
},
deactivated () {
//被缓存,并且隐藏
console.log('deactivated');
}
})
Vue.component('l-list', {
template:`
<div>
我是列表页
</div>
`
})
Vue.component('l-about', {
template:`
<div>
我是关于页
</div>
`
})
varvm =newVue({
el:'#app',
data:{
curPage:"l-home"
}
})
</script>