全局组件的简单使用

  • 组件的定义
  • 组件的复用性
  • 全局组件只要使用了 全局就可以用 性能不高 但是使用是比较方便的
const app = Vue.createApp({
    template: `
    <div>
        hello 
        <div>world</div>    
    </div>
    `
})
// 绑定元素
const vm = app.mount('#root')

如果把 hello 和 word 拆出来 需要创建两个组件

app.component('hello', {
    template: `
    <div>
        hello
    </div>
    `
})

app.component('word', {
    template: `
    <div>
        word
    </div>
    `
})

局部组件

// 声明局部组件
 const counter = {
    data(){
        return {
            count: 1
        }
    },
    template: `
    <div @click="count +=1">{{count}}</div>
    `
}

const app = Vue.createApp({
    template: `
    <div>
      <counter />
    </div>
    `,
    components: {
        counter: counter
    }
})

组件间传值以及传值校验
父组件给子组件传值

const app = Vue.createApp({
            template: `
            <div>
              <test content=1 />
            </div>
            `
        })

        app.component('test', {
            props: ['content'],
            template: `
            <div>
                {{content}}
                {{ typeof  content}}  
                数据类型是string 如果换成数字也是string
            </div>
            `
        })

如果想传递本身的数据类型,可以使用动态传值

如果是冒号的方式传递值,是动态传值,不带冒号的传值是静态传值,值是写死的

const app = Vue.createApp({
    data () {
        return {
            num: 123
        }
    },
    template: `
    <div>
      <test v-bind:content='num' />
    </div>
    `
})

app.component('test', {
    props: ['content'],
    template: `
    <div>
        {{content}}
        {{ typeof  content}}  
    </div>
    `
})

数据类型的校验
如果在 vue3中 数据类型不匹配,在控制台会有警告

// String  Boolean Array Object Function Symbol 
props: {
    content: String
}
 const app = Vue.createApp({
            data () {
                return {
                    num: ()=>{alert(123)}
                }
            },
            template: `
            <div>
              <test :content='num' />
            </div>
            `
        })

        app.component('test', {
            // props: ['content'],
            props: {
                content: Function
            },
            template: `
            <div @click="this.handleClick">
                {{ typeof  content}}  
            </div>
            `,
            methods: {
                handleClick(){
                    alert(456)
                    this.content()
                }
            }
        })
props: {
	content: {
	    type: Number,
	    // 必须传
	    required: true,
	    // 限定传入的值的范围
	    validator: function (value) {
	        // 如果是 < 1000 返回的是 true  否则返回的就是 false 
	        return value < 1000
	    },
	    // default: 789
	    default: function(){
	        return 456
	    }
	}
},

实现单项数据流
了解什么是单项数据流:子组件可以使用父组件传递过来的值,但是,不能修改父组件中的值

如果不是单项数据流,使用多个子组件的时候,修改其中的一个子组件,其他的子组件也会被修改,降低了代码的耦合性

Non-Props属性是什么

// Non-Props 属性,也就是父组件给子组件传值 不使用 props接收
1、父组件还是传值,子组件使用props接收,接收的数据不用,结构会清晰
2、Non-Props 属性就是不使用props接收的值,那么传递的值会被当做子组件的属性使用
<div>Counetr</div> 会放在子组件的根元素div下面,并且 msg='hello word' 会变成其属性的存在

const app = Vue.createApp({
    template: `
    <div>
      <counter msg="hello word" />
    </div>
    `,
})

/* 
如何不接收父组件的 Non-Props属性
子组件中设置 inheriAttrs: false  不接收父组件中的 Non-Props属性
*/
app.component("counter", {
    inheritAttrs: true,
    template: `
    <div>
            Counter
    </div>
    `,
});

Non-Props的使用场景

// 比如添加类名 class 以及行内样式等
const app = Vue.createApp({
            template: `
            <div>
              <counter class="box" style="color: red" />
            </div>
            `,
        })

        /* 
        如何不接收父组件的 Non-Props属性
        子组件中设置 inheriAttrs: false  不接收父组件中的 Non-Props属性
        */
        app.component("counter", {
            inheritAttrs: true,
            template: `
            <div class="box1">
                    Counter
            </div>
            `,
        });

但是,如果子元素使用了多个根元素,Non-Props就会失效

app.component("counter", {
inheritAttrs: true,
template: `
<div>
        Counter
</div>
<div>
        Counter
</div>
<div>
        Counter
</div>
`,
});

如何让多个根元素也可以使用Non-Props属性

const app = Vue.createApp({
    template: `
    <div>
      <counter class="box" style="color: red" :msg1='haha' :msg="gaga" />
    </div>
    `,
})

/* 
如果子元素是多个根元素,想使用Non-Props属性 去 $attrs.class中取值
*/
app.component("counter", {
    mounted(){
        console.log(this.$attrs);
    },
    // inheritAttrs: true,
    template: `
    <div v-bind:class="$attrs.class">
            Counter
    </div>
    <div>
            Counter
    </div>
    <div>
            Counter
    </div>
    `,
});

父子组件如何通过事件进行通信
建议1:触发事件的时候,用驼峰的方式 addOne

建议2:监听事件的时候,使用短横线 add-one

const app = Vue.createApp({
data () {
    return {
        count: 1
    }
},
methods: {
    handleAddOne(){
        this.count +=1
    }
},
template: `
<div>
  <counter  :count="count" @add-one="handleAddOne"/>
</div>
`,
})

app.component('counter', {
props: ['count'],
methods: {
    addOne() {
        // 不能直接使用count 也不能修改 this.couun
        // 需要注册事件
        this.$emit('addOne')
    }
},
template: `
<div @click='addOne'>{{count}}</div>
`
})

也可以传递更多的数据

const app = Vue.createApp({
    data () {
        return {
            count: 1
        }
    },
    methods: {
        handleAddOne(param1){
            this.count += param1
        }
    },
    template: `
    <div>
      <counter  :count="count" @add-one="handleAddOne"/>
    </div>
    `,
})

app.component('counter', {
    props: ['count'],
    methods: {
        addOne() {
            // 不能直接使用count 也不能修改 this.couun
            // 需要注册事件
            // 也可以在这个位置直接计算this.$emit('addOne', this.count+2)
            // this.$emit('addOne', 2, 3)
            this.$emit('addOne', this.count+2)

        }
    },
    template: `
    <div @click='addOne'>{{count}}</div>
    `
})

如果一个子组件,向外部触发一个事件的话,emits可以知道向外部触发了哪些事件

 /* 子组件向外部触发事件 -- 如果事件名和下面需要触发的事件名不匹配,会在控制台提出警告*/
 emits: ['addOne'],// emits: ['add'],

emits也可以使用函数的形式

emits: {
    // count是事件addOne传递的参数
    addOne: (count) => {
        console.log(count);
        // 满足条件允许传递
        if (count < 0) {
            return true
        }
        // 不满足条件不允许传递
        return false
    }
},
Logo

前往低代码交流专区

更多推荐