Vue 组件

89 阅读1分钟

1. 组件

组件
概念组件即自定义控件
用途组件能够封装可重用代码,扩展HTML标签功能
本质自定义标签
分类全局组件:不同作用域内均可使用 局部组件:只在定义该组件的作用域内可以使用

❗注意:组件和Vue实例类似,需要注册后才可以使用。

创建组件的步骤: ①创建组件 ②注册组件 ③使用组件

<body>
    <div id="app">
        <!-- 组件名中含有大写字母,浏览器编译的时候会转成小写,导致找不到相应的组件,
        可以全变成小写,中间加-来解决 -->
        <!-- 所有的组件都需要使用一个div来包裹 -->
        <div>
            <child-b />
        </div>
        <div>
            <son />
        </div>
    </div>
    <!-- 模板的第二种写法 使用template加id -->
    <template id="ChildB">
        <!-- template里面也需要使用div来包裹一下 -->
        <div>
            <h1>我是ChildB</h1>
            <h1>我是ChildB</h1>
            <div>
                <child-a />
            </div>
        </div>
    </template>
    <script src="./node_modules/vue/dist/vue.min.js"></script>
    <script>
        /* 一定要写在new Vue的前面 */
        /* 全局组件 */
        Vue.component('ChildA', {
            /* 模板的第一种写法 直接写 */
            template: '<h1>我是ChildA</h1>',
            created: function () {
                console.log('我是childA')
            }
        })
        Vue.component('ChildB', {
            template: '#ChildB'
        })
        // 在Vue实例创建的为局部组件
        new Vue({
            el: "#app",
            //局部组件
            components: {
                son: {
                    template: `<h1>我是局部组件son</h1>`,
                    created() {
                        console.log('son')
                    }
                }
            }
        })
    </script>
复制代码
复制代码

1.2子组件的数据问题

前提:对象的内存问题。 2022-03-15_115927.png

  1.子组件的DATA赋值之所以使用函数RETURN的方式是因为:每次retur的对象都独占了一份内存空间,所以在修改组件实例的数据时,不会发生连锁效应。
    
  2.如果使用{}对象的方式直接赋值,那么多次服用组件的实例的DATA属性指向同一个对象,产生连锁反应

2022-03-15_120927.png

2. 父子组件传值

2.1 子改父的步骤

①使用Vue里面的$emit方法发送一个自定义事件,如childchange
②在子组件上使用@childchange="ctrl" 绑定自定义事件,触发父组件的ctrl方法
③通过父组件的方法修改了父组件的值

    <!-- 父组件有个一个数组对象 传值给子组件展示    
    点击子组件里面的某一项 可以把父组件里面的数组的某一项给删除 -->
    <div id="box">
        <kid :list='list' @delkid='del' />
    </div>
    <template id="kid">
        <div>
            <ul>
                <li v-for="(item,index) in list" :key="index" @click="del(index)">{{item.content}}</li>
            </ul>
        </div>
    </template>
    <script src="./node_modules/vue/dist/vue.min.js"></script>
    <script>
        new Vue({
            el: '#box',
            data: {
                list: [{ content: 'apple' }, { content: 'pineapple' }, { content: 'applepie' }]
            },
            methods: {
                del(index) {
                    this.list.splice(index, 1)
                }
            },
            components: {
                kid: {
                    template: '#kid',
                    props: ['list'],
                    methods: {
                        del(index) {
                            this.$emit('delkid', index)
                        }
                    },
                }
            }
        })
    </script>
复制代码
复制代码

3. 添加属性且触发视图更新

vue 的缺陷:给引用数据类型添加的属性不能进行视图渲染

解决方法

1—— this.set()// this.delete

    <div id="app">
        <h1>{{list}}</h1>
        <button @click="fn">添加age</button>
        <hr>
        <h1>{{arr}}</h1>
        <button @click="fn2">添加car</button>
    </div>
    <script src="./vue.min.js"></script>
    <script>
        new Vue({
            el: "#app",
            data: {
                list: {
                    name: 'tom'
                },
                arr: [{
                    name: 'jack'
                }, {
                    name: 'taotao'
                }]
            },
            methods: {
                fn() {
                    /* Vue2的一个缺陷不可以给对象添加新属性 
                    解决这个bug的方案是 使用$set*/
                    /* this.$set(目标对象,具体的key要使用引号,具体的值) */
                    this.$set(this.list, 'age', 30)
                    console.log(this.list)
                },
                fn2() {
                    /* 这是更新对象数据的方式 */
                    // this.$set(this.arr[1],'car','bmw')
                    /* 这个更新数组的到视图的方式 */
                    /* 三个参数分别对应 目标数组 数组所在的索引 和需要修改的内容 */
                    this.$set(this.arr, 1, { name: 'taotao', car: 'benchi' })
                }
            }
        })
    </script>

2——this.$forceUpdata()暴力刷新

methods:{
                click(){
                   this.xinxi.forEach(i => {
                       this.$set(i,'age','18')                      
                   });
                },
                del(i){
                    delete(this.xinxi[i].age)
                    this.$forceUpdate()
                }
            },