弹性盒子 display:flex
align-item:center
justify-content:center
Vue组件
组件 (Component) 是 Vue.js 最强大的功能之一。
组件可以扩展 HTML 元素,封装可重用的代码。是可复用的Vue实例。
组件的注册
// html 代码 <div id="app"> <my-component></my-component> </div> // js 代码 Vue.component('my-component', { template: '<div>A component!</div>' }) var app = new Vue({ el: '#app', data: { } });
// html 代码 <div id="app"> <my-component></my-component> </div> // js 代码 // 组件中的data必须是个函数 var Child = { template: '<div>A component!</div>', data: function() { return { name: "gao", } }}; new Vue({ // ... components: { // <my-component> 将只在父组件模板中可用 'my-component': Child } })
// js 代码 Vue.component('child', { template: `<div><button @click="on_click()">{{msg}}</button></div>`, data: function () { return { msg: "点我", } }, methods: { on_click(){ alert(123) } } }); new Vue({ el: "#app", })
<script>
var my_component = {
template: `<div><h1>{{msg}}</h1></div>`,
data(){
return{
msg: "这是子组件"
}
}
};
var global_component = {
template: `<div>
<h1>{{msg}}</h1>
<button @click="on_click">点我</button>
<my_component></my_component>
</div>`,
data(){
return {
msg: "全局组件"
}
},
methods: {
on_click() {
alert("123")
}
},
components:{
my_component:my_component,
}
};
const app = new Vue({
el: "#app",
data: {
},
components: {
global_component: global_component,
// my_component: my_component,
}
});
</script>
组件之间的通信
我们的组件在任何地方用的时候都要是一个样子么~
可不可以我们给组件传个参数~让组件在不同的地方表现不同的状态~
我们之前说过博客评论@某某某,点击用户名可以跳转到该用户站点。
这样一个小功能,我们每次@的时候都要写,我们可以封装成组件,传值即可~~
// html 代码 <div id="app"> <child username="gaoxin"></child> </div> // js 代码 Vue.component('child', { template: `<a :href="'/user/'+ username">{{username}}</a>`, props: ["username"], }); var app = new Vue({ el: "#app", data:{ name: "@gaoxin" } });
app.$on(event, callback) 监听当前实例上的自定义事件,事件由$emit触发,回调函数接收事件触发器额外参数。
app.$emit(event, [args....]) 触发当前实例上的事件,额外参数传给监听器的callback回调函数。
// html 代码 <div id="app"> <parent></parent> </div> // js 代码 Vue.component('parent',{ template: ` <div> <child @show_balance="show"></child> <p v-if="active">您的余额998</p> </div> `, data: function () { return { active: false, } }, methods: { show: function(data){ this.active=true; console.log(data) } } }); Vue.component('child', { template: `<div><button @click="on_click()">{{msg}}</button></div>`, data: function () { return { msg: "显示余额", } }, methods: { on_click(){ // alert(123) this.$emit('show_balance', {q:1,b:2}) } } });
平行组件之间的通信,喊话需要一个中间调度器,在组件加载完成之后去监听调度器事件,回调函数接收数据。
// html 代码 <div id="app"> <whh></whh> <shh></shh> </div> // js 代码 var Event = new Vue() Vue.component('whh',{ template: ` <div> 我说: <input @keyup="on_change" v-model="i_said"> </div> `, data: function () { return { i_said: '', } }, methods: { on_change: function () { Event.$emit("whh_said_something", this.i_said) } } }); Vue.component('shh', { template: ` <div> 花花说:{{whh_said}} </div> `, data: function () { return { whh_said: '', } }, mounted: function () { var me = this Event.$on('whh_said_something', function (data) { me.whh_said = data }) } });
混合Mixins
重复功能和数据的储存器,可以覆盖Mixins的内容。
// 点击显示和隐藏 提示框的显示和隐藏 // html 代码 <div id="app"> <PopUp></PopUp> <ToolTip></ToolTip> </div> // js 代码 var base = { data: function () { return { visible: false, } }, methods: { show: function () { this.visible = true }, hide: function () { this.visible = false } } } Vue.component('popup', { template:` <div> <button @click="show">PopUp show</button> <button @click="hide">PopUp hide</button> <div v-if="visible"><p>hello everybody</p></div> </div> `, mixins: [base], data: function () { return { visible: true, } } }); Vue.component('tooltip', { template: ` <div> <div @mouseenter="show" @mouseleave="hide">ToolTip</div> <div v-if="visible"><p>ToolTip</p></div> </div> `, mixins: [base] }); new Vue({ el: "#app", })
插槽 Slot
插槽是一套内容分发的API,在组件中,<slot>作为内容承载分发的出口
// html 代码 <div id="app"> <panel> <div slot="title"> HELLO</div> <div slot="content">hello</div> </panel> <panel></panel> <panel></panel> </div> <template id="panel-tpl"> <div class="panel"> <div class="title"> <slot name="title"></slot> </div> <div class="content"> <slot name="content"></slot> </div> <!--<div class="content">Failure is probably the fortification in your pole. It is like a peek your wallet as the thief, when you are thinking how to spend several hard-won lepta,</div>--> <div class="footer"> <slot name="footer">更多信息</slot> </div> </div> </template> // js 代码 Vue.component('panel', { template: '#panel-tpl', }); new Vue({ el: "#app", })
vue-router是什么~~
vue-router是Vue的路由系统,定位资源的,我们可以不进行整页刷新去切换页面内容。
vue-router的安装和基本配置
vue-router.js 可以下载 也可以用cdn,基本配置信息看如下代码~~~
// html 代码 <div id="app"> <div> <router-link to="/">首页</router-link> <router-link to="/about">关于我们</router-link> </div> <div> <router-view></router-view> </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script src="../js/router_demo.js"></script> // js 代码 var routes = [ { path: "/", component: { template: `<div><h1>首页</h1></div>` } }, { path: "/about", component: { template: `<div><h1>关于我们</h1></div>` } } ] var router = new VueRouter({ routes: routes, // 路由去掉# // mode: 'history', }); var app = new Vue({ el: '#app', router: router, });
路由的一些方法
路由传参以及获取参数~~
// html 代码 <div id="app"> <div> <router-link to="/">首页</router-link> <router-link to="/about">关于我们</router-link> <router-link to="/user/琴女?age=20">琴女</router-link> <router-link to="/user/提莫">提莫</router-link> </div> <div> <router-view></router-view> </div> </div> // js 代码 var routes = [ { path: "/", component: { template: `<div><h1>首页</h1></div>` } }, { path: "/about", component: { template: `<div><h1>关于我们</h1></div>` } }, { path: "/user/:name", component: { template: `<div> <h1>我是:{{$route.params.name}}</h1> <h1>我年龄是:{{$route.query.age}}</h1> </div>`, } } ] var router = new VueRouter({ routes: routes, }); var app = new Vue({ el: '#app', router: router, });
命名路由~ 注意router-link里to一定要v-bind~~
// html代码 <div id="app"> <div> <router-link to="/">首页</router-link> <router-link :to="{name: 'about'}">关于我们</router-link> <router-link to="/user/gaoxin?age=19">gaoxin</router-link> </div> <div> <router-view></router-view> </div> </div> // js代码 let routes = [ { path: '/', component: { template: `<h1>这是主页</h1>` } }, { path: "/about", name: "about", component: { template: `<h1>关于我们</h1>` } }, { path: "/user/:name", component: { template: `<div> <h1>我是{{$route.params.name}}</h1> <h2>我的年龄是{{$route.query.age}}</h2> </div> ` } } ]; let router = new VueRouter({ routes: routes, mode: "history" }); const app = new Vue({ el: "#app", router: router, mounted(){ console.log(this.$route) console.log(this.$router) } })
子路由~~ 以展示详细为例~~
// 添加子路由变化的只有父级路由 // 基于上面的例子增加 // js 代码 { path: "/user/:name", component: { template: `<div> <h1>我是:{{$route.params.name}}</h1> <h1>我年龄是:{{$route.query.age}}</h1> <router-link to="more" append>更多信息</router-link> <router-view></router-view> </div>`, }, children: [ { path: "more", component: { template: `<div> {{$route.params.name}}的详细信息 </div>`, } } ] },
手动访问路由,以及传参~~
// 基于上面例子追加 // html 代码 <div id="app"> <div> <router-link to="/">首页</router-link> <router-link to="/about">关于我们</router-link> <router-link to="/user/琴女?age=20">琴女</router-link> <router-link to="/user/提莫">提莫</router-link> // 添加一个button按钮 <button @click="on_click">旅游</button> </div> <div> <router-view></router-view> </div> </div> // js 代码 // 注意路由name的使用 这是在原例子追加 var app = new Vue({ el: '#app', router: router, methods: { on_click: function () { setTimeout(function () { this.$router.push('/about') setTimeout(function () { this.$router.push({name: "user", params:{name: "琴女"},query:{age: 20}}) }, 2000) }, 2000) } } });
命名路由视图 router-view
当我们只有一个<router-view></router-view>的时候~所有内容都展示在这一个面板里面~
如果是content 和 footer 就需要同时显示并且不同区域~这就需要对视图进行命名~
// html 代码 <div id="app"> <div> <router-link to="/">首页</router-link> </div> <div> <router-view name="content" class="content-view"></router-view> <router-view name="footer" class="footer-view"></router-view> </div> </div> // js 中的主要代码 var routes = [ { path: "/", components: { content: { template: `<div><h1>首页</h1></div>`, }, footer: { template: `<div><h1>关于我们</h1></div>`, } } }, ]
错误路由的重定向~~
let routes = [ { path: "**", redirect: "/" } ]
$route以及$router的区别~~
-- $route为当前router调转对象,里面可以获取name, path, query, params等~
-- $router为VueRouter实例,有$router.push方法等~~
路由的钩子
路由的生命周期就是从一个路由跳转到另一路由整个过程,下面介绍两个钩子~
router.beforeEach() router.afterEach() 详情请看代码~~
// html 代码 <div id="app"> <router-link to="/">首页</router-link> <router-link to="/login">登录</router-link> <router-link to="/user">用户管理</router-link> <div> <router-view></router-view> </div> </div> // js 代码 var routes = [ { path: "/", component: { template: "<h1>首页</h1>" } }, { path: "/login", component: { template: "<h1>登录</h1>" } }, { path: "/user", component: { template: "<h1>用户管理</h1>" } } ]; var router = new VueRouter({ routes: routes }); router.beforeEach(function (to,from,next) { // console.log(to) // console.log(from) // console.log(next) // next(false) if(to.path=="/user"){ next("/login") } else { next(); } }); router.afterEach(function (to, from) { console.log(to) console.log(from) }); var app = new Vue({ el: '#app', router: router });
next:function 一定要调用这个方法来resolve这个钩子函数。 执行效果依赖next方法的调用参数 next() 什么都不做继续执行到调转的路由 next(false) 中断当前导航 没有跳转 也没有反应 next("/") 参数是路径 调转到该路径 next(error) 如果next参数是一个Error实例 导航终止该错误 会传递给router.onError()注册过的回调中
上面的例子~~如果/user下面还有子路由的情况下会怎么样呢~????
// 匹配子路由 改一下匹配方法就可以~ // js 改动代码 router.beforeEach(function (to,from,next) { // console.log(to) // console.log(from) // console.log(next) // next(false) if(to.matched.some(function (item) { return item.path == "/post" })){ next("/login") } else { next(); } }); // 元数据配置 改动代码 // html 部分 { path: "/user", meta: { required_login: true, }, component: { template: ` <div> <h1>用户管理</h1> <router-link to="vip" append>vip</router-link> <router-view></router-view> </div> ` }, children: [{ path: "vip", meta: { required_login: true, }, component: { template: '<h1>VIP</h1>' } }] } // js 部分 router.beforeEach(function (to,from,next) { // console.log(to) // console.log(from) // console.log(next) // next(false) if(to.meta.required_login){ next("/login") } else { next(); } });

浙公网安备 33010602011771号