Vue
Vue 的基础
-
常用指令
-
v-cloak 解决{{}}插值闪烁问题
-
参考网址:https://www.jianshu.com/p/f56cde007210?utm_source=oschina-app
// javascript: var app new Vue(){ el:"#app", data:{ context:"hello world" } }
/* html: */ <div id="app" v-cloak> {{ context }} </div>
-
```css // css: [v-cloak]{ display:none; } ``` + v-text 会**先执行、覆盖**元素中原本的内容,但是插值表达式只会覆盖自己的占位符,默认**不会闪烁**,,可以简写成 {{ }} + v-html 渲染html标签,覆盖元素中原有元素内容 + v-bind 简写为:用来绑定数据,可以写合法的js表达式; 注意:**可以简写为 ** ***【 :要的绑定的属性 】*** + v-on :简写为 @ 用来点击事件 + v-model:双向数据绑定事件 - v-bind 只能实现数据的单向绑定,【el 绑定到表单中】 - v-model 可以实现 表单元素和 model 中数据的双向数据绑定 注意:** v-model 只能运用在表单元素中 ** < input(radio,text,address,email...) select checkbox textarea> ```html <html> <head> <title>Vue 的常用指令</title> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.js"></script> </head> <body> <div id="app"> <div v-cloak>{{ msg }} </div> <div v-text="msg2"></div> <div v-html="msg2"></div> <input type="button" value="自定义title按钮" v-bind:title="mytitle + '2344'" > <button v-0n:click='show'>按钮</button> <!--- 简写 [ v-bind: 、v-on: ] ---> <input type="button" value="自定义title" :title="mytitle + '2344'"> <button @click = "show">按钮</button> </div> <script> var vm = new Vue({ el:'#app', data:{ msg:'123', msg2:'<h1>这是一个h1标签</h1>', mytitle:'这是一个自己定义的title' }, methods:{ show:function(){ alert('3') } } }) </script> </body> </html> ```
-
数据与方法
- 当一个Vue实例被创建时,它将 data 对象中的所有的 property 加入到 Vue 的响应式系统中。当这些 property 的值发生改变时,视图将会产生 “响应”,即匹配更新为新的值。
<html>
<head>
<!-- 1、导入 Vue 的包 -->
<script src="vue.js"></script>
</head>
<body>
<!-- 实例所控制的这个元素区域,就是我们的 V -->
<div id="app">
<p>{{ msg }}</p>
</div>
<script>
// 2、创建一个 Vue 实例
// 当我们导入包之后,在浏览器的内存中,就多了一个 Vue 构造函数
// 注意;我们 new 出来的这个 vm 对象,就是我们 mvvm 的 vm 调度者
var vm = new Vue({
el:'#app', // 表示,当前我们 new 的这个 Vue 实例,要控制在页面上的区域
data:{ // data 属性中,存放的是 el 中要用到的数据
msg:'欢迎学习Vue' // 通过 Vue 提供的命令,很方便的就能把数据渲染到页面上,程序员不再手动操作 DOM 元素了【前端的 Vue 之类的框架,不提倡我们去手动操作 DOM 元素了】
}
})
</script>
</body>
</html>
事件修饰符
- .stop 阻止冒泡
- .prevent 阻止默认事件 【例如 a 标签的 href 属性】
- . capture 添加事件侦听器时使用事件捕获模式 【冒泡时先触发】
- .self 只当事件在该元素本身(比如不是子元素)触发时触发回调
- .once 事件只触发一次
在Vue 中使用样式
使用 class 样式
-
数组
<h1 :class="['red','thin']"> 这是一个邪恶的h1 </h1>
-
数组中使用三元表达式
<h1 :class="['red','thin',isactive?'active':'']"> 这是一个邪恶的h1 </h1>
-
数组中嵌套对象 【使用对象来代替 三元表达式,提高代码的可读性】
<h1 :class="['red','thin',{'active':isactive}]"> 这是一个邪恶的h1 </h1>
-
直接使用对象 【在为 class 使用 v-bind 绑定对象的时候,对象的属性是类名,对象的属性可带也可不带引号,属性的值是一个标识符】
<h1 :class="{red:true,italic:true,active:true,thin:true}">
这是一个邪恶的h1
</h1>
使用内联样式
-
直接在元素上通过
:style
的样式,书写样式对象<h1 :style="{color:'red','font-size':'400px'}"> 这是一个善良的h1 </h1>
-
将样式对象,定义到
data
中,并直接引用到:style
中- 在 data 上定义
data:{ h1styleObj:{color:'red','font-size':'40px','font-wight':'200'} }
- 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="h1StyleObj"> 这是一个善良的h1 </h1>
-
在
:style
中通过数组,引用多个data
上的样式对象-
在 data 上定义样式
data:{ h1StyleObj:{color:'red','font-size':'40px','font-weight':'200'}, h1StyleObj2{fontStyle:'italic'} }
-
在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="[h1StyleObj,h1StyleObj2]"> 这是一个善良的h1 </h1>
-
Vue 指令 v-for
和 key
属性
-
迭代数组
<div class="app"> <p v-for="(item,i) in users"> 索引号:{{ i }}---id: {{ item.id }}---name: {{ item.name }} </p> </div>
-
迭代对象中的属性
<div class="app"> <p v-for="(val,key,i) in obj">属性名:{{ key }} , 属性值:{{ val }} , 索引号:{{ i }} </p> </div>
-
迭代数字
<div class="app"> <p v-for="count in 10">这是第 {{ count }} 次循环</p> </div>
2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的
- 当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue将不是移动DOM元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
- 为了给Vue一个提示,**以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,**你需要为每项提供一个唯一 key 属性。
总结
过滤器
- Vue.js 允许你自定义过滤器,**可被用作一些常见的文本格式化。过滤器可以用在两个地方:
mustache 插值
**和v-bind 表达式
。过滤器应该被添加在 javascript 表达式的尾部,由 ” 管道 ”符指示;
私有过滤器
-
HTML元素:
<td>{{ item.ctime | dataFormat("yyy-mm-dd") }}</td>
-
私有
filters
定义方法filters:{ // 私有局部过滤器,只能在 当前 vm 对象所控制的view 区域内进行 dateFormat:function(){ var dt = new Date(dateStr) // yyyy-mm-dd var y = dt.getFullYear(); var m = dt.getMonth() + 1; var d = dt.getDate(); // return `${y}-${m}-${d}` if (pattern.toLowerCase() === 'yyyy-mm-dd') { return `${y}-${m}-${d}` } else { var hh = dt.getHours() var mm = dt.getMinutes() var ss = dt.getSeconds() return `${y}-${m}-${d} ${hh}:${mm}:${ss}` } } }
按键修饰符
- x 中自定义键盘修饰符 [ 了解 ]
Vue.directive('on').keyCode.f2 = 113;
-
x中自定义键盘修饰符
-
通过
Vue.config.keyCodes.名称 = 按键值
· 来自定义案件修饰符的别名Vue.config.keyCodes.f2 = 113;
-
使用自定义的按键修饰符:
<input type="text" v-model="name" @keyup.f2="push()">
-
自定义指令
-
自定义全局和局部的自定义指令:
// 自定义全局指令 `v-focus` 为绑定的元素自动获取焦点 Vue.directive('focus',{ inserted:function(el){ // inserted 表示被绑定元素插入父节点时调用 el.focus() } })
-
也可以注册局部指令,组件中接受一个
directive
的选项:directive:{ focus:{ // 指令的定义 inserted:function(el){ el.focus() } } }
-
钩子函数
bind : 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次 inserted : 表示元素插入到 DOM 中的时候,会执行 inserted 函数【触发1次】 updated : 当VNode更新的时候,会执行 updated , 可能会触发多次
-
Vue实例的生命周期
- 从Vue实例创建、运行、到销毁期间、总是伴随着各种各样的事件,这些事件,统称为生命周期!
- 生命周期钩子:就是生命周期事件的别名.
主要生命周期函数
生命周期图示
- 创建期间的生命周期函数:
- beforeCreate() : 实例刚在内存中被创建出来,此时,还
没有初始化
好 data 和 methods 属性 - created() :实例已经在内存被创建出来,data 和 methods 都
已经被初始化
好了 !如果要调用
methods 中的方法,或者操作
data 中的数据,只能在 created 中操作 - beforeMount():表示已经完成了模板的编译,但是尚未把模板渲染到页面中
- mounted():表示实例已经被完全创建好了,内存中的模板已挂载到页面中。是创建期间的最后一个生命周期函数
- beforeCreate() : 实例刚在内存中被创建出来,此时,还
- 运行期间的生命周期函数:
- beforeUpdate():表示界面还未被更新,此时,data 中的数据已更新
- updated():此函数执行时,表示页面和 data 数据已经保持同步了,都是新的
- 销毁期间的生命周期函数
- beforeDestroy():执行时,实例身上所有的 data 数据和所有的 methods ,以及 过滤器、指令… 都处于可用状态,此时,还未真正执行销毁过程;但是表示Vue实例已经从运行阶段进入到了销毁阶段;
- destroyed():当执行到此函数时,组件已经被完全销毁了,此时,组件中所有的 data 数据 、methods 方法、指令、过滤器…*都已经不可用了
Vue-resource 实现 get,post,jsonp 请求
- 除了 vue-resource 之外,还可以使用
axios
的第三方包实现数据的请求
-
常见的数据请求类型?get 、post、jsonp
-
测试的URL请求资源地址:
- get 请求地址:http://vue.studyit.io/api/getlunbo
- post 请求地址:http://vue.studyit.io/api/post
- jsonp 请求地址:http://vue.studyit.io/api/jsonp
-
jsonp 的实现原理
-
由于浏览器的安全性限制,不允许AJAX访问协议不同、域名不同、端口号不同的 数据接口,浏览器认为这种访问不安全;
-
可以通过动态创建script 标签的形式,把 script 标签的 src 属性,指向数据接口的地址,因为 script 标签不存在跨域限制,这种数据获取方式称作 JSONP(注意:JSONP的实现原理是只支持Get 请求l
-
实现过程:
- 先在客户端定义一个回调方法,预定义对数据的操作;
- 再把这个回调方法的名称,通过URL传参的形式,提交到服务器的数据接口;
- 服务器数据接口组织好要发送给客户端的数据,再拿着客户端传过来的回调方法名称,拼接出一个调用这个方法的字符串,发送给客户端去解析执行;
- 客户端拿到服务器返回的字符串之后,当作 script 脚本解析执行,这样就能够拿到JSONP的数据了;
const server = http.createServer(); // 监听 服务器的 request 请求事件,处理每个请求 server.on('request',(req,res) => { const url = req.url; // 解析客户端请求的URL 地址 var info = urlModule.parse(url,true); // 如果请求的 URL 地址是 /getjsonp ,则表示要获取JSONP类型的数据 if(info.pathname === '/getjsonp'){ // 获取客户端指定的回调函数的名称 var cbName = info.query.callback; // 手动拼接要返回给客户端的数据对象 var data = { name:'Jack', age:22, gender:'男', hobby:['play games','slepping','watch movies'] } //拼接处一个方法的调用,再调用这个方法的时候,把要发送给客户端的数据,序列化为字符串,作为参数传递给这个调用的方法: var result = `${cbName}(${JSON.stringify(data)})`; // 将拼接好的方法的调用,返回给客户端去解析执行 res.end(result); }else{ res.end('404'); } }); server.listen(3000,() => { console.log('server running at http://127.0.0.1:3000'); });
-
vue-resource基本使用
<div id="app">
<input type="button" name="" id="" value="get请求" @click="getInfo">
<input type="button" name="" id="" value="post请求" @click="postInfo">
<input type="button" name="" id="" value="jsonp请求" @click="jsonpInfo">
</div>
<script>
var vm = new Vue({
el: '#app',
data: {},
methods: {
getInfo() { // 发起get请求
// 当发起 get 请求后,通过 .then 来设置成功的回调函数
this.$http.get('http://vue.studyit.io/api/getlunbo').then(function (result) {
// 通过 result.body 拿到服务器返回的成功的数据
console.log(result.body)
})
},
postInfo() { // 发起 post 请求
// 手动发起的 post 请求,默认没有表单格式,所以,有的服务器处理不了
// 通过 post 方法的第三个参数,{ emulateJSON:true } 设置 提交的内容类型为 普通表单数据格式
this.$http.post('http://vue.studyit.io/api/post', {}, {
emulateJSON: true
}).then((result) => {
concole.log(result.body)
})
},
jsonpInfo() {
this.$http.jsonp('http://vue.studyit.io/api/jsonp').then((result) => {
console.log(result.body)
})
}
}
})
</script>
请求方法(Methods)
-
快捷方式方法可用于所有请求类型中。这些方法可全局或在Vue实例中工作。
// 全局Vue对象 Vue.http.get('/someUrl',[ config ]).then(successCallback,errorCallback); Vue.http.post('/someUrl',[ body ],[ config ]).then(successCallback,errorCallback); // 在Vue实例中 this.$http.get('someUrl',[ config ]).then(successCallback,srrorCallback); this.$http.post('someUrl',[ body ],[ config ]).then(successCallback,errorCallback);
-
请求方法格式
- get (url , [config])
- post (url, [body], [config])
- jsonp (url, [body], [config])
- delete (url, [config])
- head(url, [config])
- put (url, [body, [config])
- patch (url, [body], [config])
Vue中的动画
使用过渡类名
-
HTML结构
<div id="app"> <input type="button" value="动画" @click="myAnimate"> <!-- 使用 transition 将需要过渡的元素包裹起来 --> <transition name="fade"> <div v-show="isshow"> 动画中</div> </div> </transition> </div>
-
VM 实例
// 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el:'#app', data:{ isshow:false }, methods:{ myAnimate(){ this.isshow = !this.isshow; } } })
- v-enter : 【这是一个时间点】 是进入之前,元素的起始状态,此时还没有开始进入
- **v-leave-to **: 【这是一个时间点】 是动画离开之后,离开的终止状态,此时,元素动画已经结束了
- v-enter-active: 【入场动画的时间段】
- v-leave-active : 【离场动画的时间段】
Javascript 钩子
<transition
<!-- 入场时的钩子函数 -->
v-on:before-enter ="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
<!-- 离场时的钩子函数 -->
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
></transition>
定义Vue组件
全局组件定义的三种方式
- 注意:不论是哪种方式创建出来的组件,组件的template 属性指向的模板内容,必须有且只能有唯一的一个根元素
-
使用 Vue.extend 配合 Vue.component 方法:
<div id="app"> <!-- 如果要使用组件,直接把组件的名称,以 HTML 标签的形式,引入到页面中即可 --> <my-login></my-login> <!-- // 如果使用 Vue.component 定义全局组件的时候,组件名称使用了 驼峰 命名,则在引用组件的时候, // 需要把 大写的驼峰改为小写的字母,同时,使用 - 链接 // 如果不适用驼峰,则直接拿名称来使用即可 --> </div> <script> var login = Vue.extend({ template: '<h3>这是使用 Vue.extend 创建的组件 </h3>' // 通过 template 属性,指定了组件要展示的HTML结构 }) // 使用 Vue.component (‘组件的名称’,创建出来的组件模板对象) Vue.component('myLogin',login); var vm = new Vue({ el:'#app', data:{}, methods:{} }) </script>
-
直接使用 Vue.component 方法:
<div id="app"> <mycom2></mycom2> </div> <script> Vue.component('mycom2', { // 不论是哪种方式创建出来的组件,组件的template 属性指向的模板内 容,必须有且只能有唯一的一个根元素 template: '<h3>这是直接使用 Vue.component 创建出来的组件</h3> <span>8888</span>' }) var vm = new Vue({ el: '#app', data: {}, methods: {} }) </script>
-
将模板字符串,定义到script标签中:
<div id="app"> <mycom3></mycom3> </div> <!-- 在被控制的 app 外面,使用 template 元素,定义组件的 HTML 模板结构 --> <template id="tmp1"> <div> <h1>这是通过 template 元素,在外部定义的组件结构,这个方式,有代码的只能提示和高亮</h1> <h4>好运,不错</h4> </div> </template> <script> Vue.component('mycom3', { template: "#tmp1" }) var vm = new Vue({ el: '#app', data: {}, methods: {} }) </script>
路由
再 Vue 中使用 vue-router
-
导入 vue-router 组件类库
<script src="./lib/vue-router-2.7.0.js"></script>
-
使用 router-link 组件来导航
<router-link to="/login">登录</router-link> <router-link to="/register">注册</router-link>
-
使用 router-view 组件来显示匹配到的组件
<router-view></router-view>
-
创建
Vue.extend
创建组件var login = Vue.extend({ template:'<h1>登录组件</h1>' }) var register = Vue.extend({ template:"<h1>注册组件</h1>" })