组件
-
组件为了拆分Vue实例的代码量,能够让我们以不同的组件,来划分不同的功能模块,需要什么样的功能就使用对应的组件
-
组件化:是从UI界面的角度划分;方便代码分层开发,保证功能模块的单一
-
模块化:是逻辑代码的角度划分,前端组件化,方便UI组件的重复利用
创建组件方式一
<script src="node_modules/vue/dist/vue.js"></script>
//组件的使用
<div id="app">
<!--
自定义的组件
注意:myComl在写成元素的时候 驼峰命名不在适用,需要在中间添加一个 - 链接 my-coml
若是在命名的时候没有驼峰命名,在引用的时候就不必在使用 - 链接,直接使用可以了
-->
<my-coml></my-coml>
</div>
<script>
//1创建全局的Vue组件 模板对象
var coml = Vue.extend({
//指定组件要展示的html结构
template:"<h2> 这是使用Vue.extend创建的组件</h2> "
})
//Vue.component("组件的名称",创建出来的组件模板对象)
Vue.component("myComl",coml)
//实例创建
new Vue({
el:"#app",
})
</script>
创建方式二
<script src="node_modules/vue/dist/vue.js"></script>
<div id="app">
<mycmol></mycmol>
</div>
<script>
//创建组件 在模板对象直接用对象代替
Vue.component("mycmol",{
data:function () {
return {
count:0
}
},
template:`<div>
<h1>这是第二种创建组件的方式</h1>
<button @click='count++'>这是开始{{count}}</button>
</div>`
})
new Vue({
el:"#app"
})
</script>
- 注意:在创建模板时,必须要只有一个根元素,所以需要用
容器元素
包裹子元素 - 组件可以有自己的
data
,但是组件的data
是一个function
(函数),必须返回一个对象
创建方式三
//引包
<script src="node_modules/vue/dist/vue.js"></script>
//HTML
</div><div id="app">
<mycoml3></mycoml3>
</div>
<!--模板代码结构-->
<template id="teml">
<div>
<h1>这是通过template元素创建的组件的结构</h1>
<h4>这样方便些html元素</h4>
</div>
//JS
<script>
//创建组件
Vue.component("mycoml3",{
template:"#teml"
})
new Vue({
el:"#app"
})
</script>
定义私有组件
<div id="app">
<login></login>
</div>
<script>
new Vue({
el:"#app",
components:{
//定义私有组件
//组件的名称
login:{
//模板对象字符串
template:`<div>
<label>
name:
<input type="text" placeholder="登录。。。">
</label>
</div>`
}
}
})
</script>
多个组件之间的切换
- 在
Vue
中提供了component
元素,这是一个占位符
元素,可以根据:is属性
来绑定要显示的元素
<component :is="comName"></component>
<div id="app">
<a href="" @click.prevent="loginHandle">登录</a>
<a href="" @click.prevent="registerHandle">注册</a>
<a href="" @click.prevent="forgetHandle">忘记密码</a>
<!--Vue提供的component元素,来展示对应名称的组件-->
<!--component是一个暂未符 根据:is属性 后面对应的名称 来展示对应的组件-->
<component :is="comName">
<!--绑定一个属性 变量 根据@click点击方法 赋值 切换组件-->
</component>
</div>
<script>
Vue.component("login",{
template:"<h2>登录组件</h2>"
})
Vue.component("register",{
template:"<h2>注册组件</h2>"
})
Vue.component("forget",{
template:"<h2>忘记密码组件</h2>"
})
new Vue({
el:"#app",
data:{
//默认显示 登录组件
comName:"login"
},
methods:{
loginHandle:function () {
this.comName = "login"
},
registerHandle:function () {
this.comName = "register"
},
forgetHandle:function () {
this.comName = "forget"
}
}
})
</script>
多个组件之间的过渡
- 就按照上面的代码例子说 我们只需要加一个
transition
元素 - 注意:多个组件之间的过渡有一个
mode
属性,mode="out-in
表示一个组件包动画先离开完全之后,另外一个组件在进来
//样式
.v-enter,
.v-leave-to{
opacity: 0;
transform: translateY(50px);
}
.v-enter-active,
.v-leave-active{
transition: all 0.5s ease;
}
<transition mode="out-in" >
<!--Vue提供的component元素,来展示对应名称的组件-->
<!--component是一个暂未符 根据:is属性 后面对应的名称 来展示对应的组件-->
<component :is="comName">
<!--绑定一个属性 变量-->
</component>
</transition>
父组件传值子组件
<div id="App">
<!--父组件,在引用子组件的时候,可以通过属性绑定(v-bind:)的方式,把需要传递的数据给子组件-->
<coml :parmsg="msg"></coml>
</div>
<script>
new Vue({
el:"#App",
data:{
msg:"父组件是不是?"
},
methods:{
},
components:{
coml:{
data:function () {
//字组件中的data数据 ,并不是父组件传递的,是子组件私有的
//比如:子组件通过Ajax,请求回来的数据,可以放到data身上
//data里面的数据是可读可写的
return {
title:"这是一个标题",
content:"www"
}
},
template:`<h1>这是一个子组件的H1++{{parmsg}}++{{title}}</h1>`,
//绑定好属性之后,在props中 写入这个属性,这样才可以使用这个数据
// 组件中的所有props中的数据,都是通过父组件传递给子组件的
//里面的数据之可读的
props:["parmsg"]
}
}
})
- 小总结
- 父组件在向子组件传值时
- 1.通过属性绑定(
v-bind:
)定义一个新的属性
- 2.将这个
新的属性
写入props
数组,这个里面的数据只可读,不可更改,否则报错
父组件传递方法给子组件
-
v-on
方属性绑定
<div id="app">
<!--父组件传递方法给子组件-->
<teml @func="show"></teml>
</div>
<!--模板---子组件-->
<template id="tml">
<div>
<h1>子组件现不现实</h1>
<input type="button" value="子组件" @click="myclick">
</div>
</template>
<script>
new Vue({
el:"#app",
data:{},
methods:{
show(){
console.log("点击父组件上的方法");
}
},
components:{
teml:{
data:function () {
return{}
},
template:"#tml",
props:[],
methods:{
myclick:function () {
console.log("是不是点击");
//拿到父组件的方法,调用
//emit出发 调用
this.$emit("func");
// 注意如果父组件上的函数有参数,那么这个 emit的第二个参数起,就是父组件函数参数与之对应
//调用父组件中的方法,并向父组件方法中传递参数this.$emit("func",123,456);
}
}
}
}
})
</script>
小案例
- 结合组件的的介绍点训练
//引包, Vue.js 和 bootstrap
<script src="node_modules/vue/dist/vue.js"></script>
<link rel="stylesheet" href="lib/bootstrap-3.3.7.css">
//Html
<div id="app">
<!--父组件 向 子组件传递方法 -->
<temp @func="loadCommtent"></temp>
<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="tmp1">
<div>
<div class="form-group ">
<label >评论人:</label>
<input type="text" class="form-control" v-model="name">
</div>
<div class="form-group ">
<label >评论内容:</label>
<textarea class="form-control" v-model="content"></textarea>
</div>
<div class="form-group">
<input type="button" value="发表评论" class="btn btn-primary" @click="postComment">
</div>
</div>
</template>
//JS
<script>
var contentbox = {
data:function () {
return {
name:"",
content:""
}
},
template:"#tmp1",
methods:{
//发表评论的方法
postComment(){
//1.数据存到 本地 localStorage
//2.localStorage只支持字符串,把对象转化成json字符串,在之前要处理判断
//是否有字符串
//3.若是localStorage中的评论字符串,为空不存在,则可以返回一个`[]`让json.parse转换
if (!this.name || !this.content) {
alert("请正确输入。。。")
return;
}
var comment = {id:Date.now(),name:this.name,content:this.content};
//获取本地数据
var list = JSON.parse(localStorage.getItem("cms") ||"[]");
list.unshift(comment);
//保存数据到本地
localStorage.setItem("cms",JSON.stringify(list));
//清空属性数据
this.name = this.content = "";
this.$emit("func");
}
}
}
new Vue({
el:"#app",
data:{
list:[
{id:Date.now(),name:"TT",content:"这是一个新的评论"},
{id:Date.now(),name:"CC",content:"CC这是一个新的评论"},
{id:Date.now(),name:"DD",content:"DD这是一个新的评论DDDD"}
]
},
created() {
this.loadCommtent();
},
methods:{
loadCommtent:function () {
//获取本地数据
var list = JSON.parse(localStorage.getItem("cms")||"[]");
//赋值给list属性
this.list = list;
}
},
components:{
temp:contentbox
}
})
</script>
render
渲染
-
render
属性对应的是一个方法函数,这个函数有一个固定的形参createElements
是一个方法,当你把模板组件传入
的时候,返回一个渲染的页面html
, 这个方法会把原来的div
删除,把返回的html渲染删除的div界面
<div id="app">
</div>
<script>
var login = {
template:"<h1>这是登录组件</h1>"
}
new Vue({
el:"#app",
data:{},
methods:{},
render:function(createElements){
//createElements是一个方法,调用它,能够把指定的组件模板,渲染为html结构
return createElements(login);
//注意:返回的结果会替换页面中 指定的那个容器(也就是会把页面中的div删除掉,把这个返回的代替原来删除的)
}
})
</script>
网友评论