Vue学习笔记02

前端小白的碎碎念:好难好难好难。。。。。,还需要多看

一、Vue中的options

const vm = new Vue(options)
options的五类属性:
1)数据:data、 props、 propsData、 computed、methods、 Watch
2)DOM: el、 template、 render、 renderError
3)生命周期钩子: beforeCreate、 created、beforeMount、 mounted、 beforeUpdate、 updated、 activated、 deactivated、 beforeDestroy、 destroyed、errorCaptured
4)资源: directives、 filters、 components
5)组合: parent, mixins、 extends、 provide、 inject

二、注册组件

01.全局注册(Vue.component)

全局注册:可以在全局任意地方访问

<body>
    <div id="app"></div>
    <script>
        //注册组件
        //1.全局---->可以在全局任意地方访问
        const Foo = {
            template: `<div>foo</div>`
        }
        //第一个字段:标记当前要注册的组件的名称
        //第二个字段:放置一个视图,可以先提前声明
        Vue.component("Foo", Foo); //全局注册

        const app = new Vue({
            el: "#app",
            data: {
                msg: "你好"
            },
            template: `
        <div>root app
            <Foo></Foo>  // <div>foo</div>
        </div>
       `
       })
    </script>
</body>

02.局部注册(components)

存在作用域问题
const Bar = {
    template: `<div>Bar</div>`
}

const Foo = {
    //局部注册:Bar只能在 Foo 内部访问
    components: {
       Bar,  //Bar为简写形式,或者"Bar":Bar (key:value形式)
    },
    template: `<div>foo
                <Bar></Bar>
               </div>
              `
 }

!!!注意事项
1)data(){ }
通过一个函数返回一个对象,确保组件之间相互独立
因为如果采用Object(data:{count:1}),则相当于创建的时候采用同一个对象,当在某一个组件更改则其余的也会受到影响

const Foo = {
            //局部注册:Bar只能在 Foo 内部访问
            components: {
                Bar,
            },
            //如果在组件内给一个data,这里data必须是一个函数
            data() {
                return {
                    count: 1,
                };
            },

            template: `<div>foo
                 {{count}}
                <Bar></Bar>
                </div>`
        }

2)只能有一个 root 根节点

const Foo = {
           ......
           //template必须用一个<div></div>包裹,但是在vue3,此语法不再强制
           template: `<div>foo
                   {{count}}
                   <Bar></Bar>
                 </div>
                `
        }

三、Vue的生命周期

  1. 快捷插件(Vue VsCode Snippets):可以根据几个字母,自动的创建代码
  2. 生命周期:创建->挂载->更新->销毁
const Foo = {
            data() {
                return {
                    count: 1,
                };
            },
            //==========创建==========
            beforeCreate() {
                console.log("before-create");
            },
            created(){
                //page -> fetch -> data
                //在create中拉取数据较好,因为此时视图还未渲染
                console.log("created");
            },
            //==========挂载==========
            beforeMount(){
                console.log("before-mounted");
            },
            mounted(){
                //整个视图创建完成
                console.log("mounted");
            },
            //==========更新==========
            beforeUpdated(){
                console.log("before-update");
            },
            updated(){
                console.log("updated");
            },
            //==========销毁==========
            beforeDestroy(){
                console.log("beofre-destroy");
            },
            Destroy(){
                cosnole.log("destroy");
            },
            
            template: `<div>foo
                </div>`
        }

在这里插入图片描述
3. 多个组件调用的顺序

//子组件
const Bar = {
            data() {
                return {
                };
            },
            //创建
            beforeCreate() {
                console.log("bar-before-create");
            },
            created() {
                console.log("bar-created");
            },
            //挂载
            beforeMount() {
                console.log("bar-before-mounted");
            },
            mounted() {
                //整个视图创建完成
                console.log("bar-mounted");
            },
            //更新
            beforeUpdated() {
                console.log("bar-before-update");
            },
            updated() {
                console.log("bar-updated");
            },
            //销毁
            beforeDestroy() {
                console.log("bar-beofre-destroy");
            },
            Destroy() {
                cosnole.log("bar-destroy");
            },

            template: `<div>foo
                {{count}}
                <button @click="count++">click</button>
                </div>`
        }
        //父组件
        const Foo = {
            component: {
                Bar,
            },
            data() {
                return {
                    count: 1,
                };
            },
            //创建
            beforeCreate() {
                console.log("before-create");
            },
            created() {
            	//请求后端的数据
                console.log("created");
            },
            //挂载
            beforeMount() {
                console.log("before-mounted");
            },
            mounted() {
         		//所有的子组件已经创建完成
                //整个视图创建完成
                //此过程常用于事件的监听等
                console.log("mounted");
            },
            //更新
            beforeUpdated() {
                console.log("before-update");
            },
            updated() {
                console.log("updated");
            },
            //销毁
            beforeDestroy() {
                console.log("beofre-destroy");
            },
            Destroy() {
                cosnole.log("destroy");
            },

            template: `<div>foo
                {{count}}
                <Bar></Bar>
                <button @click="count++">click</button>
                </div>`
        }
### before-create --->  create ---> before-mount ---> bar-before-create --->bar-create --->bar-before-mount ---> bar-mount ---> mount
### 先创建父组件,在父组件挂载之前,完成子组件的初始化(创建+挂载),最后再加载父组件

四、props(声明一个组件可以接收到的参数)

