续上一篇文章:
1. vue 组件的说明和使用
一个组件实质上是一个拥有预定义选项的一个 Vue 实例
在header组件内部允许外部使用,需要导出属性,有2种导出方法- 默认导出(不用命名)
export default {data () {return {msg: 'header'}}}复制代码
以上代码实际上会自动生成一个 new vue
在父组件中导入
import Header from './components/header'复制代码
2.直接在任何变量或者函数前面加上一个关键字
export const sqrt = Math.sqrt;在父组件中导入import sqrt from './components/header'; 引用一个组件 import Header from './components/header'复制代码
在该组件中定义
export default{ data: function () {}, //data一定要是返回一个函数 components: { comHeader: Header //声明组件 } }复制代码
在template中使用
复制代码//注意,html不区分大小写,所以需要将 comHeader 写成 com-header
一个vue对象通常包括下面几个属性
data: //vue对象的数据methods: //vue对象的方法watch: //对象监听的方法computed: //计算逻辑放到computed中created: //属性已绑定,dom未生成,一般在这里进行ajax处理以及页面初始化处理复制代码
2. vuex
通过尤大大这张图,我们很清楚的看到,所有的数据流都是单向的,并且actions只能通过分发mutations来修改 store 实例的状态像一些全局信息通用,比如 header内容的渲染,是否显示,loading 什么时候显示,什么时候隐藏,以及接口api的固定值,都写在store记录组件的state。
const store = new Vuex.Store({ state: { comm: { loading: false, //是否显示loading apiUrl: 'http://www.sherlochao.com:9091/photosharing/', //接口base url imgUrl: 'http://www.sherlochao.com:9091/filebase', //图片base url indexConf: { isFooter: true, // 是否显示底部 isSearch: true, // 是否显示搜索 isBack: false, // 是否显示返回 isShare: false, // 是否显示分享 title: '' // 标题 } } }})复制代码
在mutations中改变state状态
const store = new Vuex.Store({mutations: { //loading的显示 isLoading: (state, status) => { state.comm.loading = status }, //修改header的信息 changeIndexConf: (state, data) => { Object.assign(state.comm.indexConf, data) }})e.g 在 header.vue 中 控制是否显示export default { data: function () { return {} }, computed: { isShowSearch: function () { return this.$store.state.comm.indexConf.isSearch //获取vuex里面 state 状态值 }, title: function () { return this.$store.state.comm.indexConf.title }, isBack: function () { return this.$store.state.comm.indexConf.isBack } }}复制代码
template代码
复制代码
在其他地方控制 header 是否显示, e.g: 详情页面
export default { created: function () { vm.$store.commit('changeIndexConf', { isFooter: false, isSearch: false, isBack: true, isShare: true, title: '详情页' }) } }复制代码
3.开发实践总结
- vue-router
由于整个项目list组件很多地方公用,并且‘我的收藏',‘搜索结果页面',‘我的圈子',仅仅只是从 /search/own 到 /search/star
此时,原来的组件实例会被复用,意味着组件的生命周期钩子不会再被调用解决方法: 复用组件时,想对路由参数的变化作出响应的话,可以简单地 watch(监测变化) 对象export default { watch: { '$route' (to, from) { // 对路由变化作出响应... } }}复制代码
2.判断是否登陆
进入个人信息页面,由于需要判断是否已登陆,此时由 router 进行一个拦截,具体代码如下
router.beforeEach(function (to,from,next) { var userMsg = localStorage.getItem('userMsg') if(to.path === '/home'){ if(!userMsg){ next({ path: '/login' }) } } next()})复制代码
3.常用api
1). 点击事件获取当前对象
event.target ,this为vue 对象
2). 和jquery类似获取当前dom对象this.$refs.isSubmit.removeAttribute('disabled') //使用this.$refs 获取当前dom复制代码
以上来自
需要重用组件的考虑
如果一个组件需要重复使用多次,那么请一开始就充分考虑接口,不要已经使用了很多组件了,然后才想起扩充接口。
总的来说,Vue组件的接口包括3个方面:Props(数据)允许外部将数据传入组件内;
Events(事件) 允许将组件内的事件向外传播;Slots(插槽)允许在外部编辑组件内的html内容;复制代码 Hello!
以上就是这三种接口在组件调用时的运用;
注意v-bind 和 v-on的简写形式,这样写有助于让你的代码看起来更清晰;取得某一个组件的实例
我们很容易取得Vue的实例,比如vm;
但是要取得一个组件的实例却并不容易,因为组件是一个模板,多次使用;每次使用都是一个实例;大多数时候我们通过传递参数来改变组件内部数据,但有时候我们需要直接获得这个实例,并改变这个实例的数据;可以这样:复制代码
ref="profile"相当于给了一个组件一个id,于是我们可以这样来取得这个组件的实例:
var vm = new Vue({ el: '#parent' })// access child component instancevar child = vm.$refs.profile复制代码
获得这个实例有什么用?
你可以直接改变组件里面的数据看这个例子:异步组件
一个组件在dom里面,要么有,要么没有,对于某些大型app,会同时有很多组件,可能你需要根据某些条件来决定如何加载这些组件,而不是一次性全部加载;
我们在定义组件的时候,可以有两个回调函数作为参数:
Vue.component('async-example', function (resolve, reject) { setTimeout(function () { resolve({ template: 'I am async!' }) }, 1000)})复制代码
一个是resolve,一个是reject,它们的意思是,当满足某个条件时,我可以选择渲染这个组件,也可以选择拒绝渲染;
上例中的setTimeout仅仅作为演示,你可以定义自己的条件。
组件的命名约定
定义的时候
// in a component definitioncomponents: { // register using camelCase 'kebab-cased-component': { /* ... */ }, 'camelCasedComponent': { /* ... */ }, 'TitleCasedComponent': { /* ... */ }}复制代码
在Html里,由于html区分大小写,所以:
复制代码
全都得长一样;
在String模板里:复制代码
随意;
递归组件
有时候,你需要一个递归调用的嵌套视图;
name: 'stack-overflow',template: ''复制代码
首先必须要有一个name属性;其次上面的代码会报无限死循环的错误,因为在嵌套自己的时候没有加入条件;比如v-if之类的,在必要的时候能够停止循环调用。
写在组件标签内的模板
一般我们都把组件的模板定义在组件的内部;
但你也可以这样写:复制代码 These are compiled as the component's own template.
Not parent's transclusion content.
加个inline-template,这样写my-component标签内部的内容不会替换组件内部的slot,而是当做my-component的模板渲染;
这样做除了造成混淆外,实际没啥卵用。x-template
对于html内容比较多的模板,你可以把模板定义在外面:
Vue.component('hello-world', { template: '#hello-world-template'})复制代码
静态组件
对于完全不需要数据绑定的组件,你可以在模板内部使用v-once,这样可以生成缓存,节约不少性能;
Vue.component('terms-of-service', { template: '\\\ '})复制代码Terms of Service
\ ... a lot of static content ...\