Свойство — было доступно во время визуализации, но не определено в экземпляре

#javascript #html #vue.js #vuejs3

Вопрос:

Я пытаюсь создать страницу «Свяжитесь с нами» с помощью v-модели, однако мой код, похоже, не хочет работать и продолжает выводить ошибки тезисов:

  • Свойство «inputted_name» было доступно во время визуализации, но не определено в экземпляре
  • Свойство «inputted_email» было доступно во время визуализации, но не определено в экземпляре
  • Свойство «параметры» было доступно во время визуализации, но не определено в экземпляре
  • Свойство «выбрано» было доступно во время визуализации, но не определено в экземпляре
 //############--contact.js--############

//--------------- PAGE TITLE ---------------
// Vue object: Title
const PageTitle = {
    data() {
        return {
            title: 'Contact Us'
        }
    }
}

Vue.createApp(PageTitle).mount('#page-title')

//--------------- NAVIGATION (Cart) ---------------
// Vue object: Title
const CartTitle = {
    data() {
        return {
            cart_title: 'Cart'
        }
    }
}

Vue.createApp(CartTitle).mount('#cart-title')

//--------------- NAVIGATION (Main pages) ---------------
// Vue object: Titles
const MainNav = {
    data() {
        return {
            home: 'Home',
            for_hire: 'For Hire',
            about: 'About',
            contact_us: 'Contact Us',
            search: 'Search'
        }
    }
}

Vue.createApp(MainNav).mount('#nav-titles')

//--------------- FORM TITLES ---------------
// Vue object: Titles
const ContactTitles = {
    data() {
        return {
            main_title: 'Contact Us',
            name: 'Name',
            email_address: 'Email Address',
            select_option: 'What is your enquiry about?',
            checkboxes: 'Please click on each wrestling company you know:'
        }
    }
}

Vue.createApp(ContactTitles).mount('#contact-titles')


//--------------- FORM INPUTS ---------------
// Vue object: Inputs
const UserInputs = {
    data() {
        return {
            inputted_name: '',
            inputted_email: '',
            inputted_message: ''
        }   
    },

    methods: {
        checkInput: function () {
            if (this.inputted_name === '' || this.inputted_email === '' || this.inputted_message === '') 
            {
                alert("Please input in all the fields");
            }
        }
    }
}

Vue.createApp(UserInputs).mount('#contact-form-inputs')

// Vue instance: Select options
Vue.createApp({
    data() {
      return {
        selected: 'None',
        options: [
          { text: 'Booking enquiry', value: 'Booking' },
          { text: 'Website improvement', value: 'Website' },
          { text: 'Item enquiry', value: 'Item' },
          { text: 'Previous experiences', value: 'Experience' },
          { text: 'Career opportunity', value: 'Career' }
        ]
      }
    }
}).mount('#select-list') 
 /* Stylesheet for SIT120 Project - contact.html */
/*----------------------------------------------------*/

/*/////////////////////////-NO margins-//////////////////////////////*/
/* Expands to width of screen*/
body, html {
    margin: 0;
    padding: 0;
}

body {
    background-color: #AAAAAA;
}

/*/////////////////////////-Header Navigation-//////////////////////////////*/

/* Top navigation (cart) */
.cart_nav ul {
    list-style-type: none;
    margin: auto;
    overflow: hidden;
    background-color: #C6393F; 
}

.cart_nav li {
    float: right;
}

.cart_nav li a {
    font-family: Actor;
    font-size: 18px;
    font-style: normal;
    font-weight:normal;
    padding: 15px 55px 15px 20px;
    color: white;
    display: inline-block;
    text-decoration: none;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    transition: all 0.2s linear;
    -webkit-transition: all 0.2s linear;
    -moz-transition: all 0.2s linear;
    
}

.cart_nav li a:hover 
{
    color:#AAAAAA;
}

/*/////////////////////////-Cart Number-//////////////////////////////*/

