Vue组件化 模板 语法糖 函数 父子组件通信
导读:@TOC1 注册组件的基本步骤创建爱你组件构造器:Vue.extends( 注册组件:Vue.component( 使用组件2 组件的基本使用<div id="app"> <!-- 3 使用组件 --> <...
@TOC
1 注册组件的基本步骤
- 创建爱你组件构造器:
Vue.extends()
- 注册组件:
Vue.component()
- 使用组件
2 组件的基本使用
div id="app">
!-- 3 使用组件 -->
my-cpn>
/my-cpn>
my-cpn>
/my-cpn>
my-cpn>
/my-cpn>
/div>
script src="../js/vue.js">
/script>
script>
// 1 创建组件构造器对象
const cpnConstructor = Vue.extend({
template: `
div>
h2>
标题/h2>
p>
哈哈哈/p>
/div>
`
}
)
// 2 注册组件
Vue.component('my-cpn', cpnConstructor)
const app = new Vue({
el: '#app',
data: {
message: "你好,有勇气的牛排"
}
}
)
/script>
3 全局组件和局部组件
script src="../js/vue.js">
/script>
script>
// 1 创建组件构造器
const cpnC = Vue.extend({
template: `
div>
h2>
标题/h2>
p>
内容/p>
/div>
`
}
)
// 2 组件注册(全局组件: 意味着可以在多个Vue实例下面使用)
// Vue.component('cpn', cpnC)
// Vue实例1
const app = new Vue({
el: '#app',
data: {
message: "你好,有勇气的牛排"
}
,
// 局部组件
components:{
// cpn使用组件时的标签名
cpn:cpnC
}
}
)
// Vue实例2
const app2 = new Vue({
el: '#app2'
}
)
/script>
4 父组件和子组件
div id="app">
cpn2>
/cpn2>
/div>
script src="../js/vue.js">
/script>
script>
// 1 创建爱你第1个组件构造器(子组件)
const cpnC1 = Vue.extend({
template: `
div>
h2>
标题1/h2>
p>
666/p>
/div>
`
}
)
// 2 创建爱你第2个组件构造器(父组件)
const cpnC2 = Vue.extend({
template: `
div>
h2>
标题2/h2>
p>
777/p>
cpn1>
/cpn1>
/div>
`,
components: {
cpn1: cpnC1
}
}
)
// root组件
const app = new Vue({
el: '#app',
data: {
message: "你好,有勇气的牛排"
}
,
components: {
cpn2: cpnC2
}
}
)
/script>
5 注册组件语法糖
主要省区了调用Vue.extend()的步骤,而是可以直接使用一个对象来代替
script>
// 1 全局组件注册的语法糖
// 1 创建组件构造器
// const cpn1 = Vue.extend()
// 2 组件注册(全局方式)
Vue.component('cpn1', {
template: `
div>
h2>
标题1/h2>
p>
666/p>
/div>
`
}
)
const app = new Vue({
el: '#app',
data: {
message: "你好,有勇气的牛排"
}
,
components: {
'cpn2': {
template: `
div>
h2>
标题2/h2>
p>
777/p>
/div>
`
}
}
}
)
/script>
6 组件模板分离写法 组件数据存放
存放
- 组件对象向也有一个data属性(也可以有methods等属性)
- 只是这个data属性必须是一个函数
- 而且这个函数返回一个对象,对象内部保存着数据
div id="app">
cpn1>
/cpn1>
cpn2>
/cpn2>
/div>
!-- 1 script标签,注意:类型必须是text/x-template -->
script type="text/x-template" id="cpn1">
div>
h2>
标题1/h2>
p>
666/p>
/div>
/script>
!-- 2 template标签 -->
template id="cpn2">
div>
h2>
标题2/h2>
p>
777/p>
/div>
/template>
script src="../js/vue.js">
/script>
script>
// 注册一个全局组件
Vue.component('cpn1', {
template: '#cpn1'
}
)
Vue.component('cpn2', {
template: '#cpn2'
}
)
const app = new Vue({
el: '#app',
data: {
message: "你好,有勇气的牛排"
}
}
)
/script>
7 组件中data为什么是函数
div id="app">
cpn>
/cpn>
cpn>
/cpn>
cpn>
/cpn>
/div>
!-- 组件实例对象 -->
template id="cpn">
div>
h2>
当前计数:{
{
counter }
}
/h2>
button @click="increment">
+/button>
button @click="decrement">
-/button>
/div>
/template>
script src="../js/vue.js">
/script>
script>
// 1 注册组件
Vue.component('cpn', {
template: '#cpn',
data() {
return {
counter: 0
}
}
,
methods: {
increment() {
this.counter++;
}
,
decrement() {
this.counter--;
}
}
}
)
const app = new Vue({
el: '#app',
data: {
message: "你好,有勇气的牛排"
}
}
)
/script>
8 父子组件的通信
- 通过props想自键传递数据
- 通过时间向父组件发送消息
props数据验证
支持:String、Number、Boolean、Array、Object、Date、Function、Symbol
div id="app">
!-- cpn v-bind:cmovies="movies" :cmessage="message">
/cpn>
-->
cpn v-bind:cmovies="movies">
/cpn>
/div>
template id="cpn">
div>
h2>
{
{
cmessage }
}
/h2>
ul>
li v-for="item in cmovies">
{
{
item }
}
/li>
/ul>
/div>
/template>
script src="../js/vue.js">
/script>
script>
// 父传子:props
const cpn = {
template: '#cpn',
// props: ['cmovies', 'cmessage'],
props: {
// 1 类型限制
// cmovies:Array,
// cmessage:String
// 2 提供一些默认值
cmessage: {
type: String,
default: '666',
required: true
}
,
// 类型是对象或者数组时,默认值必须是一个函数
cmoves: {
type: Array,
default() {
return []
}
}
}
,
data() {
return {
}
}
,
methods: {
}
}
const app = new Vue({
el: '#app',
data: {
message: "你好,有勇气的牛排",
movies: ['三体', '金刚狼', '疯狂外星人']
}
,
components: {
cpn
}
}
)
/script>
9 父子通信-父传子(props中的驼峰命名)
div id="app">
cpn :c-info="info" :child-my-message="message">
/cpn>
/div>
template id="cpn">
h2>
{
{
cInfo }
}
/h2>
/template>
script src="../js/vue.js">
/script>
script>
const cpn = {
template: '#cpn',
props: {
cInfo: {
type: Object,
default() {
return {
}
}
}
,
childMyMessage: {
type: String,
default: ''
}
}
}
const app = new Vue({
el: '#app',
data: {
info: {
name: "有勇气的牛排",
age: 18,
sex: 0
}
}
,
components: {
cpn
}
}
)
/script>
10 组件通信-子传父(自定义事件)
什么时候需要使用自定义事件?
- 当子组件需要想父组件传递数据时,就要用到自定义事件了
- v-on不仅仅可以用于监听DOM事件,也可以用于组件间的自定义事件
自定义事件的流程
- 在子组件中,通过$emit()来触发事件。
- 在父组件中,通过v-on来鉴定子组件事件
!-- 子组件模板 -->
template id="cpn">
div>
button v-for="item in categories"
@click="btnClick(item)">
{
{
item.name }
}
/button>
/div>
/template>
script src="../js/vue.js">
/script>
script>
// 1 子组件
const cpn = {
template: '#cpn',
data() {
return {
categories: [
{
id: '1', name: '热门推荐'}
,
{
id: '2', name: '手机数码'}
,
{
id: '3', name: '家电'}
,
{
id: '4', name: '电脑办公'}
,
{
id: '5', name: '衣服'}
,
{
id: '6', name: '玩具'}
]
}
}
,
methods: {
btnClick(item) {
// console.log(item)
// 发射事件: 自定义事件
this.$emit('item-click', item)
}
}
}
// 2 父组件
const app = new Vue({
el: '#app',
data: {
message: '有勇气的牛排'
}
,
components: {
cpn
}
,
methods: {
cpnclick(item) {
console.log('cpnclick', item);
}
}
}
)
/script>
11 12 组件通信 案例
见gitee源代码
13 父子组件的访问方式:$children
有时候我们需要父组件直接访问子组件,子组件直接访问父组件,或者是组件访问跟组件。
- 父组件访问子组件:使用$children或者$refs(reference 引用)
- 子组件访问父组件:$parent
div id="app">
cpn>
/cpn>
cpn ref="key1">
/cpn>
cpn>
/cpn>
button @click="btnClick">
按钮/button>
/div>
template id="cpn">
div>
我是子组件/div>
/template>
script src="../js/vue.js">
/script>
script>
const app = new Vue({
el: '#app',
data: {
message: "你好,有勇气的牛排"
}
,
methods: {
btnClick() {
// 1 $children
// console.log(this.$children);
// this.$children[0].showMessage();
// this.$children[0].name;
// for(let c of this.$children){
// c.showMessage();
// }
// 2 $refs =>
对象类型,默认是一个空对象 ref='key1'
console.log(this.$refs.key1.name);
}
}
,
components: {
cpn: {
template: '#cpn',
data() {
return {
name: '我是子组件的name'
}
}
,
methods: {
showMessage() {
console.log('showMessage');
}
}
}
}
}
)
/script>
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: Vue组件化 模板 语法糖 函数 父子组件通信
本文地址: https://pptw.com/jishu/340380.html