dVue.js是类似于angular.js的一套构建用户界面的渐进式框架,只关注视图层, 采用自底向上增量开发的设计。
Vue.js的代码需要放置在指定的HTML元素后面。
关于Vue的数据绑定:
例子:
<div id="app"> {{a}} </div> new Vue({ el:"#app", //使用选择器找到绑定数据的模块 data:{ a:"hello world" //数据内容 } })
防止刷新看到花括号的方法:在父元素添加v-cloak 是一个样式,添加后在CSS里定义
[v-cloak]{ Display:none; } <span>{{msg}}</span> -> v-text {{{msg}}} -> v-html // 转义HTML文本
关于Vue的双向数据绑定:使用v-model
例子:
<div id="app"> {{a}} <input type="text" v-model="a"/> </div> new Vue({ el:"#app", data:{ a:"hello world" //数据内容 } })
如果不想页面上的数据随着输入值改变,可以加* 输入改变数据后,页面不会改变。数据只绑定一次 {{a*}} 页面加载的时候进行数据绑定,后面数据更改页面不变化
HTML转意输出 {{{msg}}} 在js中定义的HTML语法,会直接在页面生成
例子;
<div id="app"> {{a*}} <input type="text" v-model="a"/> </div>
关于Vue的事件绑定:使用v-on
后面跟各种事件:v-on:click/mouseout/mouseover/dblclick/mousedown.....
可以简写为 @click=""
例子:v-on:click="函数"
事件对象: $event 封装了的事件event 表示当前鼠标点击对象
@click="show($event)"
事件冒泡:
阻止冒泡: 在事件后面加上 .stop
ev.cancelBubble=true; 使用 $event 后定义在方法中
@click.stop推荐 @click.stop=“方法” 原生写法
默认行为(默认事件): 在事件后面加上 .prevent
阻止默认行为:
ev.preventDefault();
@contextmenu.prevent推荐
键盘事件:
@keydown 敲打键盘任意键触发(显示前) 后面可以直接.序号表示按某个键@keyup 敲打键盘任意键触发(显示后)
$event.keyCode 键盘触发事件对象,即该按键的序号在方法中传入事件对象
常用键:
回车
a). @keyup.13 // 13表示按键的键盘序号
b). @keyup.enter 推荐
上、下、左、右
@keyup/keydown.left
@keyup/keydown.right
@keyup/keydown.up
@keyup/keydown.down
.....
自定义键盘信息:
Vue.directive('on').keyCodes.ctrl=17; // ctrl 是按键名称
//声明某个按键的序号,即可以在后面使用@keydown /@keyup .按键名调用
关于Vue的事件绑定:使用v-bind
v-bind:src="" 后面跟各种属性,如src/class/style.....
简写: :src="url" 后面可以直接写data里的数据名称
Class后面带的可以是一个数组,也可以是一个对象,或者直接一个json文件
例子:
<strong :class="json">文字...</strong> <strong :class="[e,red]">文字...</strong> <strong :class="{red:true,blue:false}">文字...</strong>
关于Vue的列表输出:使用v-for
相当于angular的ng-repeat,不过不需要var
例子:
<ul> <li v-for="n in todos">{{n.text}}</li> </ul>
new Vue({ el:".app", data:{ todos:[ {text:"第一个数据"}, {text:"第二个数据"}, {text:"第三个数据"}, ] } })
$index :表示遍历的索引下标,默认从0开始
$key:表示遍历json数组时的key值
v-for="(k,v) in json" 这样的写法会在页面同时输出key值和value值
当数组数据有重复时,使用v-for会报错,需要添加track-by='$index/uid'
关于Vue的条件判断:使用v-if v-else 控制元素显示或者隐藏
例子:
<div v-if="true">为true时显示</div>
<div v-else>否则这个显示</div>
v-show:类似于v-if 不过隐藏时也会占据页面空间
v-on: 绑定一个事件,后面跟随触发类型
例子:
<button v-on:click="revr">Reverse Message</button> var app5 = new Vue({ el: '#app-5', methods: { revr: function () { this.message = this.message.split('').reverse().join('') //使用Vue内部的变量,需要使用this } } })
关于Vue的过滤器:跟angular一样也是使用 数据|格式
vue提供过滤器 : capitalizeuppercasecurrency....
数组数据配合使用的过滤器:
limitBy:限制几个 即数组遍历显示的时候限制显示几个,后面带两个参数
limitBy 取几个 从哪个下标开始 如:limitBy 2 3
filterBy:过滤数据,将包含某个数据的内容显示
filterBy 包含的内容 如:filterBy a
orderBy:排序,将数组内容排序显示,后面两个参数
1表示正序,-1表示倒序
orderBy 按照什么排序 1/-1 如: orderBy 'o'
例子:
{{data | uppercase}} //转化为大写 val in arr | limitBy 2 //只显示两个数据 val in arr | filterBy a //只显示包含数据a的内容 val in arr | orderBy 'o' //以o数据位置为标准进行排序显示
Vue.filter:自定义转化格式,,需要在js中使用Vue.filter定义,可以改变数据的格式、内容等
Vue.filter('name', function (value) { //定义格式转化名称name,传入参数值value
return value.split('').reverse().join('') //重新定义数据内容并return 返回
})
时间过滤器:
Vue.filter('date',function(input){ var oDate=new Date(input); return oDate.getFullYear()+'-'+(oDate.getMonth()+1)+'-'+oDate.getDate()+' '+oDate.getHours()+':'+oDate.getMinutes()+':'+oDate.getSeconds(); });
双向过滤器:使用在v-modul 绑定数据的过滤
Vue.filter('filterHtml',{ read:function(input){ //model-view return input.replace(/<[^<]+>/g,''); }, write:function(val){ //view -> model return val; } });
关于Vue的数据交互: 引入: vue-resource
引入vue-resource.js文件,使用this.$http
get方式:
获取一个普通文本数据:不需要传参数的时候
this.$http.get('aa.txt').then(function(res){ alert(res.data); },function(res){ alert(res.status); });
then() : 里面跟两个方法,第一个为请求成功,第二个为失败
res: 传入方法内,表示请求返回的数据
res.data:表示请求返回的数据内容
给服务发送数据:需要传参数的时候
this.$http.get(this.$root.api+'/Index/Staff/training',{params:{ //传递的参数必须为一个对象,使用params subject_field_id:1, //表示传参数过去,值为1 train_state:2 }}).then(function(res){ console.log(res.data); },function(res){ alert(res.status); });
get():请求方式括号内带一个对象,对象内容为传过去的参数
post方式:在请求方式括号内增加一个对象 { emulateJSON:true }
this.$http.post('post.php',{ a:1, b:20 },{ emulateJSON:true }).then(function(res){ alert(res.data); },function(res){ alert(res.status); });
jsonp方式:跨域请求,请求地址为外域网站
https://sug.so.360.cn/suggest?callback=suggest_so&word=a
https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&cb=jshow
this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',{ wd:'a' //传过去的参数 },{ jsonp:'cb' //更改callback名字,默认名字就是"callback" }).then(function(res){ alert(res.data.s); },function(res){ alert(res.status); });
第四种方式:默认是get提交
this.$http({ url:地址 data:给后台提交数据, method:'get'/post/jsonp 提交方式 jsonp:'cb' //cbName 如果是jsonp提交方式,声明名称 });
关于Vue的生命周期:vue内部执行过程
new Vue({})声明了一个对象,也叫钩子函数
Vue内部会自己经历四个阶段:可以在后面跟方法
created: 当new Vue执行后,即实例已经创建时执行
beforeCompile:当开始编译HTML页面所有的Vue语法之前执行
compiled: 当编译HTML页面所有的Vue语法结束之后执行
ready: 当编译结束后把所有元素挂到Dom树,即插入到文档中后执行
Vue可以通过new声明创建,也可以进行销毁,使用$destroy
销毁后会经历两个阶段:
beforeDestroy: 销毁之前
destroyed: 销毁之后
例子:
var vm=new Vue({ }); document.onclick=function(){ vm.$destroy(); /*点击页面销毁vue对象* };
关于Vue的计算属性:类似data数据
同样是一个数据,不过后面跟的是function的写法,放置逻辑代码,使用return返回值,没有使用return返回值,则该数据为空
一般情况下,只使用get返回的数据,无法在后期通过其他办法更改值
* computed里面可以放置一些业务逻辑代码,一定记得return
有两种写法:
computed:{ b:function(){ //默认调用get return 值 } }
完整写法:
computed:{ b:{ get:function(){ return this.a+2; }, set:function(val){ //必须传入一个值 this.a=val; } } }
监听数据变化 : vm.$watch 监听某个数据,发生改变时执行方法
vm.$watch(name,function); //name表示监视的数据名称,后面带方法
vm.$watch(name,fnCb,{deep:true}); //深度监视 ,监视对象是数组
关于Vue的实例简单方法:
因为var vm=new Vue({})等于实例化一个对象,所以可以通过 . 访问它的各个值
vm.$el-> 就是元素,可以直接获取el后面选择器的整个元素内容
vm.$data -> 就是data,获取data里的所有数据,返回数组
vm.$destroy-> 销毁对象
vm.$log();-> 查看现在数据的状态,即在控制台输出所有数据
vm.$mount -> 手动挂在vue程序,当没有声明el:”控制器”时使用
例子:
var vm=new Vue({ data:{ a:1, b:2 } }).$mount('#box');
vm.$options-> 获取自定义属性,即定义的各个数据或方法写在外部
例子:
var vm=new Vue({ aa:11, //自定义属性, show:function(){ alert(1); }, data:{ a:1 } }).$mount('#box'); vm.$options.show(); console.log(vm.$options.aa);
关于Vue的自定义指令:Vue.directive
类似v-text v-for v-html 都称为Vue的指令,即扩展的html语法
可以通过Vue.directive自定义这些指令
Vue.directive('red',function(a){ //red为自定义的指令的名称 this.el.style.backgrund='red'; //this.el指使用该指令的元素 }); <span v-red> 内容 </span> //指令名称为red,这里需要使用v-
指令后面可以带参数,例如 v-text=“a”
a相当于在自定义的function传入的参数
自定义元素指令:(用处不大) Vue.elementDirective
Vue.elementDirective('zns-red',{ //自定义HTML标签zns-red bind:function(){ this.el.style.background='red'; //定义该标签作用 } }); <zns-red></zns-red>
关于Vue的动画:引入animate.css
最基本的动画:
//给需要添加动画的元素添加transition="名称"
例子:
<div id="div1" v-show="bSign" transition="fade"></div> //在css样式里面进行定义 <style> .fade-transition{ transition : 1s all ease; } //定义动画时间 .fade-enter{ opacity: 0; } //进入的动画 .fade-leave{ opacity: 0; transform: translateX(200px); } //离开的动画 </style>
推荐使用的动画:引入animate.css
animate.css是一个css动画库,可以在百度上直接下载,在页面引入
//给需要添加动画的元素添加transition="名称" class=”animated”
例子:
<div id="div1" class="animated" v-show="bSign" transition="bounce"></div>
//在new Vue里面声明transitions对象并定义动画
new Vue({ el:'#box', transitions:{ bounce:{ //动画的名称 enterClass:'zoomInLeft', //进入时使用的动画的class,参考animate.css书册 leaveClass:'zoomOutRight' //离开时使用的动画的class } } });
关于Vue的组件:Vue.extend Vue.component
vue组件:其实就是一个大的对象,例如new Vue就是一个组件
1. 全局组件 Vue.component定义在外部为全局组件
两种书写方式:
*组件里面放数据 : data必须是函数的形式,函数必须返回一个对象(json);事件不变
<div id="box"> <aaa></aaa> </div> //自定义的HTML标签 <script> var Aaa=Vue.extend({ // 赋值给变量Aaa data(){ return { //组件内部的数据以对象的形式,需要return返回 msg:'ddddd' //定义数据 } } template:'<h3>{{msg}}</h3>' //使用Vue.extend定义一个模版, }); Vue.component('aaa',Aaa); //使用Vue.component将aaa绑定到Aaa //Vue.component定义在外部为全局组件 绑定后页面使用<aaa></aaa>相当于<h3>我是标题3</h3> var vm=new Vue({ el:'#box', data:{ bSign:true } }); </script>
第二种书写方式:
Vue.component('my-aaa',{ //绑定 template:'<strong>好</strong>' //定义模版 }); var vm=new Vue({ el:'#box' });
2. 局部组件 Vue.component定义在某个组件为局部组件
var Aaa=Vue.extend({ // 赋值给变量Aaa data(){ return { //组件内部的数据以对象的形式,需要return返回 msg:'ddddd' //定义数据 } } template:'<h3>{{msg}}</h3>' //使用Vue.extend定义一个模版, }); var vm=new Vue({ el:'#box', components:{ //在new Vue里面将aaa绑定到Aaa,为局部组件 “aaa” : Aaa } });
第二种书写方式:
var vm=new Vue({ el:'#box', components:{ 'my-aaa':{ //自定义的标签,<my-aaa></my-aaa> data(){ return { msg:'welcome vue' } }, methods:{ change(){ this.msg='changed'; } }, template:'<h2 @click="change">标题2->{{msg}}</h2>' } //定义模版 } });
配合模版:定义的模版比较复杂时,可以在其他位置定义,
然后在template绑定id
两种书写方式:
第一种.
<script type="x-template" id="aaa"> <h2 @click="change">标题2->{{msg}}</h2> </script>
第二种.
<template id="aaa"> <h1>标题1</h1> <ul><li v-for="val in arr">{{val} }</li> </ul> </template>
动态组件:可以通过js动态更改页面上的组件模版
<component :is="组件名称"></component> <component :is="a"></component> <script> var vm=new Vue({ el:'#box', data:{ a:'aaa' }, components:{ 'aaa':{ template:'<h2>我是aaa组件</h2>' }, //定义模版 'bbb':{ template:'<h2>我是bbb组件</h2>' } } }); </script>
组件的嵌套:组件里面可以嵌套另一个组件
var vm=new Vue({ el:'#box', components:{ //父级组件 'aaa':{ template:'<h2>我是aaa组件</h2><bbb></bbb>', //子级组件定义的标签在父级模版使用 components:{ //子级组件 'bbb':{ template:'<h3>我是bbb组件</h3>' } } } } });
组件之间的数据交互:
子组件获取父组件的数据:props
:mmm.sync表示同步数据,即子组件数据改变,父组件数据也改变
<template id="aaa"> //父组件的模版 <h1>11111</h1> <bbb :mmm="msg2"></bbb> //子组件的内容,msg2为父组件的数据,绑 </template> 定到自定义的名称上
components:{ //这个为子组件 'bbb':{ props:['mmm'], //使用props 自定义名称 mmm template:'<h3>我是bbb组件->{{mmm}}</h3>' //使用自定义的名称 }
父组件获取子组件的数据:vm.$emit(事件名,数据);
需要子组件自己触发事件发射数据
<template id="aaa"> <span>我是父级 -> {{msg}}</span> <bbb @child-msg="get"></bbb> //使用定义的事件名,触发父组件的方法 </template> <template id="bbb"> <h3>子组件-</h3> <input type="button" value="send" @click="send"> //触发事件发射数据 </template>
methods:{ get(msg){ this.msg=msg;} //父组件的方法,接收子组件发射的数据 methods:{ send(){ this.$emit('child-msg',this.a); } //子级组件内的一个方法,使用$emit } // child-msg为事件名,this.a为子组件的数据
<slot></slot> : 保留组件模版内原本的HTML文本
组件内部的HTML文本默认会被定义的模版内容覆盖,使用slot可以保留原本的HTML文本,当需要多个slot分别代表多个HTML文本时,可以设置slot值和name值一致
例子:
<ul slot="ul-slot"></ul> <slot name="ul-slot"></slot>
关于Vue的路由跳转:<router-view></router-view>
需要在页面引入vue-router文件,然后在自定义的js文件中配置路由
例子:
<div id="app"> <p> <!-- 使用 router-link 组件来导航. --> <!-- 通过传入 `to` 属性指定链接. --> <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 --> <router-link to="/foo">Go to Foo</router-link> <router-link to="/bar">Go to Bar</router-link> </p> <!-- 路由匹配到的组件将渲染在这里 --> <router-view></router-view> </div>
<script> const Foo = { template: '<div>foo</div>' } // 定义(路由)组件并编写HTML内容 const Bar = { template: '<div>bar</div>' } // 可以从其他文件 import 进来 // 2. 定义路由 const routes = [ { path: '/foo', component: Foo }, //定义路由的名称,以及路由跳转的位置 { path: '/bar', component: Bar } ] // 3. 创建 router 实例,然后传 `routes` 配置 const router = new VueRouter({ routes // (缩写)相当于 routes: routes,后面也可以跟一个对象数组 }) // 4. 创建和挂载根实例。页面的data数据内容以及methods方法在这里面编写 const app = new Vue({ router }).$mount('#app') </script>
关于Vue使用了脚手架后自动创建环境的路由跳转:
Vue.js提供了自己的脚手架vue-cli,用于自动生成vue.js模板工程。即使用该脚手架会自动安装好webpack打包需要的所有模块等等。安装vue-cli之前,需要先安装了vue和webpack。
安装vue-cli步骤:在命令行输入以下指令
npm install -g vue-cli //全局安装vue-cli
vue init webpack projectName //生成项目名为projectName的模板,这里的项目名可以自定义
cd projectName //打开模板
npm install //初始化安装依赖
npm run dev //运行项目 可自动打开项目并实时更新
npm run build //执行发布打包 为代码编写完成后的最后步骤
代码编写:
初始化安装依赖后项目目录如下:
Index.html文件为总页面。需要从外部引入的css等文件在这里引入
打开src文件夹,
Components文件夹内的各个vue文件为各个单页面,各单页面在这个文件夹里面编写,样式和js代码全部写在一起。
//HTML代码编写在<template>标签的div内,必须使用一个div作为父容器
//js代码编写在<script>标签的export default 对象里面,data数据需要return到外部才可以使用,事件对象还是写在methods对象里面
//该页面的样式全部写在<style>标签里面
例子:
<template> <div id="app"> <router-link to="/bar">Go to Bar</router-link> <router-link to="/">Go to main</router-link> </div> </template>
<script> export default { name: 'app', data () { return { todos:[ {text:"sddfsdf"}, {text:"dsf"}, {text:"sdfsdf"}, ], message:"IS my work" } }, methods:{ revr: function () { this.message = this.message.split('').reverse().join('') } } } </script>
<style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; } </style>
Router文件内有一个index.js文件,里面编写的是该项目的路由
使用import从外部引入各个单页面文件(vue文件),不需要加vue后缀
在routes对象数组内设置路由,每个路由为一个对象
例子:
import Vue from 'vue' import Router from 'vue-router' import Hello from 'components/Hello' import Foo from 'components/Foo' //引入单页面文件 import Bar from 'components/Bar' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Hello', component: Hello, }, { path: '/foo', name: 'Foo', component: Foo }, { //配置路由 path: '/bar', //路由的链接 name: 'Bar', component: Bar //路由的名称 } ] })
App.vue文件为页面默认跳转页面。可以根据情况修改内容
关于如何在vue-cli里面配置默认路径的简写方式:
在build文件夹中的webpack.base.conf.js中,alias里进行相关配置
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
'base': path.resolve(__dirname, '../src/sass/base/_base.scss')
}
},
集成vue+ts 开发环境配置
1.完成vue-cli 下载后,安装TypeScript相关依赖和项目其余依赖
# npm install typescript ts-loader --save-dev
# npm install
安装官方插件vue-class-component,vue-property-decorator
npm install vue-class-component,vue-property-decorator --save-dev
2.修改目录下bulid/webpack.base.conf.js
文件,在文件内module>rules
添加以下规则
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/],
}
},
修改入口文件
entry: {
app: './src/main.ts'
}
resolve部分
extensions: ['.js', '.vue', '.json', '.ts', '.tsx']
3.在src目录下新建一个文件vue-shims.d.ts
,用于识别单文件vue内的ts代码
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
4.在项目根目录下建立TypeScript配置文件tsconfig.json
{
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
],
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"allowJs": true,
"module": "es2015",
"target": "es5",
"moduleResolution": "node",
"experimentalDecorators": true,
"isolatedModules": true,
"lib": [
"dom",
"es5",
"es2015.promise"
],
"sourceMap": true,
"pretty": true
}
}
5.重命名src下的main.js
为main.ts, .vue文件的<script>改为 <script lang="ts">
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
import { Watch } from 'vue-property-decorator'
@Component
export default class Hello extends Vue {
msg: string = 'this is a type' get productIdsString() {
const arr = [1,2,3,4]
return arr.join('_')
} @Watch('msg')
onSidChange() {
this.tets()
} tets() {
alert('dsdsd')
} cheng() {
this.msg = '45654654654'
}
}
</script>
如何将vue文件中的css 和 js 分离
1. js中引入 Component 和vue文件
import { Watch, Component } from 'vue-property-decorator'
2.在 Component中声明引入的vue文件
@Component({
mixins: [Template],
})
3 路由引入直接指定到目录即可
import HelloWorld from '@/components/Hello'