const Foo = {
            //声明一个组件可以接收到的参数
            // props:["msg"]; 
            //当有多个属性需要设置时,采用对象形式
            //props:只读,不可写
            props: {
                //声明的msg也是一个响应式数据
                msg: {
                    type: String,
                    defalut: "msgmsgmsg", //给定默认值
                    //自定义校验器,验证val 是否符合校验规则
                    validator(val) {
                        console.log(val);
                        return val === 'abc';
                    }
                },
            },
            data() {
                return {
                    count: 1,
                };
            },

            template: `<div>foo
                {{msg}}
                </div>`
        }

        Vue.component("Foo", Foo);

        const app = new Vue({
            el: "#app",
            data: {
                msg: "你好"
            },
            //父组件和子组件之间的通信方式
            template: `
                   <div>root app
                      //父组件传递给子组件
                      <Foo msg="abc"></Foo> //在validator中验证值
                   </div>
            `
        })

五、自定义事件

01.this.$emit

const Foo = {
            data() {
                return {
                    count: 1,
                };
            },
            methods: {
                handleClick() {
                    console.log("click");
                    //让 父级 接收到 子级传递来的消息
                    //子组件向父组件传值:this.$emit("function",param)
                    //第一个参数是函数的名字,param:需要传递的参数,可为多个
                    this.$emit("heihei", "a", "b");
                }
            },
            template: `<div>foo
                <button @click="handleClick">点击</button>
                </div>`
        }

        Vue.component("Foo", Foo);

        const app = new Vue({
            el: "#app",
            data: {
                msg: "你好"
            },
            methods: {
            //val secondVal 对应 emit 传递来的参数
                handleHeiHei(val, secondVal) {
                    console.log(val);
                    console.log(secondVal);
                    console.log("heihei in parent component");
                }
            },
            template: `
                   <div>root app
                    在父组件中 子组件引用处添加函数:v-on:function="function1"; 
                    //其中 function为子组件中定义函数 ( heihei事件名就是emit 发出的事件名称 ) ,function1为父组件定义函数--用于接收子组件传值并进行相应数据处理,可定义为同一名称
                    <Foo @heihei="handleHeiHei"></Foo>
                   </div>
            `
        })

02.v-model

写法一:

const Foo = {
            //props 必须为["value"]
            props: ["value"],
            data() {
                return {
                    count: 1,
                };
            },
            methods: {
                handleClose() {
                    //2.emit 为 input
                    this.$emit("input",false);
                }
            },
            template: `<div v-if="value">foo
                <button @click="handleClose">关闭</button>
                </div>`
        }

        Vue.component("Foo", Foo);

        const app = new Vue({
            el: "#app",
            data: {
                msg: "你好",
                showFoo: true
            },
            methods: {
                handleClose(val) {
                    this.showFoo = val;
                }
            },
            template: `
                   <div>root app
                    //3.$emit处采用input , 此处采用v-model
                    <Foo v-model="showFoo"></Foo>
                   </div>
            `
        })

六、插槽

将内容渲染进组件内,实现组件的通信

  1. 插槽简单实现
const Foo = {
            data() {
                return {
                    count: 1,
                };
            },
            template: `<div>
                <div>
                    默认slot
                   <slot></slot>   //如果没加name,默认default
                </div>
                <div>
                    first
                   <slot name="first"></slot> //通过name指定slot
                </div>
                <div>
                    second
                    <slot name="second"></slot>
                </div>
                
                </div>`
        }

        Vue.component("Foo", Foo);

        const app = new Vue({
            el: "#app",
            data: {
                msg: "你好"
            },
            //Foo 如果什么都不写,采用默认slot中的内容,如果Foo中内容更改,则变成更改后的内容
            // v-slot:first 缩写 #first
            //通过v-slot将指定内容插入指定的slot内
            template: `
                   <div>root app
                      <Foo>
                        012
                        <template v-slot:first>
                            345
                        </template>
                        <template #second>
                            678
                        </template>
                      </Foo>  
                   </div>
            `
        })
  1. 插槽传递数据
const Foo = {
            data() {
                return {
                    count: 1,
                    title: "FooFooFoo"
                };
            },
            template: `<div>
                        <slot name="first" :title="title" age="13"></slot>
                    </div> `
        }

        Vue.component("Foo", Foo);

        const app = new Vue({
            el: "#app",
            data: {
                msg: "你好"
            },

            template: `
                   <div>root app
                      <Foo>
                        <template #first="data">
                            {{data}}  //结果:{ "title": "FooFooFoo", "age": "13" }
                        </template>
                        
                        <template #first="{age}"> //想得到谁,则结构成对象的形式
                            {{age}}  
                        </template>
                        
                      </Foo>  
                   </div>
            `
        })

七、组件的复用性

01.mixin(公用的方式用mixin抽离)

//mixin 将公共的部分抽离封装,写法和组件类似,options中相同的部分会合并
        //鼠标移动的逻辑 x y 
        const MousemoveMixin = {
            data() {
                return {
                    x: 0,
                    y: 0
                }
            },
            methods: {
                handleMousemove(e) {
                    this.x = e.pageX;
                    this.y = e.pageY;
                }
            },
            mounted() {
                window.addEventListener("mousemove", this.handleMousemove);
            },
            destroyed() {
                window.removeEventListener("mousemove", this.handleMousemove);
            },
        }

        const Foo = {
            mixins: [MousemoveMixin],
            data() {
                return {
                    count: 1
                };
            },


            template: `<div>foo
                {{x}}---{{y}}
                </div>`
        }

        Vue.component("Foo", Foo);

        const app = new Vue({
            el: "#app",
            data: {
                msg: "你好"
            },
            template: `
                   <div>root app
                      <Foo></Foo>  
                   </div>
            `
        })

!!!注意:mixin 缺点----->vue3中能解决
1)来源不清晰
2)命名冲突问题

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值