赞
踩
趁team leader的安排,在团队内部进行一次技术分享的机会。整理下这半年用的比较多的Vue.js内容,从开发使用层面上做一个简单的总结和入门,开两个专题:Vue组件和Vue Router。
打开pycharm后,file–>new–>project.按照下图一路next到底。
个人理解,Vue中的组件技术类似于后端开发中常用的一些工具类或方法,如果一个方法或功能在多个地方要用到,我们就需要将其进行抽离出来,在Vue中,组件就是一种很好的复用一个功能的手段。比如页面上的按钮、输入框等都可以以组件的形态存在,以供多个页面去复用使用。
下面,本文档将以组件的使用流程为主线进行简单的梳理和总结。
创建组件放在后面讲,先看下注册组件。首先假设存在一个已经开发好的组件M(可能是个人开发的,也可能是别人开发的,亦可能是通过npm install安装的第三方库的组件),在我们的项目中如何去注册。
组件注册主要分**全局注册和局部注册**。
全局组件通常使用 Vue.component(tagName, {options})的格式注册;
局部组件则在实例中的components中注册。
注意:
要确保在初始化根实例之前注册了组件,即:先注册组件,再初始化Vue实例;
建议将组件提取出来放在单独js文件中,按需引用。
如果页面A上使用某个组件M,统一称呼的口径,全文约束调用方页面A为父组件,被调用方组件M称之为子组件。
组件使用和开发的核心就是父子组件的数据传递(通信)问题,按照数据传递方向可分为三类:
4.1 父–>子组件 props:
<template> <div> <p>我是子组件,父组件通过props传递过来的值是</p> {{postTitle}} </div> </template> <script> export default { name: 'parent-child', // props: ['postTitle'], props: { 'postTitle': String } } </script> <style scoped> </style>
注意:
1.子组件中的驼峰命名的 prop 名在父组件赋值的时候需要使用其等价的短横线分隔命名;
2.props如果不加类型校验则是一个数组;若加上类型校验则是一个对象。
4.2 子–>父组件 :$emit()
props里面的属性字段值是单向的,只能是父组件传递给子组件,如果在子组件对其进行修改父组件是无感知的。子组件如果想跟父组件进行反馈,通过在子组件利用emit()定义一个事件回调函数。
<template> <div> <button v-on:click="btnClickEvent"> 子组件的按钮 </button> </div> </template> <script> export default { name: 'child-parent', methods: { // 在子组件内部通过emit定义btn-click事件,在父组件中去监听btn-click事件并实现对其的响应 btnClickEvent: function () { this.$emit('btn-click') } } } </script> <style scoped> </style> ------------------- 分割线: 以下是调用上面子组件的父组件 --------------------- <!-- 子组件通过emit注册的事件回调父组件的事件响应函数 --> <template> <div> <!-- 监听子组件预定义的btn-click事件 --> <child-parent @btn-click="callback_fn"></child-parent> </div> </template> <script> import childParent from '@/components/child-parent' export default { name: 'emit', methods: { callback_fn () { alert('父组件预定义的供子组件回调的函数 ==> (由子组件触发)') } }, components: { childParent } } </script> <style scoped> </style>
小结:Props 向下传递数据,事件向上传递数据。
在标准组件和自定义组件上分别使用v-model
1.在标准组件上使用v-model
<!-- 在标准组件input上使用v-model实现变量的双向绑定 -->
<div id="app">
<input :value="name" @input="name = $event.target.value" />
<input v-model="name" />
</div>
上面示例代码中的两行input标签效果是一样的,在标准组件上使用v-model 节约了不少代码,最重要的是可以少定义一个事件处理函数,所以 v-model 实际干的事包括:
2.在自定义组件上使用v-model
如同在标准组件上使用v-model一样,如果在自定义的子组件上利用v-model绑定某个值,就相当于子组件内部实现上的props里面有个value属性,同时还注册一个input事件,如下所示:
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
Vue.component('custom-input', {
props: ['value'],
template:
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
})
再看下面代码所示为父组件的一个例子,在该父组件中引用了子组件model-input,其中
<model-input :value="msg" @input="(res) => {this.msg = res}"></model-input>
这一行代码就说明在model-input子组件中必须得有一个接收value值的props和利用$emit注册一个input事件。
<!-- 父组件上使用v-model,子组件上使用model --> <template> <div> <!-- 在input标签上时 v-model == value + input --> <model-input :value="msg"></model-input> <model-input :value="msg" @input="(res) => {this.msg = res}"></model-input> <model-input v-model="msg"></model-input> <span>父组件:{{msg}}</span> <!-- model选项可以指定当前的事件类型和传入的props, 因此可以解决v-model默认只能是value + input --> <model-conponent value="type1" :checked="checked"></model-conponent> <model-conponent value="type2" :checked="checked" @change="change"></model-conponent> <model-conponent value="type3" v-model="checked"></model-conponent> <p>父组件中的当前选中状态: {{this.checked}}</p> </div> </template> <script> import modelConponent from '@/components/v-model' import modelInput from '@/components/model-input' export default { name: 'vModel', data () { return { msg: 'byteDance', checked: false } }, methods: { change (value) { console.log('父组件事件回调响应函数 ==>', value) this.checked = value } }, components: { modelConponent, modelInput } } </script> ---------------------------分割线,以下是子组件的代码---------------------------- <template> <div> <input ref="input" type="text" :value="value" @input="input"/> </div> </template> <script> export default { name: 'modelInput', // 利用model强制修改默认input事件为input-fn事件 // model: { // prop: 'value', // event: 'input-fn' // }, props: { value: String }, methods: { input () { console.log('子组件 == ', event.target.value) this.$emit('input', event.target.value) } } } </script>
可以在子组件中用model对v-model默认的value属性和input事件进行修改,上面示例代码中,子组件<model-conponent value="type1" :checked="checked"></model-conponent>
就是利用model改变默认的value和input为checked和change。
子组件上使用model的示例
4.3 子组件与子组件(兄弟组件)数据传递:vuex
个人理解,把各组件间用到的共享数据,抽离出到一个全局共享变量中,交由vuex进行集中管理。
1.将vuex引入到当前工程:
2.引入到工程中后,在工程组件中使用的步骤,详见store.js
除了以上内容外,下面在总结下组件的两个高级特性:slot和动态组件
slot(插槽)类似于props,也是父组件到子组件传递数据的一种方式,区别于props的子组件标签内属性数据传递,而slot是子组件标签之间的数据传递,可以传递像dom之类的template内容,也包括html和一些其他组件。
上述截图所示,如果子组件slot-child内部没有<slot></slot>
则父组件的
<span>我是从父组件传递到子组件的数据</span>
是无法展示的。以下是子组件代码:
<template> <div> 子组件Slot-Child: <br/> <button @click="update"> {{btnName}} </button> <br/> <!-- 如果注释掉下面的slot标签,则无法接受父组件内容 --> <slot></slot> </div> </template> <script> export default { name: 'slot-child', props: { btnName: String, default: '子组件按钮' }, methods: { update () { this.$emit('update', '子组件回调函数的入参') } } } </script>
动态组件:通过使用 <component>
标签,让多个组件可以使用同一个挂载点,并动态切换,<component :is="currentTabComponent" class="tab"></component>
根据 v-bind:is=“组件名” 中的组件名去自动匹配组件,显示相应的组件内容。
文章对应的项目源码
后续todo:
1.localstorage
2.vuex-persistedstate
3.vue-codemirror
4.函数内部函数的局部this
Vue学习资料
Webpack原理剖析:https://wx.kaikeba.com/presaledata/5?channel=0ebwxz
vue-router前端路由原理剖析:https://wx.kaikeba.com/presaledata/4?channel=pwvrgj
Vue源码解析:https://wx.kaikeba.com/presaledata/21?channel=fiqp7b
react组件化:https://wx.kaikeba.com/presaledata/22?channel=kw2iey
react原理剖析:https://wx.kaikeba.com/presaledata/23?channel=lfdb15
Koa2源码解读:https://wx.kaikeba.com/presaledata/3?channel=p1ina4
如何通过数据劫持实现vue框架:https://wx.kaikeba.com/presaledata/6?channel=3a2mxj
Web全栈Vue资料:https://pan.baidu.com/s/1e4rQqDf3Pn7ZRD276bsTnQ
提取码:cmws
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。