1. 什么是Vue?
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
2. 安装Vue
建立一个html文件,在head部分引用vue在线包(当然,您也可以下载下来使用)
开发环境包:
<!-- 开发环境版本,包含了用帮助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
生产环境包:
<!-- 生产环境版本,优化了尺寸和速度 --> <script src="https://cdn.jsdelivr.net/npm/vue"></script>
3. 入门
Vue就是通过实例化一个Vue对象,传入一个selector,一个控制器来实现各种UI渲染的。
3.1. 文本渲染
html
<span class="test"> {{ message }} </span>
script
var app = new Vue({ el: '.test', data: { message: '这是一段文本' } }); app.message = '新文本';
3.2. 绑定title
html
<span class="test"> <b v-bind:title="message">鼠标悬停几秒显示title信息</b> </span>
script
var app = new Vue({ el: '.test', data: { message: '这是title标题信息' } });
3.3. 条件控制
html
<span class="test"> <b v-if="seen">看到了吗?</b> </span>
script
var app = new Vue({ el: '.test', data: { seen:false } }); app.seen = true;
3.4. 循环
html
<span class="test"> <ul> <li v-for="item in arr"><b>{{ item.text }}</b></li> </ul> </span>
script
var app = new Vue({ el: '.test', data: { arr:[ {text:"A"}, {text:"B"}, {text:"C"} ] } }); app.arr.push({text:"D"});
3.5. 事件
html
<span class="test"> <a v-on:click="funName">{{ message }}</a> </span>
script
var app = new Vue({ el: '.test', data: { message : '请点击我' }, methods: { funName : function(){ this.message = '刚刚点击了我'; } } });
3.6. 表单项绑定
html
<span class="test"> <label>{{ selected }}</label> <select v-model="selected"> <option>无选择</option> <option value="A">A</option> <option value="B">B</option> <option value="C">C</option> </select> </span>
script
var app = new Vue({ el: '.test', data: { selected : 'C' } });
3.7. 组件
script(模板定义)
Vue.component('li-item', { props : ['item'], template: '<li>{{ item.text }}</li>' });
html
<span class="test"> <ol> <li-item v-for="li in olList" v-bind:item="li" v-bind:key="li.id"> </li-item> </ol> </span>
script
var app = new Vue({ el: '.test', data: { olList : [ {id:1, text:'A'}, {id:2, text:'B'}, {id:3, text:'C'} ] } });
4. 牛刀小试
4.1. 应用于表格
5. TFWEB的Vue
5.1. 命名规则
组件内部的信息类的属性,我们统一放到 info 这个集合里,例如:info : { title : 'title', desc : 'desc' ... }
组件内部的子组件,可以考虑使用独立的集合,例如:options : { ... } elements : { ... }
组件内部的插槽,可以考虑使用独立的集合
5.2. 属性绑定
属性名称不区分大小写,需要用“-”分隔,但是JSON数据的节点名称如果包含“-”又必须用引号括起来。将“-”替换成“_”是个不错的选择。
<my-component :isSpec="isSpec"></my-component> 这里的 isSpec 会被转移成 isspec,在接收的时候也必须用 props : { isspec : { } } 接收 <my-component :is-spec="isSpec"></my-component> 这里的 is-spec 包含“-”,在接收的时候必须加引号括起来 props : { 'is-spec' : { } } 接收 <my-component :is_spec="isSpec"></my-component> 这里的 is_spec 包含“_”,在接收的时候可直接 props : { is_spec : { } } 接收
5.3. 事件绑定
事件名称不区分大小写,需要用“-”分隔,但是JSON数据的节点名称如果包含“-”又必须用引号括起来。将“-”替换成“_”是个不错的选择。
<my-component @callSpec="callSpec"></my-component> 这里的 callSpec 会被转移成 callspec,对应的方法名称也应该是 callspec : function(){ } <my-component @call-spec="callSpec"></my-component> 这里的 call-spec 包含“-”,对应的方法名称也应该是 'call-spec' : function(){ } <my-component @call_spec="callSpec"></my-component> 这里的 is_spec 包含“_”,对应的方法名称也应该是 call_spec : function(){ }
5.4. 数据优先级
数据优先级由高到低为:组件调用传递 > 组件接收默认 > 组件内建
数据初始化优先级由高到低为:mounted > created > data
html
<div id="comp"><comp :a1="a1"></comp></div>
script
Vue.component('comp', { props : { a1 : { default : 'props' } }, data : function(){ return { a1 : 'data' } }, mounted : function(){ this.a1 = 'change on mounted'; }, created : function(){ this.a1 = 'change on created'; }, template : '<div>\{\{a1\}\}</div>' }); new Vue({ el : '#comp', data : { a1 : 'pass' } });
5.5. 组件事件
5.5.1. 子组件调用父组件方法
父组件通过在子组件上设置 @父组件方法="父组件方法" 传递方法给子组件, 子组件通过子组件方法里执行 this.$emit('父组件方法') 调用父组件方法
子组件
Vue.component('son', { methods : { call_fa_fun : function(){ this.$emit('fa_fun'); } } template : '<div>'+ ' <a @click="call_fa_fun">call fa fun</a>'+ '</div>' });
父组件
Vue.component('fa', { methods : { fa_fun : function(){ alert('call from son'); } } template : '<div>'+ ' <son @fa_fun="fa_fun"></son>'+ '</div>' });
html
<fa id="test"></fa>
javascript
new Vue({ el : '#test' });
5.5.2. 父组件调用子组件方法
子组件通过在自身设置 ref="子组件别名" 传递句柄给父组件, 父组件通过父组件方法里执行 this.$refs.子组件别名.子组件方法() 调用子组件方法
父组件
Vue.component('fa', { methods : { call_son_fun : function(){ this.$refs.son.son_fun(); } } template : '<div>'+ ' <son ref="son"></son>'+ ' <br />'+ ' <a @click="call_son_fun">call son fun</a>'+ '</div>' });
子组件
Vue.component('son', { methods : { son_fun : function(){ alert('call from fa'); } } template : '<div>son</div>' });
html
<fa id="test"></fa>
javascript
new Vue({ el : '#test' });
5.5.3. 子组件之间相互调用方法
声明一个事件调度 var VueEventCtrlr = new Vue() 用来传递事件, 子组件A通过 mounted 函数里定义自定义函数 VueEventCtrlr.$on('自定义函数', function(){ ... }) 给子组件B使用, 子组件B通过 VueEventCtrlr.$emit('自定义函数', ...) 调用自定义函数
调度
var VueEventCtrlr = new Vue();
子组件A
Vue.component('a_com', { data : function(){ return { msg : '' } }, methods : { call_b_fun : function(){ VueEventCtrlr.$emit('b_fun', this.msg); } }, template : '<div>'+ '输入:<input type="text" @keyup="call_b_fun" v-model="msg" />'+ '</div>' });
子组件B
Vue.component('b_com', { data : function(){ return { msg : '' } }, mounted : function(){ var ex = this; VueEventCtrlr.$on('b_fun', function(d){ ex.msg = d; }); }, template : '<div>打印:{{msg}}</div>' });
html
<div id="test"> <a_com></a_com> <b_com></b_com> </div>
javascript
new Vue({ el : '#test' });
5.6. 插槽
5.6.1. 规范
插槽使用 <slot name="xxx"></slot> 定义
插槽传值可以用 <template slot="xxx"></template>,也可以用 <div slot="xxx"></div> 这样的普通html标签
插槽不能跨级传递,也就是说“爷”组件只能向“子”组件传 slot 值,不能向“孙”组件传 slot 值