/* Cart number (circled) */
.cart_items 
{
    font-family: Righteous;
    font-size: 16px;
    font-weight: bold;
    color: white;
    background-color:#2C2C2C;
    float: right; 
    margin-top: 16px;
    margin-right: 16px;
    margin-left: -33px;
    border-radius: 60%;
    width: 25px;
    height: 22px;
    text-align: center; 
}

/*/////////////////////////-Cart icons-//////////////////////////////*/

/* Top navigation ICONS (cart) */
.cart_icon
{
    display:inline-flex;
    width: 40px;
    height: 40px;
    margin-top: -20px;
    margin-bottom: -15px;
    margin-right: -17px;
    padding-left: 8px;
}

/*/////////////////////////-Main navigation-//////////////////////////////*/

/* Main navigation (pages) */
.page_nav ul
{
    list-style-type: none;
    margin: auto;
    overflow: hidden;
    background-color: #2C2C2C;
}

.page_nav li 
{
    float: left;
}

.page_nav li a {
    font-family: Bai Jamjuree;
    font-size: 22px;
    font-weight: bold;
    padding: 15px;
    line-height: 22px;
    color: #AAAAAA;
    display: inline-block;
    padding: 40px 60px 35px 30px;
    text-decoration: none;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    transition: all 0.2s linear;
    -webkit-transition: all 0.2s linear;
}

.page_nav li a:hover 
{
    color:#FFFFFF;
}

.page_nav li a.active
{
    text-decoration: overline;
    color:#FFFFFF;

}
.page_nav li a:focus
{
    text-decoration: overline;
    color:#FFFFFF;

}

/*/////////////////////////-Navigation icon (Search)-//////////////////////////////*/

/* Main navigation search ICON */
.search_icon
{
    display:inline-block;
    width: 35px;
    height: 37px;
    margin-top: -40px;
    margin-bottom: -15px;
    margin-right: -50px;
    padding-left: 13px;
    padding-right: 45px;
}

/*/////////////////////////-LOGO-//////////////////////////////*/

 /* Main logo (Wrestle Hire logo) */
.site_logo
{
    display: inline;
    float: left;
    width: 180px;
    height: 145px; 
    padding-right: 50px;
    margin-bottom: -20px;
    margin-left: -30px;
    margin-top: -10px;
}


.site_logo:hover
{
    cursor: pointer;
}

/*/////////////////////////-Form-//////////////////////////////*/
.form_container {
   background-color: #2C2C2C;
   margin-left: auto;
   margin-right: auto;
   width: 50em;
   padding: 45px;
   border: #C6393F 6px solid;
   border-radius: 4px;
   box-shadow: 20px 20px 20px grey;
}

.form_inputs 
{
    margin-left: 1.2em;
    margin-right: auto;
    width: 100%;
}

.input_container input {
    padding: 15px;
    border: none;
    width: 42em;
    
}

::placeholder {
    font-family: Abel;
    font-size: 18px;;
}

label {
    font-family: Bai Jamjuree;
    font-size: 18px;
    color: #AAAAAA;
    line-height: 2em;
}

