.js
按照上一篇的组件树创建目录
按照 esm 的方式创建各组件的 js 文件,也可以把样式抽离出去成 scss 或 css 文件
main
import App from 'App';
Vue.createApp(App).mount("#app");
App
import MyHeader from './components/MyHeader';
const App = {
components: {
MyHeader
},
data() {
return {
navData: [
{id: 1, title: 'Baidu', link: 'http://www.baidu.com'},
{id: 2, title: 'Google', link: 'http://www.google.com'},
{id: 3, title: 'Bing', link: 'http://www.bing.com'}
],
navData2: [
{id: 1, title: '京东', link: 'http://www.jd.com'},
{id: 2, title: '淘宝', link: 'http://www.taobao.com'},
{id: 3, title: '天猫', link: 'http://www.tmall.com'}
]
}
},
template: `
<div>
<my-header :nav-data="navData" />
<my-header :nav-data="navData2" />
</div>
`
}
export default App;
MyHeader
import MyLogo from './MyLogo';
import MyNav from './MyNav';
import MyUser from './MyUser';
const MyHeader = {
components: {
MyLogo,
MyNav,
MyUser
},
props: ['navData']
template: `
<header>
<my-logo />
<my-nav :nav-data="navData" />
<my-user />
</header>
`
}
export default MyHeader;
MyLogo
import './index.scss';
const MyLogo = {
template: `
<div class="my-logo">LOGO</div>
`
}
export default MyLogo;
.my-logo {
float: left;
padding: 0 20px;
}
MyNav
import NavItem from './NavItem';
import './index.scss';
const MyNav = {
components: {
NavItem
},
props: ['navData']
template: `
<ul class="my-nav">
<nav-item v-for="item of navData" :key="item.id" :nav-item="item"/>
</ul>
`
}
export default MyNav;
NavItem
const NavItem = {
props: ['navItem'],
template: `
<li>
<a :href="navItem.link" target="_blank">{{ navItem.title }}</a>
</li>
`
}
export default NavItem;
.my-nav {
float: left;
padding: 0 35px;
margin: 0;
list-style:none;
.nav-item {
float: left;
padding: 0 15px;
}
}
MyUser
const MyUser = {
template: `
<div>
<a href=“#”>Sign in</a> | <a href=“#”>Sign up</a>
</div>
`
}
export default MyUser;
.vue
.vue 的本质是在一个文件内包含
- template
- script
- style
然后.vue 会打包成 .js
为了 import 时可以忽略写 .vue
在 webpack.config.js 加上
model.exports = {
//...
resolve: {
extension: ['.js', '.jsx', '.vue']
},
// ...
}
在 webpack 中已经配置 vue-loader 可以解析到 .vue 文件
App
<template>
<div>
<my-header :nav-data="navData" />
<my-header :nav-data="navData2" />
</div>
</template>
<script>
export default {
name: 'app',
components: {
MyHeader
},
data() {
return {
navData: [
{id: 1, title: 'Baidu', link: 'http://www.baidu.com'},
{id: 2, title: 'Google', link: 'http://www.google.com'},
{id: 3, title: 'Bing', link: 'http://www.bing.com'}
],
navData2: [
{id: 1, title: '京东', link: 'http://www.jd.com'},
{id: 2, title: '淘宝', link: 'http://www.taobao.com'},
{id: 3, title: '天猫', link: 'http://www.tmall.com'}
]
}
},
}
</script>
MyHeader
<template>
<header>
<my-logo />
<my-nav :nav-data="navData" />
<my-user />
</header>
</template>
<script>
import MyLogo from './MyLogo';
import MyNav from './MyNav';
import MyUser from './MyUser';
export default {
name: 'my-header',
components: {
MyLogo,
MyNav,
MyUser
}
props: ['navData']
}
</script>
MyLogo
<template>
<div class="my-logo">LOGO</div>
</template>
<script>
export default {
name: 'my-logo'
}
</script>
<style lang="scss">
.my-logo {
float: left;
padding: 0 20px;
}
</style>
MyNav
<template>
<ul class="my-nav">
<nav-item v-for="item of navData" :key="item.id" :nav-item="item"/>
</ul>
</template>
<script>
export default {
name: 'my-nav',
components: {
NavItem
},
props: ['navData']
}
</script>
<style lang="scss">
.my-nav {
float: left;
padding: 0 35px;
margin: 0;
list-style:none;
}
</style>
NavItem
<template>
<li>
<a :href="navItem.link" target="_blank">{{ navItem.title }}</a>
</li>
</template>
<script>
export default {
name: 'nav-item',
props: ['navItem']
}
</script>
<style lang="scss">
.nav-item {
float: left;
padding: 0 15px;
}
</style>
MyUser
<template>
<div>
<a href=“#”>Sign in</a> | <a href=“#”>Sign up</a>
</div>
</template>
<script>
export default {
name: 'my-user',
}
</script>
组件全局注册
组件注册
- 全局注册
- 局部注册
在组件树最顶层,即在 main.js 中 createApp 返回的对象通过 component
方法注册
import App from './App';
const app = Vue.createApp(App);
app.component('my-search', {
data() {
return {
placeholder: 'Please type the keyword...',
keyword: ''
}
},
template: `
<div style="float: left">
<input type="text" :placeholder="placeholder" v-model="keyword" />
<button @click="searchAction">Search</button>
</div>
`,
methods: {
searchAction() {
console.log(this.keyword);
}
}
});
app.mount("#app");
这样可以在所有组件中不需要局部相应的注册来使用,如在 MyHeader 中使用
<template>
<header>
<my-logo />
<my-search />
<my-nav :nav-data="navData" />
<my-user />
</header>
</template>
<script>
import MyLogo from './MyLogo';
import MyNav from './MyNav';
import MyUser from './MyUser';
export default {
name: 'my-header',
components: {
MyLogo,
MyNav,
MyUser
}
props: ['navData']
}
</script>
分离全局注册
创建一个 globalComponents.js 方法
export default function globalComponents (app) {
app.component('my-search', {
data() {
return {
placeholder: 'Please type the keyword...',
keyword: ''
}
},
template: `
<div style="float: left">
<input type="text" :placeholder="placeholder" v-model="keyword" />
<button @click="searchAction">Search</button>
</div>
`,
methods: {
searchAction() {
console.log(this.keyword);
}
}
});
}
import App from './App';
import globalComponents from './components/Global'
const app = Vue.createApp(App);
globalComponents(app);
app.mount("#app");