Упражнение по разработке плагина Vue — практическое всплывающее окно

JavaScript Vue.js

1. Введение

В прошлый раз я сказал компоненты (Упражнение по разработке компонентов Vue — переключение карт фокуса) проекта упражнений, на этот раз я изменил вкус и рассказал о проекте практики плагинов Vue. По сравнению с предыдущими компонентами переключения карты фокуса, это может быть проще, в принципе, достаточно быть знакомым с шагами разработки плагина! Для этого проекта я рекомендую вам попрактиковаться на практике.Это всплывающее окно более практично и чаще используется, чем предыдущая карта фокуса. В то же время он также может ознакомить всех с процессом разработки плагинов для Vue. Код тот же, выложу на гитхаб(ec-dialog), вы можете перейти непосредственно к коду, если он вам нужен!

предложение
1. Для следующих шагов лучше запускать их локально, и выполнять их шаг за шагом в соответствии с шагами статьи.Если вы только посмотрите на код, то легко запутаться.
2. Если вы не знаете, какой код что делает, вы можете отладить его самостоятельно, удалить код и посмотреть, какой эффект он дает, и легко понять, что делает код!

2. Каталог проекта

Это все еще очень простой каталог. Я не знаю, для чего каждый каталог. Вы можете перейти, чтобы увидеть мою последнюю статью. По сравнению с каталогом разработки компонентов разница в том, чтоsrc/js/componentsв этой папке.

3. Процесс разработки

3-1. Запустите проект

Во-первых, получитьsrc/js/components/alertэтот компонент. все равно сначалаsrc/js/components/alert/src/main.vue. Вывод «ожидание». код показывает, как показано ниже

<template>
    <transition name="ec">
        <div class="ec">
            守候
        </div>
    </transition>
</template>
<script>
    export default {
        data () {
            return {
                name: 'ec-alert',
            }
        },
        computed: {},
        mounted () {
        },
        methods: {
        }
    }
</script>

потом пришел'alert/index.js'. Какой файл называется этим термином, я не уверен, пока просто назовите его файлом конфигурации плагина! Код выглядит следующим образом (обратите внимание на комментарии)

import Vue from 'vue'
import AlertComponent from './src/main.vue'
//合并对象函数,这个方法是会改变,第一个参数的值的
function merge(target) {
    for (let i = 1, j = arguments.length; i < j; i++) {
        let source = arguments[i] || {};
        for (let prop in source) {
            if (source.hasOwnProperty(prop)) {
                let value = source[prop];
                if (value !== undefined) {
                    target[prop] = value;
                }
            }
        }
    }
    return target;
};
let instance;
//extend 是构造一个组件的语法器.传入参数,返回一个组件
let AlertConstructor = Vue.extend(AlertComponent);

let initInstance = ()=>{
    //实例化ConfirmConstructor组件
    instance = new AlertConstructor({
        el: document.createElement('div')
    });
    //添加到boby
    document.body.appendChild(instance.$el);
}

let Alert = (options={}) => {
    //初始化
    initInstance();
    // 将单个 confirm instance 的配置合并到默认值(instance.$data,就是main.vue里面的data)中
    merge(instance.$data, options);
    //返回Promise
    return new Promise((resolve, reject)=>{
        instance.show = true;
        let success = instance.success;
        let cancel = instance.cancel;
        instance.success = () => {
            //先执行instance.success(main.vue里面的success函数)
            success();
            //再执行自定义函数
            resolve('ok');
        }
    });

}
export default Alert;

потом пришелcomponents/js/index.jsЭтот файл, компоненты конфигурации и API, код выглядит следующим образом

import alert from './alert/index.js'

const install = function(Vue) {
    //注册全局组件
    Vue.component(alert.name, alert)
    //添加全局API
    Vue.prototype.$alert = alert
}
export default install

Затем в файле шаблонаindex.htmlУстановите div внутри, чтобы облегчить тест монтирования

<!DOCTYPE html>
<html lang="en">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
</div>
</body>
</html>  

Затем в файле вводаindex.jsВнутри используйте плагин

require("./index.html");
//引入sass
require("./src/sass/com.scss");
import Vue from 'vue'
import dialog from './src/js/components/index';
Vue.use(dialog)
let App = new Vue({
    el: '#app',
    data(){
        return {
            'name': 'index'
        }
    },
    mounted(){
        this.$alert();
    }
});

Затем командная строка$ npm run dev, результат отличный

3-2 Модификация стиля

После завершения предыдущего шага более половины этого плагина завершено! Остальные работы в основном развиваются вcomponents/../main.vueЭтот документ разработан.
Во-первых, не спешите писать код, подумайте, какие поля наверняка нужны всплывающему окну.