input[type="text"]
{
    font-family: Bai Jamjuree;
    font-size: 18px;
    color: #2d2d2d;
    font-size: 1rem;
    background-color: white;
    border-radius: 4px;
} 
 <html>
    <head>
        <!--Stylesheets and responsiveness-->
        <link rel="stylesheet" type= "text/css" href="contact.css">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!--Link Vue Framework-->
        <script src="https://unpkg.com/vue@next"></script>

        <!-- Set responsiveness to screen size -->
        <meta name="viewport" content="width=device-width, initial-scale=1">    

        <!--Google fonts-->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Bai Jamjuree">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Righteous">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Abel">

        <!--Page Icon-->
        <link rel="icon" href="../Assets/page_icon.png">

        <!-- Page title-->
        <title id="page-title">{{title}}</title>
    </head>
    
    <body>
        <!--NAVIGATION-->
        <header>
            <!--Top navigation section (login, account and cart)-->
            <div class = "cart_nav" id = "cart-title">
                <ul>
                    <div class = "cart_items">0</div>
                    <li><a href="#cart">{{cart_title}}<img class = "cart_icon" src="../Assets/cart.png" alt="cart_icon"></a></li>
                </ul>
            </div>

              <!--Main navigation section (main pages)-->
            <div class = "page_nav" id = "nav-titles">
                <ul>
                    <!--All main pages will have .html files, this example has the contact as a separate file (and empty files)-->
                    <a href="../Home/home.html"><img href ="../Home/home.html" class = "site_logo" id = "siteLogo" src="../Assets/website_logo.png"/></a>
                    <li><a href="../Home/home.html">{{home}}</a></li>
                    <li><a href="">{{for_hire}}</a></li>
                    <li><a href="">{{about}}</a></li>
                    <li><a class = "active" href="contact.html">{{contact_us}}</a></li>
                    <li class = "search" style="float:right"><a>{{search}}<img class = "search_icon" src="../Assets/search.png" alt="search_icon"></a></li>
                </ul>
            </div>
        </header>

        <!--CONTACT FORM-->
        <h1>contact us</h1>

        <div class="form_container" id = "contact-titles">
            <div class = "form_inputs" id = "contact-form-inputs">
                    <!--Name input-->
                    <div class="input_container">
                        <label for="nameInput">{{name}}</label> <br>
                        <input id="nameInput" type="text" v-model="inputted_name" placeholder="Enter name">
                    </div>
                    <br>

                    <!--Email input-->
                    <div class="input_container">
                        <label for="emailInput">{{email_address}}</label> <br>
                        <input id="emailInput" type="text" v-model="inputted_email" placeholder="example@gmail.com">
                    </div>
                    <br>

                    <!--Selection list-->
                    <div class="select_container" id = "select-list">
                        <select v-model="selected">
                            <label>{{select_option}}</label> <br>
                            <option v-for="option in options" :value="option.value">{{option.text}}</option>
                        </select>
                    </div>
            </div>
        </div>
    </body>

    <!-- Link JavaScript file -->
    <script src="contact.js"></script>
</html> 

Связано ли это с тем, как я делаю компоненты? Если у кого-то есть ответ, пожалуйста, покажите изменения в моем коде, так как я очень новичок в Vue, спасибо

Ответ №1:

Ваши ContactTitles UserInputs и #select-lists приложения используют один и тот же макет , но не используют общие реквизиты данных. Ошибки прекратятся, если вы определите все реквизиты в самом верхнем приложении.

Примечание: Я буду рекомендовать создать одно корневое приложение и вместо этого использовать компоненты, потому что ремонтопригодность такого подхода очень сложна.

 //############--contact.js--############

//--------------- PAGE TITLE ---------------
// Vue object: Title
const PageTitle = {
    data() {
        return {
            title: 'Contact Us'
        }
    }
}

Vue.createApp(PageTitle).mount('#page-title')

//--------------- NAVIGATION (Cart) ---------------
// Vue object: Title
const CartTitle = {
    data() {
        return {
            cart_title: 'Cart'
        }
    }
}

Vue.createApp(CartTitle).mount('#cart-title')

//--------------- NAVIGATION (Main pages) ---------------
// Vue object: Titles
const MainNav = {
    data() {
        return {
            home: 'Home',
            for_hire: 'For Hire',
            about: 'About',
            contact_us: 'Contact Us',
            search: 'Search'
        }
    }
}

Vue.createApp(MainNav).mount('#nav-titles')

//--------------- FORM TITLES ---------------
// Vue object: Titles
const ContactTitles = {
    data() {
        return {
            main_title: 'Contact Us',
            name: 'Name',
            email_address: 'Email Address',
            select_option: 'What is your enquiry about?',
            checkboxes: 'Please click on each wrestling company you know:',
        selected: 'None',
        options: [
          { text: 'Booking enquiry', value: 'Booking' },
          { text: 'Website improvement', value: 'Website' },
          { text: 'Item enquiry', value: 'Item' },
          { text: 'Previous experiences', value: 'Experience' },
          { text: 'Career opportunity', value: 'Career' }
        ],
            inputted_name: '',
            inputted_email: '',
            inputted_message: ''
        }
    }
}

Vue.createApp(ContactTitles).mount('#contact-titles')


