美文网首页
Vue-自定义组件3

Vue-自定义组件3

作者: 云瑶糖糖 | 来源:发表于2021-12-06 14:56 被阅读0次

    好看的网页千篇一律,有趣的代码万里挑一。

    一到秋天,南京就美成了金陵。

    现在已经初冬了,南京街头还是深秋景象。

    这种配色,看起来极度舒适。

    为平淡的生活,混入一丝仙气。

    四季的轮转,给熟悉的街景添加了不同的滤镜。

    换个角度,完全是全新的视觉盛宴。

    知识的更迭,让思维产生质变。

    欣赏完美景,回归到工作。

    保持学习的热情,温故而知新。

    今天继续Vue自定义组件知识。


    1. 深入理解v-model

    // 定义一个数据加减的组件

    Vue.component('b-counter', {

    template: `

    <div class="counter">

        <button @click="jian" :disabled="myCount===minCount">-</button>

        <input type="text" :value="myCount" readonly>

        <button @click="jia" :disabled="myCount===maxCount">+</button>

    </div>

    `,

    props: {

    // 数量

    value: {

    // 类型

    type: Number,

    // 非空

    required: true,

    },

    // 最小值

    minCount: {

    type: Number,

    // 默认值

    default: 1

    },

    // 最大值

    maxCount: {

    type: Number,

    default: 10

    }

    },

    // 定义组件的数据

    data() {

    return {

    // 从props里面将value的值给myCount复制一份

    myCount: this.value

    }

    },

    // 定义组件的方法

    methods: {

    //数量减方法

    jian() {

    this.myCount--

    },

    // 数量加方法

    jia() {

    this.myCount++

    }

    },

    // 侦听器

    watch: {

    // 侦听myCount是否发生变化

    myCount() {

    // 触发自定义事件,注意:事件名称中不能采用大写字母

    this.$emit('input', this.myCount)

    }

    }

    })

    new Vue({

    el: "#app",

    data() {

    return {

    name: '张三',

    // 衣服的数量

    yfcount:2

    }

    },

    methods: {

    },

    })

    2. .sync修饰符

    <div id="app">

        <div>

            <h4>衣服数量:{{yfcount}}</h4>

            <h4>裤子数量:{{kzcount}}</h4>

            <h4>鞋子数量:{{xzcount}}</h4>

            <!-- <b-box :yfcount="yfcount" :kzcount="kzcount" :xzcount="xzcount"

            @update:yfcount="yfcount=$event" @update:kzcount="kzcount=$event"

            @update:xzcount="xzcount=$event"></b-box> -->

            <hr>

            <!-- 如果触发的事件名称是update:属性名,那么就可以使用..sync修饰符简化调用的过程。 -->

            <!-- 总结:如果组件只回传一份数据,用v-model。如果组件回传多份数据,用.sync修饰符。 -->

            <b-box :yfcount.sync="yfcount" :kzcount.sync="kzcount" :xzcount.sync="xzcount"></b-box>

        </div>

    </div>

    // 定义一个数据加减的组件

    Vue.component('b-counter', {

    template: `

    <div class="counter">

        <button @click="jian" :disabled="myCount===minCount">-</button>

        <input type="text" :value="myCount" readonly>

        <button @click="jia" :disabled="myCount===maxCount">+</button>

    </div>

    `,

    props: {

    // 数量

    value: {

    // 类型

    type: Number,

    // 非空

    required: true,

    },

    // 最小值

    minCount: {

    type: Number,

    // 默认值

    default: 1

    },

    // 最大值

    maxCount: {

    type: Number,

    default: 10

    }

    },

    // 定义组件的数据

    data() {

    return {

    // 从props里面将value的值给myCount复制一份

    myCount: this.value

    }

    },

    // 定义组件的方法

    methods: {

    //数量减方法

    jian() {

    this.myCount--

    },

    // 数量加方法

    jia() {

    this.myCount++

    }

    },

    // 侦听器

    watch: {

    // 侦听myCount是否发生变化

    myCount() {

    // 触发自定义事件,注意:事件名称中不能采用大写字母

    this.$emit('input', this.myCount)

    }

    }

    })

    // 定义一个b-box组件

    Vue.component('b-box', {

    // 模板中必须包含一个根标签

    template:`

    <div>

        <div>衣服:<b-counter v-model="myyfcount"></b-counter>

        </div>

        <div>裤子:<b-counter v-model="mykzcount"></b-counter>

        </div>

        <div>鞋子:<b-counter v-model="myxzcount"></b-counter>

        </div>

    </div>

    `,

    props:['yfcount','kzcount','xzcount'],

    data() {

    return {

    // 将props传进来的数据,在data中备份一下,从此以后操作data中的数据

    myyfcount:this.yfcount,

    mykzcount:this.kzcount,

    myxzcount:this.xzcount

    }

    },

    watch:{

    myyfcount(){

    // 注意:这里触发事件的名称是:update:属性名;

    // 如果满足该规则,那么在触发事件时,就可以使用sync修饰符简化调用的过程。

    this.$emit('update:yfcount',this.myyfcount)

    },

    mykzcount(){

    this.$emit('update:kzcount',this.mykzcount)

    },

    myxzcount(){

    this.$emit('update:xzcount',this.myxzcount)

    }

    }

    })

    new Vue({

    el: "#app",

    data() {

    return {

    // 衣服的数量

    yfcount:2,

    // 裤子的数量

    kzcount:3,

    // 鞋子的数量

    xzcount:5

    }

    },

    methods: {

    },

    })


    3. 具名插槽

    <div id="app">

        <b-box>

            <!-- template标签指定它里面的内容在哪一个具体的插槽中呈现 -->

            <template v-slot:header>

                <h4>好好学习</h4>

                <h4>天天向上</h4>

            </template>

            <template v-slot:default>

                <img src="https://img0.baidu.com/it/u=2293835918,4228668324&fm=253&fmt=auto&app=120&f=JPEG?w=556&h=500">

                <img

                    src="https://ss0.baidu.com/-Po3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=e25abb7779061d95624631384bf50a5d/5ab5c9ea15ce36d39e62417f2df33a87e950b11f.jpg">

            </template>

            <!-- v-slot:的简写是# -->

            <template #footer>

                <a href="http://www.baidu.com">百度</a>

                <a href="http://www.taobao.com">淘宝</a>

            </template>

        </b-box>

    </div>

    // 在组件内部通过slot标签定义插槽,在通过name属性给插槽定义名字,这样的插槽称之为:具名插槽。// 插槽的默认名称是:default。如果有多个插槽,允许其中一个插槽不定义名称。Vue.component('b-box',{template:` <div class="box">

        <h2>我是组件</h2>

        <div class="header">

        <slot name="header"></slot>

        </div>

        <div class="main">

        <slot></slot>

        </div>

        <div class="footer">

        <slot name="footer"></slot>   

        </div>

        </div>

        `})newVue({el:'#app',})


    4. 作用域插槽

    <div id="app">

        <b-box>

            <!-- 注意:一定要用使用具名插槽的方式去接收作用域插槽传递回来的数据,

            通常我们会定义scope变量,就收传回来的数据。 -->

            <template v-slot:edit="scope">

                <button @click="scope.item.name='苹果'">修改</button>

                <button @click="scope.list.splice(scope.index,1)">删除</button>

            </template>

        </b-box>

    </div>

    Vue.component('b-box', {

        // 可以在slot标签上绑定属性,这样外面在使用该插槽时,就可以获取到上面绑定的数据。

        // 这样的插槽,我们称之为:作用域插槽

        template:`

        <div class="box">

        <ul>

        <li v-for="(item,index) in list" :key="index">

        {{item.id}}--{{item.name}}

        <slot name="edit" v-bind:item="item" v-bind:list="list" v-bind:index="index"></slot>

        </li>

        </ul>

        </div>

        `,

        data() {

            return {

                list:[

                    {

                        id:1001,

                        name:'薯片'

                    },

                    {

                        id:1002,

                        name:'饼干'

                    },

                    {

                        id:1003,

                        name:'面包'

                    },

                    {

                        id:1004,

                        name:'糖果'

                    },

                ]

            }

        },

    })

    new Vue({

        el:'#app',

    })

    5. 混入

    突然想到了炒鸡蛋,😄,鸡蛋打散混入葱花,搅拌均匀。

    哈哈,代码中也可以混入,密钥是mixin

    <div id="app1">

        <h2>app1</h2>

        <h4>姓名:{{name}},年龄:{{age}},工资:{{money}}</h4>

        <button @click="sayHi">sayHi</button>

        <button @click="updateMoney">修改工资</button>

        <b-box></b-box>

    </div>

    <hr>

    <div id="app2">

        <h2>app2</h2>

        <h4>姓名:{{name}},年龄:{{age}},工资:{{money}}</h4>

        <button @click="sayHi">sayHi</button>

        <button @click="updateMoney">修改工资</button>

        <b-box></b-box>

    </div>

    // 全局混入 -- 注意:必须要先执行

    Vue.mixin({

        // mixin()方法的参数是配置对象,Vue实例可以配置的东西,它都可以配置。

        // 比如:数据,方法,生命周期钩子函数,计算属性,侦听器,过滤器,等等...

        data() {

            return {

                name:'张三',

                age:20,

                money:10000,

            }

        },

        methods: {

            sayHi(){

                alert('大家好!')

            },

            // 更新工资的方法

            updateMoney(){

                this.money+=1000

            }

        },

        mounted() {

            console.log('mixin里面定义的生命周期钩子函数----我已经挂载完毕....');

        },

        computed:{

            usMoney(){

                return '$'+(this.money/6).toFixed(2)

            }

        },

    })

    // 在全局混入的内容,之后创建的所有Vue实例包括组件实例都将拥有。

    // 在创建Vue实例时,会将mixin里面的成员跟Vue实例自身的成员进行合并,如果冲突了,最终采用Vue实例身上的成员。

    // 特别注意:生命周期钩子不是合并,是叠加执行,是先执行mixin里面的生命周期钩子,再执行Vue实例里面的生命周期钩子。

    // 定义组件

    Vue.component('b-box', {

        template:`

        <div class="box">

        <h4>姓名:{{name}},年龄:{{age}},工资:{{money}},美元工资:{{usMoney}}</h4>

        <button @click="sayHi">sayHi</button>

        <button @click="updateMoney">修改工资</button>

        </div>

        `,

        methods: {

            updateMoney(){

                this.money+=10000

            }

        },

        mounted() {

            console.log('组件自己定义的生命周期钩子函数----我已经挂载完毕....');

        },

    })

    // 创建第一个Vue的实例--操作的容器是#app1

    new Vue({

        el:'#app1',

    })

    // 创建第二个Vue的实例--操作的容器是#app2

    new Vue({

        el:'#app2',

    })

    6. 混入ajax的基本操作

    <div id="app1">{{students}}</div>

    <hr>

    <div id="app2">{{subjects}}

        <hr>

        <p>课程名称:<input type="text" v-model="subject.subjectName"></p>

        <p>课程年级:<input type="text" v-model="subject.gradeId"></p>

        <p>课程课时:<input type="text" v-model="subject.classHour"></p>

        <p><button @click="add">添加</button></p>

    </div>

    // 将ajax请求相关的操作,通过mixin混入给Vue

    Vue.mixin({

        data() {

            return {

                // 接口根路径

                base_url:'http://www.bingjs.com:81'

            }

        },

        methods: {

            // get方法

            async $get(url,params){

                let {data} = await axios.get(this.base_url+url,{params})

              return data

            },

            // post方法

            async $post(url,params){

                let {data} = await axios.post(this.base_url+url,params)

                return data

            }

        },

    })

    new Vue({

        el:'#app1',

        data() {

            return {

                // 学生信息

                students:[]

            }

        },

        created() {

            this.getStudents()

        },

        methods: {

            async getStudents(){

                let students = await this.$get('/Student/GetAll')

                this.students = students.map(s=>s.StudentName)

            }

        },

    })

    new Vue({

        el:'#app2',

        data() {

            return {

                // 课程信息

                subjects:[],

                subject:{

                    subjectName:'',

                    classHour:'',

                    gradeId:''

                }

            }

        },

        created() {

            this.getSubjects()

        },

        methods: {

            async getSubjects(){

                let subjects = await this.$get('/Subject/GetAll')

                this.subjects = subjects.map(s=>s.SubjectName)

            },

            async add(){

                let r = await this.$post('/Subject/Add',this.subject)

                if(r){

                    alert('添加成功!')

                }

            }

        },

    })

    是不是越来越有趣了,试试看敲出来的效果吧。

    相关文章

      网友评论

          本文标题:Vue-自定义组件3

          本文链接:https://www.haomeiwen.com/subject/gnggxrtx.html