Ссылаясь на вышеизложенное, обнаружено, что есть заголовок, содержание и текст кнопки. Наконец, переменная необходима для управления отображением всплывающего окна. Затем функция действия, которая нажимает кнопку. Затем стили, вероятно, следующие

О стиле много говорить не буду, другие поля, просто заполните одну редьку и одну косточку, код выглядит следующим образом

<template>
    <transition name="ec">
        <div v-if="show" class="ec">
            <div class="ec-box">
                <div class="ec-box-inner">
                    <!--标题-->
                    <div class="ec-title" v-if="title">{{title}}</div>
                    <!--内容-->
                    <div class="ec-content">{{content}}</div>
                </div>
                <!--按钮-->       
                <div class="ec-box-buttons">
                    <span class="ec-btn-success" @click="success">{{submitText}}</span>
                </div>
            </div>
        </div>
    </transition>
</template>
<script>
    export default {
        data () {
            return {
                name:'ec-alert',
                show: false,
                title: '提示',
                content: '',
                submitText: '确定',
                cancelText: '取消'
            }
        },
        computed: {},
        mounted () {
        },
        methods: {
            //按钮事件
            success () {
                this.show = false;
            }
        }
    }
</script>
<style lang="scss" scoped>

    .ec {
        background: rgba(00, 00, 00, .5);
        position: fixed;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        .ec-box {
            width: 80%;
            max-width: 400px;
            top: 200px;
            position: absolute;
            left: 0;
            right: 0;
            margin: auto;
            background: #fff;
            box-sizing: border-box;
            padding: 20px;
            border-radius: 6px;

        }
        .ec-title {
            padding-left: 0;
            margin-bottom: 0;
            font-size: 16px;
            font-weight: 700;
            height: 18px;
            color: #333;
        }
        .ec-content {
            padding: 14px 0;
            line-height: 24px;
            color: #48576a;
            font-size: 14px;
        }
        .ec-box-buttons {
            text-align: right;
        }
        .ec-btn-success {
            background: #20a0ff;
            border-color: #20a0ff;
            display: inline-block;
            line-height: 1;
            white-space: nowrap;
            cursor: pointer;
            color: #fff;
            margin: 0;
            padding: 10px 15px;
            border-radius: 4px;
        }
        .ec-btn-cancel {
            display: inline-block;
            line-height: 1;
            white-space: nowrap;
            cursor: pointer;
            background: #fff;
            border: 1px solid #c4c4c4;
            color: #1f2d3d;
            margin: 0;
            padding: 10px 15px;
            border-radius: 4px;
        }
    }
    .ec-enter {
        opacity: 0;
        .ec-box {
            transform:scale(0);
        }
    }

    .ec-enter-active {
        transition: opacity .4s;
        .ec-box {
            transition: transform .4s;
        }
    }
    .ec-leave-active{
        transition: opacity .2s;
        .ec-box {
            transition: transform .2s;
        }
    }
    .ec-leave-active {
        opacity: 0;
    }
</style>

текущий результат

3-3 Использование плагинов

Как мы все знаем, на предыдущих шагах'alert/index.js'Вот вернулось обещание. Таким образом, использование используется как обещание!


Итак, в файле вводаindex.jsпиши прямо внутри

mounted(){
    this.$alert({
        title:'提示2',
        content:'这里是提示内容2'
    }).then(()=>{
        this.name='守候'
        alert(this.name)
    })
}

текущий результат

4. Другие всплывающие окна

Опять же, программистов статус-кво не устроит, всплывающее окно только одно, как его может хватить, ниже добавлю еще одно, которое в принципе такое же, как и выше, за исключением того, что есть дополнительная кнопка отмены.
Здесь я расскажу о простом каштане.Что касается стиля всплывающего окна, то его слишком много, я не буду его здесь расширять, вы можете расширить то, что вам нужно.

Сначала создайте этот каталог (вы можете напрямую скопировать каталог предупреждений, а затем изменить его несколько раз, и все готово)

Тогда дляcomfirm/src/main.vueфайл, добавьте следующий код (следующий код в основном изalert/src/main.vueКопия состоит в том, чтобы добавить поле и функцию операции, соответствующую кнопке отмены)

<template>
    <transition name="ec">
        <div v-if="show" class="ec">
            <div class="ec-box">
                <div class="ec-box-inner">
                    <!--标题-->
                    <div class="ec-title" v-if="title">{{title}}</div>
                    <!--内容-->
                    <div class="ec-content">{{content}}</div>
                </div>
                <!--按钮-->
                <div class="ec-box-buttons">
                    <span class="ec-btn-success" @click="success">{{submitText}}</span>
                    <span class="ec-btn-cancel" @click="cancel">{{cancelText}}</span>
                </div>
            </div>
        </div>
    </transition>