//--------------- FORM INPUTS ---------------
// Vue object: Inputs
const UserInputs = {
    data() {
        return {
            inputted_name: '',
            inputted_email: '',
            inputted_message: ''
        }   
    },

    methods: {
        checkInput: function () {
            if (this.inputted_name === '' || this.inputted_email === '' || this.inputted_message === '') 
            {
                alert("Please input in all the fields");
            }
        }
    }
}

Vue.createApp(UserInputs).mount('#contact-form-inputs')

// Vue instance: Select options
Vue.createApp({
    data() {
      return {
        selected: 'None',
        options: [
          { text: 'Booking enquiry', value: 'Booking' },
          { text: 'Website improvement', value: 'Website' },
          { text: 'Item enquiry', value: 'Item' },
          { text: 'Previous experiences', value: 'Experience' },
          { text: 'Career opportunity', value: 'Career' }
        ]
      }
    }
}).mount('#select-list') 
 /* Stylesheet for SIT120 Project - contact.html */
/*----------------------------------------------------*/

/*/////////////////////////-NO margins-//////////////////////////////*/
/* Expands to width of screen*/
body, html {
    margin: 0;
    padding: 0;
}

body {
    background-color: #AAAAAA;
}

/*/////////////////////////-Header Navigation-//////////////////////////////*/

/* Top navigation (cart) */
.cart_nav ul {
    list-style-type: none;
    margin: auto;
    overflow: hidden;
    background-color: #C6393F; 
}

.cart_nav li {
    float: right;
}

.cart_nav li a {
    font-family: Actor;
    font-size: 18px;
    font-style: normal;
    font-weight:normal;
    padding: 15px 55px 15px 20px;
    color: white;
    display: inline-block;
    text-decoration: none;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    transition: all 0.2s linear;
    -webkit-transition: all 0.2s linear;
    -moz-transition: all 0.2s linear;
    
}

.cart_nav li a:hover 
{
    color:#AAAAAA;
}

/*/////////////////////////-Cart Number-//////////////////////////////*/

/* Cart number (circled) */
.cart_items 
{
    font-family: Righteous;
    font-size: 16px;
    font-weight: bold;
    color: white;
    background-color:#2C2C2C;
    float: right; 
    margin-top: 16px;
    margin-right: 16px;
    margin-left: -33px;
    border-radius: 60%;
    width: 25px;
    height: 22px;
    text-align: center; 
}

/*/////////////////////////-Cart icons-//////////////////////////////*/

/* Top navigation ICONS (cart) */
.cart_icon
{
    display:inline-flex;
    width: 40px;
    height: 40px;
    margin-top: -20px;
    margin-bottom: -15px;
    margin-right: -17px;
    padding-left: 8px;
}

/*/////////////////////////-Main navigation-//////////////////////////////*/

/* Main navigation (pages) */
.page_nav ul
{
    list-style-type: none;
    margin: auto;
    overflow: hidden;
    background-color: #2C2C2C;
}

.page_nav li 
{
    float: left;
}

.page_nav li a {
    font-family: Bai Jamjuree;
    font-size: 22px;
    font-weight: bold;
    padding: 15px;
    line-height: 22px;
    color: #AAAAAA;
    display: inline-block;
    padding: 40px 60px 35px 30px;
    text-decoration: none;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    transition: all 0.2s linear;
    -webkit-transition: all 0.2s linear;
}

.page_nav li a:hover 
{
    color:#FFFFFF;
}

.page_nav li a.active
{
    text-decoration: overline;
    color:#FFFFFF;

}
.page_nav li a:focus
{
    text-decoration: overline;
    color:#FFFFFF;

}

/*/////////////////////////-Navigation icon (Search)-//////////////////////////////*/

/* Main navigation search ICON */
.search_icon
{
    display:inline-block;
    width: 35px;
    height: 37px;
    margin-top: -40px;
    margin-bottom: -15px;
    margin-right: -50px;
    padding-left: 13px;
    padding-right: 45px;
}

/*/////////////////////////-LOGO-//////////////////////////////*/

 /* Main logo (Wrestle Hire logo) */
