Vue学习:组件学习
一、什么是组件
组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可; 组件化和模块化的不同:
- 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
- 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用
二、组件的创建
- 创建方式1
var test_yk = Vue.extend({
template: '<h1>创建组件</h1>'
});
Vue.component('testYk', test_yk );
- 方式2
Vue.component('testYk', Vue.extend({
template: '<h3>创建组件</h3>'
}));
- 方式3
<template id="test">
<h4>创建组件</h4>
</template>
Vue.component('testYk', Vue.extend({
template: '#test'
}));
- 渲染:
<!-- 有大字的要转成驼峰-->
<test-yk></test-yk>
- 创建私有组件
<div id="app1">
<test></test>
</div>
<template id="yk1">
<div>
<h3>我是私有组件</h3>
</div>
</template>
var vm = new Vue({
el: '#app1',
data: {
},
methods: {
},
// 定义实例内部私有组件的
components: {
test: {
template: '#yk1'
}
}
})
三、组件中的data
<body>
<div id="app">
<my></my>
</div>
<script>
//组件中的data必须是一个有返回值的方法,和实例中的data使用不一样
Vue.component('my', {
template: '<h3>这是全局组件 --- {{msg}}</h3>',
data: function () {
return {
msg: '我是vue中的data----组件中的data必须有一个返回值,和实例中的data使用不一样'
}
}
})
var vm = new Vue({
el: '#app',
data: {
},
methods:{
//组件方法
}
})
</script>
</body>
四、使用components属性定义局部子组件
<body>
<div id="app">
<account>
<login></login>
</account>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {},
components: { // 定义子组件
account: { // account 组件
template: '<div><h1>这是Account组件{{name}}</h1><login></login></div>', // 在这里使用定义的子组件
components: { // 定义子组件的子组件
login: { // login 组件
template: "<h3>这是登录组件</h3>"
}
}
}
}
});
</script>
</body>
五、组件的切换
- 使用component实现组件的切换
<body>
<div id="app">
<!-- 组件需要加上单引号,不然应该是以字符串输出了-->
<a href="" @click.prevent="comName='login'">登录</a>
<a href="" @click.prevent="comName='register'">注册</a>
<!-- component 是一个占位符, :is 属性,可以用来指定要展示的组件的名称 -->
<component :is="comName"></component>
</div>
<script>
Vue.component('login', {
template: '<h3>登录组件</h3>'
})
Vue.component('register', {
template: '<h3>注册组件</h3>'
})
var vm = new Vue({
el: '#app',
data: {
// 当前 component 中的 :is 绑定的组件的名称
comName: 'login'
}
})
</script>
</body>
- 使用v-if和v-else实现组件的切换
<div id="app">
<a href="" @click.prevent="flag=true">登录</a>
<a href="" @click.prevent="flag=false">注册</a>
<login v-if="flag"></login>
<register v-else="flag"></register>
</div>
<script>
Vue.component('login', {
template: '<h3>登录组件</h3>'
})
Vue.component('register', {
template: '<h3>注册组件</h3>'
})
var vm = new Vue({
el: '#app',
data: {
flag: false
}
})
</script>
这里需要加上.prevent,防止预设行为,不然切换到注册的一瞬间就又切换回来了。
六、父子组件的传值
- 父组件传值给子组件
<div id="app">
<!-- 父传子可以通过属性绑定方式传值 -->
<yk :parentmsg="msg"></yk>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: '我是父组件的数据'
},
methods: {
},
components: {
//子组件是无法直接获取父组件中的data上的数据和methods 中的方法
yk: {
template: '<h3 @click="change">我是子组件 --- {{parentmsg}}</h3>',
// props 中的数据都是父组件传来的,都是只读的,无法重新赋值
props: ['parentmsg'],
methods: {
//即使强制修改,VUE会报错
change() {
this.parentmsg = '被修改了'
}
}
}
}
})
</script>
- 父组件传方法给子组件
<div id="app">
<!-- 父组件向子组件传递方法,使用的是事件绑定机制v-on, 当我们自定义了一个事件属性之后,那么子组件就能够通过某些方式来调用传递进去的方法了 -->
<!-- 如果show()带括号就是将调用完show的方法的结果返回给func,不带括号的就将show的方法给func-->
<com2 @func="show"></com2>
</div>
<template id="tmpl">
<div>
<h1>这是 子组件</h1>
<input type="button" value="这是子组件中的按钮 - 点击它,触发父组件传递过来的func方法" @click="myclick">
</div>
</template>
<script>
var com2 = {
template: '#tmpl',
methods: {
myclick() {
this.$emit('func')
}
}
}
var vm = new Vue({
el: '#app',
data: {
msg: '我是父组件的数据'
},
methods: {
show() {
console.log('调用了父组件身上的 show 方法: --- ');
}
},
//加载组件
components: {
com2
}
})
</script>
- 子组件传值给父组件(子组件需要使用父组件的方法传值)
<div id="app">
<com2 @func="show"></com2>
</div>
<template id="tmpl">
<div>
<h1>这是 子组件</h1>
<input type="button" value="这是子组件中的按钮 - 点击它,触发 父组件传递过来的 func 方法" @click="myclick">
</div>
</template>
<script>
var com2 = {
template: '#tmpl',
data() {
return {
sonmsg: { name: '张三', age: 16 }
}
},
methods: {
myclick() {
//调用父组件的方法并且穿值给组件
// this.$emit('func', 123)
//传对象
this.$emit('func', this.sonmsg)
}
}
}
var vm = new Vue({
el: '#app',
data: {
msg: '我是父组件的数据'
},
methods: {
show(data) {
//获取子组件传来的值
// console.log('调用了父组件身上的 show 方法: ---获取子组件传的值 ' + data);
//获取子组件传的对象
this.msg = data
console.log("使用子组件的值 " + this.msg.name+" "+this.msg.age);
}
},
//加载组件
components: {
com2
}
})
</script>
七、使用ref获取组件和DOM元素
vue不推荐直接操作dom元素
<body>
<div id="app">
<input type="button" value="获取" @click="getElement" ref="mybtn">
<h3 ref="myH3"> 学习使用ref获取组件和DOM元素</h3>
<hr>
<!-- 组件也是可以通过ref引用的 -->
<login ref="mylogin"></login>
</div>
<script>
var login = {
template: '<h1>登录组件</h1>',
data() {
return {
msg: '我是子组件的数据'
}
},
methods: {
show() {
console.log('调用了子组件的方法')
}
}
}
var vm = new Vue({
el: '#app',
data: {
},
methods: {
getElement() {
//获取dom元素数据
console.log(this.$refs.myH3.innerText)
//通过ref调用子组件的数据
console.log(this.$refs.mylogin.msg);
//通过ref调用子组件的方法
this.$refs.mylogin.show()
}
},
components: {
login
}
})
</script>
</body>