-
-
vue
vue简介
-
什么是vue
- 一套用于构建用户界面的渐进式JavaScript框架
- 特点
- 关注视图层
- 易于上手
- 便于与第三方库或既有项目整合
- 我们要把一个 json对象的数据,显示到一个元素上去。可以怎样做
- 用到 JS 或者 JQuery,通过操作 HTML DOM 的方式,把数据显示上去。
- 使用Vue, 那么仅仅需要提供数据,以及数据要绑定到的元素的id,就行了,不需要显式地操作HTML DOM。
-
js的方式
-
通过id操作html dom 显示数据
<div id="div1"> </div> <script> //准备数据 var gareen = {"name":"盖伦","hp":616}; //获取 html dom var div1 = document.getElementById("div1"); //显示数据 div1.innerHTML= gareen.name; </script>
-
-
js方式的问题
- html dom其实只是手段,我们真正想要的,就是数据,显示在元素上。
-
VUE的方式
-
创建html导入vue.js cdn
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
-
创建div,id为divl
<div id="divl"> <!-- 取出数据 --> {{hero.name}} </div>
-
编写js
<script> //准备数据 var hero={"name":"vue"}; //通过vue.js 把数据和对应的视图关联起来 new Vue({ el:'#divl', data: { message: hero } }) </script>
事件监听
-
v-on
-
在js里为Vue对象的数据为clickNumber
-
新建一个方法count
-
在按钮上增加click监听,调用count方法
-
<div id="divl"> <!-- 取出数据 --> <div>一共点击 {{clickNumber}}</div> //v-on:click可替换为@click <button type="button" v-on:click="count">点击</button> </div> <script> new Vue({ el:"#divl", data: { clickNumber: 0 }, methods: { // 方法 count: function(){ this.clickNumber++; } } }) </script>
-
-
事件修饰符
-
阻止冒泡 .stop
-
事件修饰符 优先触发 .capture
-
事件修饰符 只有自己能触发,子元素无法触发.self
-
事件修饰符 只能提交一次 .once
-
事件修饰符 阻止提交 .prevent
- 只有超链和form这种会导致页面刷新的操作,.prevent 才有用。 普通的不导致页面刷新的按钮,加上这个没有任何变化。
-
<div id="content"> <div id="grandFather" v-on:click="doc"> grandFather <div id="father" v-on:click="doc"> father <div id="me" v-on:click="doc"> me <div id="son" v-on:click.capture="doc"> son </div> </div> </div> </div> </div> <script> var content = new Vue({ el: "#content", data: { id: '' }, methods: { doc: function () { this.id= event.currentTarget.id; alert(this.id) } } }) </script>
-
条件判断
-
v-if
-
v-else
-
v-else-if
<div id="div"> <button @click="toggle">切换隐藏</button> <div v-if="show==0">看见</div> <div v-else-if="show==1">看不见</div> <div v-else>你瞎啦</div> </div> <script> new Vue({ el:"#div", data: { show:0 }, methods: { toggle: function(){ this.show=!this.show this.show++ } } })
循环
-
for数据json
-
<table id="div1"> <tr> <td>id</td> <td>名字</td> <td>血量</td> </tr> 注意index的使用 <tr v-for="hero,index in heros"> <td>{{index++}}</td> <td>{{hero.name}}</td> <td>{{hero.hp}}</td> </tr> </table> <script> var data = [ {name:"盖伦",hp:341}, {name:"提莫",hp:225}, {name:"安妮",hp:427}, {name:"死歌",hp:893} ]; new Vue({ el:'#div1', data: { heros: data } }) </script>
-
for数值
-
<div id="dd"> <div v-for="i in 10"> {{i}} </div> </div> <script> new Vue({ el:'#dd' }) </script>
-
-
属性绑定
-
v-bind属性绑定
<div id="d"> <a v-bind:href="page">aaaa</a> </div> <script> new Vue({ el:'#d', data: { page: 'http://www.baidu.com' } }) </script>
-
v-bind:href简写为:href
<div id="d"> <a :href="page">aaaa</a> </div> <script> new Vue({ el:'#d', data: { page: 'http://www.baidu.com' } }) </script>
双向绑定
-
v-model
-
视图上的数据放到Vue对象上去呢?
这时就需要用到v-model进行双向绑定
像这样,当input里面的值发生变化的时候,就会自动把变化后的值,绑定到Vue对象上去了 -
<div id="d"> hero name: <input v-model="name" /> <button @click="onClick">提交数据</button> </div> <script> new Vue({ el:'#d', data: { name: "teemo" }, methods: { onClick: function(){ alert(this.name); } } }) </script>
-
修饰符
- .lazy:加上.lazy之后,相当于监听change操作,只有在失去焦点的时候,才会进行数据绑定了
- .number:把类型转换为number类型,而v-model默认是string类型
- .trim:trim 去掉前后的空白
-
计算属性
-
compute
-
<table id="divl"> <tr> <tr>美元</tr> <tr>人民币</tr> </tr> <tr> <td align="center"> 汇率:<input type="number" v-model.number="exchange"> </td> <tr>人民币</tr> </tr> <tr> <td align="center"> ¥:<input type="number" v-model.number="rmb"> </td> <td align="center"> $:{{dollar}} </td> <tr>人民币</tr> </tr> </table> <script> new Vue({ el:"#divl", data: { exchange:6.4, rmb:0 }, computed: { dollar: function(){ return this.rmb/this.exchange } } }) </script>
-
-
methonds
-
<table id="divl"> <tr> <tr>美元</tr> <tr>人民币</tr> </tr> <tr> <td align="center"> 汇率:<input type="number" v-model.number="exchange"> </td> <tr>人民币</tr> </tr> <tr> <td align="center"> ¥:<input type="number" v-model.number="rmb"> </td> <td align="center"> <!-- compute调用不需要加() --> $:{{getdollar()}} </td> <tr>人民币</tr> </tr> </table> <script> new Vue({ el:"#divl", data: { exchange:6.4, rmb:0 }, methods: { getdollar: function(){ return this.rmb/this.exchange } } }) </script>
-
-
computed和methods的区别
- computed是有缓存的,只要rnb没有变化,dollar会直接返回以前计算出来的值,而不会再次计算。这样就可以节约不少的时间
- 而methods每次都会调用
-
watch
-
vue可以通过watch来监听属性值的变化。
<table id="divl"> <tr> <tr>美元</tr> <tr>人民币</tr> </tr> <tr> <td align="center"> 汇率:<input type="number" v-model.number="exchange"> </td> </tr> <tr> <td align="center"> ¥:<input type="number" v-model.number="rmb"> </td> <td align="center"> $:<input type="number" v-model.number="dollar)"> </td> </tr> </table> <script> new Vue({ el:"#divl", data: { exchange: 6.4, rmb: 0, dollar: 0 }, watch:{ rmb:function(val){ this.rmb=val; this.dollar=this.rmb / this.exchange; }, dollar:function(val){ this.dollar=val; this.rmb=this.dollar * this.exchange; } } }) </script>
-
过滤器
-
一个过滤器
-
<div id="div1"> <table align="center" > <tr class="firstLine"> <td>输入数据</td> <td>过滤后的结果</td> </tr> <tr> <td align="center"> <input v-model= "data" /> </td> <td align="center"> {{data|capitalize}} </td> </tr> </table> </div> <script type="text/javascript"> new Vue({ el:'#div1', data: { data:'' }, filters:{ capitalize:function(value){ if(!value) return '' value=value.toString() return value.charAt(0).toUpperCase()+value.substring(1) } } }) </script>
-
定义一个 首字母大写 过滤器
filters:{ capitalize:function(value){ if(!value) return '' value=value.toString() return value.charAt(0).toUpperCase()+value.substring(1) } }
-
-
然后在视图里如下方式使用: {{ data|capitalize }}
-
多个过滤器
-
定义两个过滤器,分别是首字母大写和尾字母大写
然后通过如下方式同时首字母大小写<div id="div1"> <table align="center" > <tr class="firstLine"> <td>输入数据</td> <td>过滤后的结果</td> </tr> <tr> <td align="center"> <input v-model= "data" /> </td> <td align="center"> {{data|capitalize|capitalizeLastLetter}} </td> </tr> </table> </div> <script type="text/javascript"> new Vue({ el:'#div1', data: { data:'' }, filters:{ capitalize:function(value){ if(!value) return '' value=value.toString() return value.charAt(0).toUpperCase()+value.substring(1) }, capitalizeLastLetter:function(value) { if (!value) return '' //如果为空,则返回空字符串 value = value.toString() return value.substring(0,value.length-1)+ value.charAt(value.length-1).toUpperCase() } } }) </script>
-
-
全局过滤器
-
过滤器是定义在Vue对象里的。 但是有时候,很多不同的页面都会用到相同的过滤器,如果每个Vue对象里都重复开发相同的过滤器,不仅开发量增加,维护负担也增加了。
所以就可以通过全局过滤器的方式,只定义一次过滤器,然后就可以在不同的Vue对象里使用了。<div id="div1"> <table align="center" > <tr class="firstLine"> <td>输入数据</td> <td>过滤后的结果</td> </tr> <tr> <td align="center"> <input v-model= "data" /> </td> <td align="center"> {{ data|capitalize|capitalizeLastLetter }} </td> </tr> </table> </div> <script> Vue.filter('capitalize', function (value) { if (!value) return '' value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) }) Vue.filter('capitalizeLastLetter', function (value) { if (!value) return '' //如果为空,则返回空字符串 value = value.toString() return value.substring(0,value.length-1)+ value.charAt(value.length-1).toUpperCase() }) new Vue({ el: '#div1', data: { data:'' } }) </script>
-
组件
-
组件是什么
- 其实组件就是一个模板,通过传递不同参数就可看到不同的样子
- 关键字:components
-
局部组件
-
在Vue对象里增加components:
-
在视图里调用
<div id="divl"> <product></product> <product></product> <product></product> </div> <script> new Vue({ el:'#divl', components: { 'product':{ template:'<div class="product">MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮</div>' } } }) </script>
-
-
全局组件
-
有的组件会在不同页面使用,这个时候就可以考虑用全局组件。
<div id="divl"> <product></product> <product></product> <product></product> </div> <script> Vue.component('product',{ template:'<div class="product">MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮</div>' }) new Vue({ el:'#divl' }) </script>
-
-
参数
-
传递参数关键字
-
props:[“参数名”]
-
使用方法:<组件名 参数名=参数>
<div id="divl"> <product name="设置参数name, 并且在组件里使用这个name"></product> <product name="参数name, 并且在组件里使用这个name"></product> <product name="设置参数name, 并且在组件里使用这个name"></product> </div> <script> Vue.component('product',{ props:['name'],//传递参数 template:'<div class="product">{{name}}</div>' }) new Vue({ el:'#divl' }) </script>
-
-
动态参数
-
动态参数,就是指组件内的参数可以和组件外的值关联起来
<div id="div1"> 组件外的值:<input v-model="outname" /><br/> <product v-bind:name="outname"></product> </div> <script> Vue.component('product',{ props:['name'], template:'<div class="product">{{name}}</div>' }) new Vue({ el:'#div1', data: { outname:'产品名称' } }) </script>
-
-
6. 自定义事件 1. 增加自定义事件和在一个Vue对象上增加 methods 是一样的做法 2. 这里是在组件上增加的,而不是在视图上增加的。 3. ````html <div id="div1"> <product name="苹果" sale="10"></product> <product name="诚挚" sale="10"></product> <product name="梨" sale="10"></product> </div> <script> Vue.component('product',{ props:['name','sale'], // v-on:click不可简化 template:'<div class="product" v-on:click="increaseSale">{{name}}销量:{{sale}}</div>', methods:{ increaseSale:function(){ this.sale++ } } }) new Vue({ el:'#div1' }) </script> ```` 7. 遍历json数组 1. ````html <div id="divl"> <product v-for="item in products" v-bind:product="item"></product> </div> <script type="text/javascript"> Vue.component('product',{ props:['product'], template:'<div class="product" v-on:click="increaseSale">{{product.name}} 销量: {{product.sale}}</div>', methods:{ increaseSale:function(){ this.product.sale++ } } }) new Vue({ el:'#divl', data:{ products:[ {"name":"MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮","sale":"18"}, {"name":"MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮","sale":"18"}, {"name":"MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮","sale":"18"}, {"name":"MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮","sale":"18"} ] } }) </script> ```` 8. 案例 1. ```html <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script> <style> div.product{ float:left; border:1px solid lightGray; width:200px; margin:10px; cursor: pointer; } div.product:hover{ border:1px solid #c40000; } div.price{ color:#c40000; font-weight:bold; font-size:1.2em; margin:10px; } div.productName{ color:gray; font-size:0.8em; margin:10px; } div.sale{ float:left; width:100px; border:1px solid lightgray; border-width:1px 0px 0px 0px; color:gray; font-size:0.8em; padding-left:10px; } div.review{ overflow:hidden; border:1px solid lightgray; border-width:1px 0px 0px 1px; color:gray; font-size:0.8em; padding-left:10px; } </style> </head> <body> <div id="tempalate" style="display:none"> <div class="product" v-on:click="increaseSales"> <div class="price"> ¥ {{product.price}} </div> <div class="productName"> {{product.name}} </div> <div class="sale"> 月成交 {{product.sale}} 笔</div> <div class="review"> 评价 {{product.review}} </div> </div> </div> <div id="div1"> <product v-for="item in products" v-bind:product="item"></product> </div> <script> var tempalateDiv=document.getElementById("tempalate").innerHTML; var templateObject = { props: ['product'], template: tempalateDiv, methods: { increaseSales: function () { this.product.sale = parseInt(this.product.sale); this.product.sale += 1 // this.$emit('increment'),传值给指定的函数,这里面没有写increment函数没有影响 this.$emit('increment') } } } Vue.component('product', templateObject) new Vue({ el: '#div1', data:{ products:[ {"name":"MAXFEEL休闲男士手包真皮手拿包大容量信封包手抓包夹包软韩版潮","price":"889","sale":"18","review":"5"}, {"name":"宾度 男士手包真皮大容量手拿包牛皮个性潮男包手抓包软皮信封包","price":"322","sale":"35","review":"12"}, {"name":"唯美诺新款男士手包男包真皮大容量小羊皮手拿包信封包软皮夹包潮","price":"523","sale":"29","review":"3"}, ] } }) </script> ```
自定义指令
1. 例子 1. ```html <div id="divl"> <div v-xart>好好学习天天向上</div> </div> <script type="text/javascript"> Vue.directive('xart',function(el){ el.innerHTML=el.innerHTML+'(x-art)' el.style.color='pink' }) new Vue({ el:'#divl' }) </script> ``` 2. 自定义指令的方式: 2. 带参数的自定义指令 1. ```html <div id="divl"> <!-- 传参方式v-xart="blue" --> <div v-xart="{color:'red',text:'best learing'}">好好学习天天向上</div> </div> <script type="text/javascript"> Vue.directive('xart',function(el,binding){ el.innerHTML=el.innerHTML+'('+binding.value.text+')' el.style.color=binding.value.color }) new Vue({ el:'#divl' }) </script> ``` 3. 钩子函数 1. 回调函数或者事件响应函数。 指的是,一个指令在创建过程中,经历不同生命周期的时候,vue.js 框架调用的函数。 2. 常见事件 1. bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。 2. unbind:只调用一次,指令与元素解绑时调用。 3. update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。可以通过比较值来判断 ````html <div id="div1"> <div v-xart:hello.a.b="message"> </div> </div> <script> Vue.directive('xart', { bind: function (el, binding, vnode) { var s = JSON.stringify el.innerHTML = 'name: ' + s(binding.name) + '<br>' + 'value: ' + s(binding.value) + '<br>' + 'expression: ' + s(binding.expression) + '<br>' + 'argument: ' + s(binding.arg) + '<br>' + 'modifiers: ' + s(binding.modifiers) + '<br>' + 'vnode keys: ' + Object.keys(vnode).join(', ') }, update: function (newValue, oldValue) { // 值更新时的工作 // 也会以初始值为参数调用一次 }, unbind: function () { // 清理工作 // 例如,删除 bind() 添加的事件监听器 } }) new Vue({ el: '#div1', data:{ message:'hello vue.js' } }) </script> ```` 3. 结果 1. ````text name: "xart" value: "hello vue.js" expression: "message" argument: "hello" modifiers: {"a":true,"b":true} vnode keys: tag, data, children, text, elm, ns, context, fnContext, fnOptions, fnScopeId, key, componentOptions, componentInstance, parent, raw, isStatic, isRootInsert, isComment, isCloned, isOnce, asyncFactory, asyncMeta, isAsyncPlaceholder ````
路由
-
vue.js里的路由的概念
- vue.js里的路由相当于局部刷新
-
引入vue-router.min.js
-
<script src="//cdn.bootcss.com/vue-router/2.5.3/vue-router.min.js"></script>
-
-
路由的使用
-
<div id="app"> <div class="menu"> <!-- router-link 相当于就是超链 to 相当于就是 href --> <router-link to="/user">用户管理</router-link> <router-link to="/second">产品管理</router-link> <router-link to="/order">订单管理</router-link> </div> <div class="workingRoom"> <!-- 点击上面的/user,那么/user 对应的内容就会显示在router-view 这里 --> <router-view></router-view> </div> </div> <script type="text/javascript"> var user={ template: '<p>用户管理页面的内容</p>'} var second={ template: '<p>产品管理页面的内容</p>'} var order={ template: '<p>订单管理页面的内容</p>'} // 定义路由 var routes=[ { path: '/',redirect:'/user'},//这个表示默认渲染,没有这个就空白 {path :'/user',component: user }, {path : '/second' , component: second}, {path: '/order',component: order} ]; // 创建VueRouter实例 var router=new VueRouter({ routes:routes }); // 给vue对象绑定路由 new Vue({ el:"#app", router }) </script>
-
-
异步数据
-
数据
-
[ {"name":"gareen","hp":"355"}, {"name":"teemo","hp":"287"}, {"name":"annie","hp":"420"} ]
-
-
frtch.js
-
</head> <body> <div id="div1"> <table align="center" > <tr class="firstLine"> <td>name</td> <td>hp</td> </tr> <tr v-for="hero in heros"> <td>{{hero.name}}</td> <td>{{hero.hp}}</td> </tr> </table> </div> <script> var url = "https://static.how2j.cn/study/jsons.txt"; new Vue({ el:'#div1', data:{ heros:[] }, mounted:function(){ //mounted 表示这个 Vue 对象加载成功了 self=this fetch(url).then(function(response) { response.json().then(function (jsonObject) { self.heros = jsonObject }) }).catch(function(err){ console.log("Fetch错误:"+err); }) } }) </script> </body>
-
-
axios.js
-
<script src="https://how2j.cn/study/vue.min.js"></script> <script src="https://how2j.cn/study/axios.min.js"></script> <head> <style> table tr td{ border:1px solid gray; } table{ border-collapse:collapse; width:300px; } tr.firstLine{ background-color: lightGray; } </style> </head> <div id="div1"> <table align="center" > <tr class="firstLine"> <td>name</td> <td>hp</td> </tr> <tr v-for="hero in heros"> <td>{{hero.name}}</td> <td>{{hero.hp}}</td> </tr> </table> </div> <script> var url = "http://how2j.cn/study/jsons.txt"; new Vue({ el:'#div1', data:{ heros:[] }, mounted:function(){ //mounted 表示这个 Vue 对象加载成功了 var self = this axios.get(url).then(function(response) { self.heros= response.data; //此时还是字符串 self.heros = eval("("+self.heros+")"); //字符串转换为数组对象 }) } }) </script>
-
vue-cli
-
vue-cli概念
-
vue-cli 是 vue 出来的一个脚手架,可以进行 组件式地开发
-
使用vue-cli
-
新建项目录:E:\project\vue-cli
-
安装vue-li
-
安装命令
npm install -g @vue/cli@3.0.1 版本3.0:这个版本号一定要跟,如果不跟,那么就是安装vue-cli 的最新版本
-
查看版本
- 安装成功后查看
- vue --version
- 安装成功后查看
-
原型工具安装
- npm install -g @vue/cli-service-global@3.0.1
-
测试
-
在项目下新建test.vue文件
-
<template> <h1>Hello Vue-Cli</h1> </template>
-
-
运行命令
- vue serve test.vue
-
访问
- http://localhost:8081/
-
结果
- 网页出现:Hello Vue-Cli
-
-
-
关于vue文件
-
vue.js组件通过 组件的方式重复使用很多代码
-
方式的缺陷
- 组件用 ‘’ 方式写,如果比较复杂,写起来麻烦
- 组件里 不包含 js
- 组件里不包含 css
-
解决方法
- html部分放在 标签里
- 提供数据部分放在
-
-