Vue组件
Vue组件
组件的出现就是为了拆分Vue实例的代码量的,能够让我们以不同的组件来划分不同的功能模块,将来我们需要什么样的功能就去调用相应的组件即可。
创建组件
方式1:使用Vue.extend创建组件对象,使用Vue.component注册组件
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 使用时直接把组件名当作标签使用即可,但若组件名是驼峰命名,则要用-分隔 -->
<my-Com1></my-Com1>
</div>
<script>
//1.1使用Vue.extend 来创建全局的组件
var com1 = Vue.extend({
//通过template来创建组件中要展示的内容,组件有且仅有一个根元素
template: '<h3>这是用extent创建的组件</h3>',
})
//1.2使用Vue.component(组件名称,组件对象)注册组件
Vue.component('myCom1', com1);
var vm = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
</body>
</html>
方式二:直接使用Vue.component(组件名,{组件对象});
上面的组件可以改写为
<script>
//使用Vue.component(组件名称,组件对象)注册组件
Vue.component('myCom2', {
//通过template来创建组件中要展示的内容,组件有且仅有一个根元素
template: '<h3>这是用extent创建的组件</h3>',
});
var vm = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
方式三:将template后面的标签字符串在外面定义好通过id属性引用
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<temp1></temp1>
</div>
<template id="tmp1">
<div>
<h3>使用template定义标签字符串</h3>
</div>
</template>
<script>
Vue.component('temp1', {
template: '#tmp1'
});
var vm = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
</body>
</html>
定义私有组件
你可以通过一个普通的 JavaScript 对象来定义组件:
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
然后在 components
选项中定义你想要使用的组件:
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
对于 components
对象中的每个 property 来说,其 property 名就是自定义元素的名字,其 property 值就是这个组件的选项对象。
注意局部注册的组件在其子组件中*不可用*。例如,如果你希望 ComponentA
在 ComponentB
中可用,则你需要这样写:
var ComponentA = { /* ... */ }
var ComponentB = {
components: {
'component-a': ComponentA
},
// ...
}
组件中的data和methods
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<temp1></temp1>
<temp2></temp2>
</div>
<template id="temp1">
<div>
<h1>组件中的data和methods</h1>
<!-- 可以直接引用自己组件中的data -->
<h2>{{msg}}</h2>
</div>
</template>
<template id="temp2">
<div>
<button @click="addCount">点击</button>
<h3>点击了:{{btncount}}次</h3>
</div>
</template>
<script>
//1. 组件可以有自己的data,但组件的data必须是一个方法,且该方法需要返回一个对象
Vue.component('temp1', {
template: '#temp1',
//之所以定义为一个方法是为了同一个组件的多个实例之间的数据独立。
//若需要这个组件的实例共享数据,可以在最外面定义一个对象,然后在方法中返回这个对象
data: function () {
return {
msg: "这是组件中的data"
};
}
})
Vue.component('temp2', {
template: "#temp2",
data: function () {
return {
btncount: 0
};
},
methods: {
addCount() {
this.btncount++;
}
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
</body>
</html>
组件之间的切换
方式1:通过v-if切换
方式2:通过component标签切换
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="../css/animate.min.css">
<script src="../js/vue.js"></script>
</head>
<body>
<!-- 方式1 -->
<div id="app">
<a href="" @click.prevent="flag=!flag">登录</a>
<a href="" @click.prevent="flag=!flag">注册</a>
<login v-if="flag"></login>
<signin v-else="flag"></signin>
</div>
<!-- 方式2 -->
<div id="app2">
<a href="" @click.prevent="comName='login'">登录</a>
<a href="" @click.prevent="comName='signin'">注册</a>
<!-- mode="out-in"指退出动画结束,再开始进入动画 -->
<transition mode="out-in" enter-active-class="animate__bounceIn" leave-active-class="animate__bounceOut"
:duration="1000">
<!-- 用transition包裹起来可以实现切换动画 -->
<component :is="comName"></component>
</transition>
</div>
<template id="login">
<form action="#">
<label for="userName">
账号:
<input type="text" />
</label>
<label for="userPwd">
密码:
<input type="text" />
</label>
<input type="submit" value="登录" />
</form>
</template>
<template id="signin">
<form action="#">
<label for="userName">
账号:
<input type="text" />
</label>
<label for="userPwd">
密码:
<input type="text" />
</label>
<label for="userName">
邮箱:
<input type="text" />
</label>
<input type="submit" value="注册" />
</form>
</template>
<script>
Vue.component('signin', {
template: "#signin"
});
Vue.component('login', {
template: "#login"
});
var vm = new Vue({
el: '#app',
data: {
flag: true
},
methods: {}
});
var vm2 = new Vue({
el: '#app2',
data: {
comName: "login"
},
methods: {}
});
</script>
</body>
</html>
组件传值
- 父组件向子组件传值
- 子组件通过方法调用给父组件传值
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 1. 在子组件标签上绑定一个自定义属性 -->
<com1 :prmsg="msg"></com1>
<!-- method-show是自定义事件,将方法传递给子组件只能通过事件绑定v-on: -->
<com2 @method_show="show"></com2>
</div>
<template id="com2">
<div>
<!-- 先调用自己的方法,再通过方法去调用父组件的方法 -->
<h2 @click="myclick">这是子组件2</h2>
</div>
</template>
<script>
var com2 = {
template: "#com2",
data: () => {
return {
msg: '子组件数据'
}
},
methods: {
myclick() {
console.log('调用了子组件的my_click方法' + this.msg);
//$emit是触发调用的意思
this.$emit('method_show', this.msg); //第一个参数是调用的方法,第二个参数起是给方法的参数
}
}
}
var vm = new Vue({
el: '#app',
data: {
msg: "父组件的msg呀"
},
methods: {
show(data) {
console.log('调用了父组件的show方法');
this.msg = this.msg + data;
}
},
components: {
'com1': {
//3. 在组件中使用
template: "<h2>这是子组件呀---{{prmsg}}</h2>",
//2. 在子组件中用props申明1中自定义的标签
//这个标签是只读的,不能修改,若强行修改Vue会报警告并建议使用data。
props: ['prmsg']
},
com2
}
});
</script>
</body>
</html>