</template>
<script>
    export default {
        data () {
            return {
                name:'ec-comfirm',
                show: false,
                title: '提示',
                content: '',
                submitText: '确定',
                cancelText: '取消'
            }
        },
        computed: {},
        mounted () {
        },
        methods: {
            //确定按钮事件
            success () {
                this.show = false;
            },
            //取消按钮事件
            cancel () {
                this.show = false;
            }
        }
    }
</script>
<style lang="scss" scoped>
    .ec {
        background: rgba(00, 00, 00, .5);
        position: fixed;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        z-index: 9999;
        .ec-box {
            width: 80%;
            max-width: 400px;
            top: 200px;
            position: absolute;
            left: 0;
            right: 0;
            margin: auto;
            background: #fff;
            box-sizing: border-box;
            padding: 20px;
            border-radius: 6px;

        }
        .ec-title {
            padding-left: 0;
            margin-bottom: 0;
            font-size: 16px;
            font-weight: 700;
            height: 18px;
            color: #333;
        }
        .ec-content {
            padding: 14px 0;
            line-height: 24px;
            color: #48576a;
            font-size: 14px;
        }
        .ec-box-buttons {
            text-align: right;
        }
        .ec-btn-success {
            background: #20a0ff;
            border-color: #20a0ff;
            display: inline-block;
            line-height: 1;
            white-space: nowrap;
            cursor: pointer;
            color: #fff;
            margin: 0;
            padding: 10px 15px;
            border-radius: 4px;
        }
        .ec-btn-cancel {
            display: inline-block;
            line-height: 1;
            white-space: nowrap;
            cursor: pointer;
            background: #fff;
            border: 1px solid #c4c4c4;
            color: #1f2d3d;
            margin: 0;
            padding: 10px 15px;
            border-radius: 4px;
        }
    }
    .ec-enter {
        opacity: 0;
        .ec-box {
            transform:scale(0);
        }
    }

    .ec-enter-active {
        transition: opacity .4s;
        .ec-box {
            transition: transform .4s;
        }
    }
    .ec-leave-active{
        transition: opacity .2s;
        .ec-box {
            transition: transform .2s;
        }
    }
    .ec-leave-active {
        opacity: 0;
    }
</style>

Тогда естьcomfirm/index.js(Это тоже базовая копия. Я сделаю скриншот и скажу, где это изменить. Вы должны внимательно посмотреть, чтобы знать, где это изменить)

потомcomponents/index.js

import comfirm from './comfirm/index.js'
import alert from './alert/index.js'

const install = function(Vue) {
    //注册全局组件
    Vue.component(comfirm.name, comfirm)
    Vue.component(alert.name, alert)
    //添加全局API
    Vue.prototype.$confirm = comfirm
    Vue.prototype.$alert = alert
}
export default install

Наконец, в файле вводаindex.jsиспользовать

require("./index.html");
//引入sass
require("./src/sass/com.scss");
import Vue from 'vue'
import dialog from './src/js/components/index';
//使用弹窗插件
Vue.use(dialog)
let App = new Vue({
    el: '#app',
    data(){
        return {
            'name': 'index'
        }
    },
    mounted(){
        //触发confirm弹窗
        this.$confirm({
            title:'提示',
            content:'这里是提示内容',
            submitText:'提交',
            cancelText:'返回'
        }).then(()=>{
            //触发alert弹窗
            this.$alert({
                title:'提示2',
                content:'这里是提示内容2'
            }).then(()=>{
                this.name='守候'
                alert(this.name)
            })
        }).catch((err)=>{
            alert(err)
        })
    }
}); 

Результат операции таков

5. Резюме

Простое всплывающее окно здесь, очень простое, но его все еще можно использовать в моей разработке и можно временно удовлетворить. Но это обязательно нужно поддерживать, ведь во многих проектах требуются всплывающие окна. Каждый может также расширяться в соответствии со своими потребностями! Приведенный выше случай также очень прост и понятен. В основном это процесс. Но я настоятельно рекомендую вам прочитать статью, пока вы это делаете. Это позволит вам попрактиковаться в разработке плагинов на основе Vue. Это хорошее упражнение. Надеюсь, оно поможет вам освоить новые знания! Наконец, если вы считаете, что статья написана неправильно или неправильно, укажите на это!



------------------------- Великолепная разделительная линия --------------------
Хотите узнать больше, обратите внимание на мой публичный аккаунт WeChat: В ожидании книжного магазина