无法解析组件:“wrestler-choice-box”如果这是本机自定义元素,请确保将其从组件解析中排除
Posted
技术标签:
【中文标题】无法解析组件:“wrestler-choice-box”如果这是本机自定义元素,请确保将其从组件解析中排除【英文标题】:Failed to resolve component: "wrestler-choice-box" If this is a native custom element, make sure to exclude it from component resolution 【发布时间】:2021-11-15 15:48:21 【问题描述】:关于我想要实现的一些背景故事,我有一组数据,我想放入我的 html 文件和一个带有模板的 Vue 组件。我想使用列表渲染,以便所述数组中的名称和图像绑定到自定义组件道具。但是,错误(在这篇文章的标题中)不断发生。这是我的代码:
//############--wrestlers.js--############
//--------------- PAGE TITLE ---------------//
// Vue object: Title
const PageTitle =
data()
return
title: 'For Hire - Wrestlers'
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: Title
const MainNav =
data()
return
home: 'Home',
for_hire: 'For Hire',
about: 'About',
contact_us: 'Contact Us',
search: 'Search'
Vue.createApp(MainNav).mount('#nav-titles')
//--------------- Hiring selection - Wrestlers ---------------//
// Custom Vue Component: Binding information to each wrestler
const app = Vue.createApp()
app.component("wrestler-choice-box",
props: ['name', 'image'],
template:
`
<div class = "option_container">
<img class = "option_image" src = "image">
<h4 class = "option_name">name</h4>
</div>
`
)
app.mount('#hire-wrestler-choice')
// Vue object: Wrestlers and information
var WrestlerData = Vue.createApp (
data()
return
items: [
wrestler_name: 'Bobby Lashley', image_src: "../Assets/Wrestlers/wrestler_1.png" ,
wrestler_name: 'Brock Lesnar', image_src: "../Assets/Wrestlers/wrestler_2.png" ,
wrestler_name: 'Commander Azeez', image_src: "../Assets/Wrestlers/wrestler_3.png" ,
wrestler_name: 'Drew McIntyre', image_src: "../Assets/Wrestlers/wrestler_4.png" ,
wrestler_name: 'Gran Metalik', image_src: "../Assets/Wrestlers/wrestler_5.png" ,
wrestler_name: 'Jeff Hardy', image_src: "../Assets/Wrestlers/wrestler_6.png" ,
wrestler_name: 'John Cena', image_src: "../Assets/Wrestlers/wrestler_7.png" ,
wrestler_name: 'Kevin Owens', image_src: "../Assets/Wrestlers/wrestler_8.png" ,
wrestler_name: 'Lince Derado', image_src: "../Assets/Wrestlers/wrestler_9.png" ,
wrestler_name: 'Pete Dunne', image_src: "../Assets/Wrestlers/wrestler_10.png" ,
wrestler_name: 'Sheamus', image_src: "../Assets/Wrestlers/wrestler_11.png" ,
wrestler_name: 'Undertaker', image_src: "../Assets/Wrestlers/wrestler_12.png" ,
wrestler_name: 'Akira Tozawa', image_src: "../Assets/Wrestlers/wrestler_13.png" ,
wrestler_name: 'Corey Grimes', image_src: "../Assets/Wrestlers/wrestler_14.png" ,
wrestler_name: 'Jinder Mahal', image_src: "../Assets/Wrestlers/wrestler_15.png" ,
wrestler_name: 'T-Bone', image_src: "../Assets/Wrestlers/wrestler_16.png" ,
]
).mount('#wrestler-data')
/* Stylesheet for SIT120 Project - wrestlers.css */
/*----------------------------------------------------*/
/*/////////////////////////-NO margins-//////////////////////////////*/
/* Expands to width of screen*/
body, html
margin: 0;
padding: 0;
/*/////////////////////////-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;
/*/////////////////////////-Hiring selection - Wrestlers-//////////////////////////////*/
.option_row
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;
margin-top: 12px;
.option_container
flex-basis: 20%;
padding: 17px;
min-width: 200px;
transition: transform 0.5s;
transition: 0.5s;
.option_container:hover
transform: translateY(-3px);
box-shadow: 0 0 15px #C6393F;
border-radius: 3px;
.option_image
width: 100%;
transition: 0.5s;
.option_list_container
margin: auto;
padding-left: 40px;
padding-right: 40px;
.option_name
font-family: Bai Jamjuree;
font-size: 1.2em;
margin-top: -1px;
.rating
color: #C6393F;
margin-top: -20px;
<!--HTML FILE: wrestlers.html-->
<!DOCTYPE html>
<html>
<head>
<!--Stylesheets-->
<link rel="stylesheet" type= "text/css" href="wrestlers.css">
<!--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">
<!--Star icon (Font Awesome)-->
<script src="https://use.fontawesome.com/d83f9b7e69.js"></script>
<!--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" ></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 href="../Contact/contact.html">contact_us</a></li>
<li class = "search" style="float:right"><a>search<img class = "search_icon" src="../Assets/search.png" ></a></li>
</ul>
</div>
</header>
<!--Wrestlers-->
<div class = "small_container" id = "wrestler-data">
<div class = "option_row" >
<wrestler-choice-box id ="hire-wrestler-choice" v-for="item in items" :name="item.wrestler_name" :image="item.image_src">
</wrestler-choice-box>
</div>
</div>
</body>
<!-- Link javascript file -->
<script src="wrestlers.js"></script>
</html>
不要介意丢失的图片,它们在我的电脑上并在文件夹中引用
如果有人能看到问题,请提及,因为我一直在努力寻找问题
谢谢:)
【问题讨论】:
据我所见,您将其安装到错误的元素上。您尝试app.mount('#hire-wrestler-choice')
但在您的 html 中,具有该 id 的元素是您尝试从安装中调用的组件。 <wrestler-choice-box id ="hire-wrestler-choice"
你可以尝试挂载到包装器上app.mount('#wrestler-data')
非常感谢,解决了“那个错误”,但现在我不幸收到错误消息“在渲染期间访问了属性“项目”,但未在实例上定义。”
尝试将您的组件作为组件添加到 vue 实例中。不要创建一个空的占位符应用程序const app = Vue.createApp()
并在那里添加组件,而是将您的组件存储在一个变量中并将该组件添加到您的摔跤手数据实例var WrestlerData = Vue.createApp (...).component(componentVar).mount('#wrestler-data')
你介意给我看看我链接的 .js 文件上的样子吗,我还是有点困惑(我对 Vue 很陌生)
【参考方案1】:
您的安装有缺陷。您引用了错误的 ID。
app.mount('#hire-wrestler-choice')
在您的 HTML 中,此 ID 设置在您尝试调用的组件上
<wrestler-choice-box id ="hire-wrestler-choice" v-for="item in items" :name="item.wrestler_name" :image="item.image_src">
</wrestler-choice-box>
您必须将它安装到现有的 html 元素才能访问该组件。例如:
app.mount('#wrestler-data')
编辑:
您使用占位符应用只是为了挂载它。我建议将您的组件直接添加到您的 wrestlerData 实例中。
//############--wrestlers.js--############
//--------------- PAGE TITLE ---------------//
// Vue object: Title
const PageTitle =
data()
return
title: 'For Hire - Wrestlers'
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: Title
const MainNav =
data()
return
home: 'Home',
for_hire: 'For Hire',
about: 'About',
contact_us: 'Contact Us',
search: 'Search'
Vue.createApp(MainNav).mount('#nav-titles')
//--------------- Hiring selection - Wrestlers ---------------//
// Custom Vue Component: Binding information to each wrestler
const wrestlerChoiceBox =
name: 'wrestler-choice-box',
props: ['name', 'image'],
template: `
<div class = "option_container">
<img class = "option_image" :src="image">
<h4 class = "option_name">name</h4>
</div>
`
;
// Vue object: Wrestlers and information
var WrestlerData = Vue.createApp(
data()
return
items: [
wrestler_name: 'Bobby Lashley',
image_src: "../Assets/Wrestlers/wrestler_1.png"
,
wrestler_name: 'Brock Lesnar',
image_src: "../Assets/Wrestlers/wrestler_2.png"
,
wrestler_name: 'Commander Azeez',
image_src: "../Assets/Wrestlers/wrestler_3.png"
,
wrestler_name: 'Drew McIntyre',
image_src: "../Assets/Wrestlers/wrestler_4.png"
,
wrestler_name: 'Gran Metalik',
image_src: "../Assets/Wrestlers/wrestler_5.png"
,
wrestler_name: 'Jeff Hardy',
image_src: "../Assets/Wrestlers/wrestler_6.png"
,
wrestler_name: 'John Cena',
image_src: "../Assets/Wrestlers/wrestler_7.png"
,
wrestler_name: 'Kevin Owens',
image_src: "../Assets/Wrestlers/wrestler_8.png"
,
wrestler_name: 'Lince Derado',
image_src: "../Assets/Wrestlers/wrestler_9.png"
,
wrestler_name: 'Pete Dunne',
image_src: "../Assets/Wrestlers/wrestler_10.png"
,
wrestler_name: 'Sheamus',
image_src: "../Assets/Wrestlers/wrestler_11.png"
,
wrestler_name: 'Undertaker',
image_src: "../Assets/Wrestlers/wrestler_12.png"
,
wrestler_name: 'Akira Tozawa',
image_src: "../Assets/Wrestlers/wrestler_13.png"
,
wrestler_name: 'Corey Grimes',
image_src: "../Assets/Wrestlers/wrestler_14.png"
,
wrestler_name: 'Jinder Mahal',
image_src: "../Assets/Wrestlers/wrestler_15.png"
,
wrestler_name: 'T-Bone',
image_src: "../Assets/Wrestlers/wrestler_16.png"
,
]
);
WrestlerData.component('wrestler-choice-box',wrestlerChoiceBox);
WrestlerData.mount('#wrestler-data');
/* Stylesheet for SIT120 Project - wrestlers.css */
/*----------------------------------------------------*/
/*/////////////////////////-NO margins-//////////////////////////////*/
/* Expands to width of screen*/
body,
html
margin: 0;
padding: 0;
/*/////////////////////////-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;
/*/////////////////////////-Hiring selection - Wrestlers-//////////////////////////////*/
.option_row
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;
margin-top: 12px;
.option_container
flex-basis: 20%;
padding: 17px;
min-width: 200px;
transition: transform 0.5s;
transition: 0.5s;
.option_container:hover
transform: translateY(-3px);
box-shadow: 0 0 15px #C6393F;
border-radius: 3px;
.option_image
width: 100%;
transition: 0.5s;
.option_list_container
margin: auto;
padding-left: 40px;
padding-right: 40px;
.option_name
font-family: Bai Jamjuree;
font-size: 1.2em;
margin-top: -1px;
.rating
color: #C6393F;
margin-top: -20px;
<!--HTML FILE: wrestlers.html-->
<!DOCTYPE html>
<html>
<head>
<!--Stylesheets-->
<link rel="stylesheet" type="text/css" href="wrestlers.css">
<!--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">
<!--Star icon (Font Awesome)-->
<script src="https://use.fontawesome.com/d83f9b7e69.js"></script>
<!--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" ></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 href="../Contact/contact.html">contact_us</a></li>
<li class="search" style="float:right"><a>search<img class = "search_icon" src="../Assets/search.png" ></a></li>
</ul>
</div>
</header>
<!--Wrestlers-->
<div class="small_container" id="wrestler-data">
<wrestler-choice-box v-for="item in items" :name="item.wrestler_name" :image="item.image_src">
</wrestler-choice-box>
</div>
</body>
<!-- Link JavaScript file -->
<script src="wrestlers.js"></script>
</html>
这样您就可以摆脱 var 应用程序,并且应该可以访问您需要迭代的数据。
有用的链接: Component Registration
【讨论】:
解决了这个问题,谢谢,但是现在我收到错误“[Vue Warn] 属性“items”在渲染期间被访问,但未在实例上定义。' @dwayne_d11 我编辑了我的答案来解决这个问题 修复了这个问题,但是有一个 TypeError: TypeError: Cannot read properties of undefined (reading 'mount') at 127.0.0.1:5500/Wrestlers%20(page)/wrestlers.js:84:32 我的错。组件调用不可链接。var WrestlerData = Vue.createApp(...); WrestlerData.component(wrestlerChoiceBox); WrestlerData.mount(...)
修复它太棒了,没有更多错误,但是屏幕上什么也没有出现,当它应该显示图像和标题时。这在我为道具硬编码值时有效,但在使用 v-for 和数组时似乎不想工作以上是关于无法解析组件:“wrestler-choice-box”如果这是本机自定义元素,请确保将其从组件解析中排除的主要内容,如果未能解决你的问题,请参考以下文章