.site_logo
{
    display: inline;
    float: left;
    width: 180px;
    height: 145px; 
    padding-right: 50px;
    margin-bottom: -20px;
    margin-left: -30px;
    margin-top: -10px;
}


.site_logo:hover
{
    cursor: pointer;
}

/*/////////////////////////-Form-//////////////////////////////*/
.form_container {
   background-color: #2C2C2C;
   margin-left: auto;
   margin-right: auto;
   width: 50em;
   padding: 45px;
   border: #C6393F 6px solid;
   border-radius: 4px;
   box-shadow: 20px 20px 20px grey;
}

.form_inputs 
{
    margin-left: 1.2em;
    margin-right: auto;
    width: 100%;
}

.input_container input {
    padding: 15px;
    border: none;
    width: 42em;
    
}

::placeholder {
    font-family: Abel;
    font-size: 18px;;
}

label {
    font-family: Bai Jamjuree;
    font-size: 18px;
    color: #AAAAAA;
    line-height: 2em;
}

input[type="text"]
{
    font-family: Bai Jamjuree;
    font-size: 18px;
    color: #2d2d2d;
    font-size: 1rem;
    background-color: white;
    border-radius: 4px;
} 
 <html>
    <head>
        <!--Stylesheets and responsiveness-->
        <link rel="stylesheet" type= "text/css" href="contact.css">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!--Link Vue Framework-->
        <script src="https://unpkg.com/vue@next"></script>

        <!-- Set responsiveness to screen size -->
        <meta name="viewport" content="width=device-width, initial-scale=1">    

        <!--Google fonts-->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Actor">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Bai Jamjuree">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Righteous">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Abel">

        <!--Page Icon-->
        <link rel="icon" href="../Assets/page_icon.png">

        <!-- Page title-->
        <title id="page-title">{{title}}</title>
    </head>
    
    <body>
        <!--NAVIGATION-->
        <header>
            <!--Top navigation section (login, account and cart)-->
            <div class = "cart_nav" id = "cart-title">
                <ul>
                    <div class = "cart_items">0</div>
                    <li><a href="#cart">{{cart_title}}<img class = "cart_icon" src="../Assets/cart.png" alt="cart_icon"></a></li>
                </ul>
            </div>

              <!--Main navigation section (main pages)-->
            <div class = "page_nav" id = "nav-titles">
                <ul>
                    <!--All main pages will have .html files, this example has the contact as a separate file (and empty files)-->
                    <a href="../Home/home.html"><img href ="../Home/home.html" class = "site_logo" id = "siteLogo" src="../Assets/website_logo.png"/></a>
                    <li><a href="../Home/home.html">{{home}}</a></li>
                    <li><a href="">{{for_hire}}</a></li>
                    <li><a href="">{{about}}</a></li>
                    <li><a class = "active" href="contact.html">{{contact_us}}</a></li>
                    <li class = "search" style="float:right"><a>{{search}}<img class = "search_icon" src="../Assets/search.png" alt="search_icon"></a></li>
                </ul>
            </div>
        </header>

        <!--CONTACT FORM-->
        <h1>contact us</h1>

        <div class="form_container" id = "contact-titles">
            <div class = "form_inputs" id = "contact-form-inputs">
                    <!--Name input-->
                    <div class="input_container">
                        <label for="nameInput">{{name}}</label> <br>
                        <input id="nameInput" type="text" v-model="inputted_name" placeholder="Enter name">
                    </div>
                    <br>

                    <!--Email input-->
                    <div class="input_container">
                        <label for="emailInput">{{email_address}}</label> <br>
                        <input id="emailInput" type="text" v-model="inputted_email" placeholder="example@gmail.com">
                    </div>
                    <br>

                    <!--Selection list-->
                    <div class="select_container" id = "select-list">
                        <select v-model="selected">
                            <label>{{select_option}}</label> <br>
                            <option v-for="option in options" :value="option.value">{{option.text}}</option>
                        </select>
                    </div>
            </div>
        </div>
    </body>

    <!-- Link JavaScript file -->
    <script src="contact.js"></script>
</html>