【Vue】二
一个第三方js处理类库 BootCDN
Vue过滤器
Date.now() 获取时间戳
Date.now()
1652411231222
计算属性实现
<body>
<div id="root">
<h2>现在是:{{fmtTime}}</h2>
</div>
</body>
<script>
Vue.config.productionTip = false
const vm = new Vue({
el: "#root",
data: {
time: 1652411751706
},
computed: {
fmtTime() {
return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss')
}
}
})
</script>
methods实现
<body>
<div id="root">
<h2>现在是:{{getFmtTime()}}</h2>
</div>
</body>
<script>
Vue.config.productionTip = false
const vm = new Vue({
el: "#root",
data: {
time: 1652411751706
},
computed: {
fmtTime() {
return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss')
}
},
methods: {
getFmtTime() {
return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss')
}
}
})
</script>
函数有返回值时,调用的函数值名必须加括号
过滤器实现
<body>
<div id="root">
<h2>现在是:{{time | Timeformat('YYYY-MM-DD') | subStr(4)}}</h2>
</div>
</body>
过滤器使用管道符号将管道前的值作为参数传入管道符后的过滤器函数
filters: {
Timeformat(val, str) {
return dayjs(val).format(str)
},
subStr(val, len) {
return val.slice(0,len)
}
}
过滤器适用于{{}}差值语法、v-bind(:)单向绑定但不适用于model双向绑定
全局过滤器
上面的过滤器全是在Vue实例中配置的,因此是局部过滤器
Vue.filter('Timeformat', function(val, str){
return dayjs(val).format(str)
})
这样所有的VUe实例均可以使用此过滤器
一些Vue内置指令
v-text
作用: 向所在节点中渲染文本内容
与插值语法的区别: v-text会替换节点中的内容,插值语法不会
<div id="root">
<h2 v-text="time">现在是:{{time | Timeformat('YYYY-MM-DD') | subStr(4)}}</h2>
</div>
结果只显示time数据
v-html
作用: 支持结构解析,v-text不能
可能存在安全注入问题:
①在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击
如用户输入: <a href="www....com?document.cookie">
②一定要在可信的内容上使用v-html,永远不要用在用户的提交上
解决: 后端使用HTTPOnly,即只有Http传输能读取到这些cookie
v-cloak 防止网速慢导致未经解析的模板加载到页面
![](file://D:\资料\学习笔记\Vue\5.png?msec=1653396919463)
如上图,由于js没有加载导致vue也不能加载,页面会显示容器中未曾解析的{{name}},但是加上v-cloak后,根据css样式会隐藏属性为v-cloak的节点,而v-cloak的特性是vue加载时会自动删掉,因此解析后的模板就会显示了。
v-once
v-once所在节点在初次动态渲染之后,就被视为静态内容了
以后的数据的改变也不会引起v-once所在结构的更新,可以用于优化性能
v-pre
v-pre可以让vue跳过所在节点的编译过程
可以利用它跳过没有使用指令、差值语法的节点,会加快编译
自定义指令
Vue生命周期
浏览器本地存储
localStorage
保存
let person = {
name: 'gravce',
sex: 'male'
}
function SaveData() {
localStorage.setItem('msg', 'hello')
localStorage.setItem('msg1', 123)
localStorage.setItem('person', JSON.stringify(person))
}
数据保存会以字符串形式,对象应该使用json
获取
function GetData() {
document.getElementById('output').value =
localStorage.getItem('person')
}
删除
function DeleteData() {
localStorage.removeItem('person')
}
清空
function ClearData() {
localStorage.clear()
}
SessionStorage
LocalStorage是保存在用户磁盘上的,浏览器关闭会话结束后不会消失,而SessionStorage会
使用浏览器本地存储保存Todolist结果
只需使用一个监视属性即可解决
data() {
return {
todos: JSON.parse(localStorage.getItem('todos')) || []
}
},
watch: {
todos(val) {
localStorage.setItem('todos', JSON.stringify(val))
}
},
注意代码中的"|| []",这是为了防止localStorage为空时,导致JSON解析为null,进而导致todos拿到的不是空数组而是null进而引起的后续错误
意料之外的bug
上面的代码在刷新页面之后不能显示做没做完,原因是没有开启深度监视
watch: {
todos: {
handler(val) {
localStorage.setItem('todos', JSON.stringify(val))
},
deep: true
}
},
组件自定义事件
绑定事件
<!-- 给组件绑定一个hikaru自定义事件,当Student组件中触发该事件时,demo就会被调用 -->
<Student v-on:hikaru="demo"></Student>
给组件绑定一个hikaru自定义事件,当Student组件中触发该事件时,demo就会被调用
绑定的简写
<Student @hikaru="demo"></Student>
组件事件的触发 $emit
methods: {
getName() {
// 触发Student组件身hikaru事件
this.$emit('hikaru')
}
},
在App.vue中使用mounted、$on 延迟事件的触发
<Student ref="stu"></Student>
mounted() {
setTimeout(()=>{
this.$refs.stu.$on('hikaru', this.demo)
}, 3000)
},
解绑自定义事件 $off
methods: {
getName() {
// 触发Student组件身上的getName事件
this.$emit('hikaru')
},
unbind() {
this.$off('hikaru')
}
},
解绑多个事件:this.$off(['hikaru', 'xxx'])
解绑所有事件:this.$off()
全局事件总线 实现任意组件之间的通信
分析:全局事件总线,实质是创建一个中间组件或者vue实体,所有的其他组件都能在这个中间体上绑定事件并通过触发事件获取数据,因此,此中间体需要满足两个条件:
①所有组件都能看见它
②它可以调用$on、$off、$emit方法
定义方式一:通过VueComponent
1 在main.js安装事件总线
const vc = Vue.extend({})
Vue.prototype.bus = new vc()
2 在事件总线上绑定事件
mounted() {
let items = this.$refs.list.$refs.item
items.forEach(item => {
item.$on('checkTodo', this.checkTodo)
item.$on('deleteOne', this.deleteOne)
});
this.bus.$on('hikaru', this.hikaru)
}
3 其他组件在时间总线上触发事件
<button @click="bus.$emit('hikaru')">hikaru</button>
定义方式一:通过VM
vm本身就可以作为原型对象,不需要在创建vue
在main.js安装事件总线
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
beforeCreate() {
Vue.prototype.bus = this
}
}).$mount('#app')
需要注意总线bus的赋值时机,在vm创建之前的话vm没有生成,而在之后的话vm已经执行完了mounted挂载,因此需要放在beforeCreate钩子中
全局事件总线的使用场景
![](file://D:\资料\学习笔记\Vue\6.png?msec=1653396919453)
消息订阅与发布
动画效果
<template>
<div>
<transition appear name="hello">
<div v-show="isShow">
<div class="black"> </div>
<div class="hello">
Hello
</div>
</div>
</transition>
<button @click="isShow = !isShow">click</button>
</div>
</template>
<script>
export default {
name: 'Test',
data() {
return {
isShow: true
}
}
}
</script>
<style scoped>
.black {
background-color: rgb(0, 0, 0);
width: 15px;
height: auto;
float: left;
}
.hello {
background-color: orange;
width: 100px;
float: left;
}
.hello-enter-active{
animation: comeAndgo 1s linear
}
.hello-leave-active{
animation: comeAndgo 1s linear reverse
}
@keyframes comeAndgo {
from {
transform: translateX(-115px);
}
to {
transform: translateX(0px);
}
}
</style>
过渡实现动画效果
/* 进入的起点 */
.hello-enter, .hello-leave-to{
transform: translateX(-100%);
}
/* 进入的重点 */
.hello-enter-to, .hello-leave{
transform: translateX(0);
}
/* 进入离开动画 */
.hello-enter-active, .hello-leave-active {
transition: 1s ;
}
多个元素过渡
<transition-group appear name="hello">
<div v-show="isShow" key="1">
<div class="black"> </div>
<div class="hello">
Hello
</div>
</div>
<div v-show="isShow" key="2">
<div class="black"> </div>
<div class="hello">
Hello
</div>
</div>
</transition-group>
多个元素过渡需要使用transition-group,并且需要在元素上添加key值
集成第三方动画库
<transition-group
appear
name="animate__animated animate__bounce"
enter-active-class="animate__zoomInDown"
leave-active-class="animate__zoomOut"
>
<div v-show="isShow" key="1">
<div class="black"> </div>
<div class="hello">
Hello
</div>
</div>
</transition-group>
(1) 安装并导入
$ npm install animate.css --save
<script>
import 'animate.css'
export default {
name: 'Test',
data() {
return {
isShow: true
}
}
}
</script>
(2) 配置name、进入离开动画
<transition-group
appear
name="animate__animated animate__bounce"
enter-active-class="animate__zoomInDown"
leave-active-class="animate__zoomOut"
>
group必须配置key
配置代理 解决ajax请求跨域问题
几种Ajax
① xhr(原生js实现)
xhr = new XMLHTTPRequest()
xhr.open() 配置请求信息
xhr.send() 发送请求
② JQuery
$.get $.post
③ axios(最常用)
④ fetch
②③都是对xhr进行二次封装,fetch和xhr都是原生的js实现
fetch获取响应需要两层then,且兼容性不好
使用axios获取学生信息
methods: {
getStuInfo() {
axios.get('http://localhost:5000/students').then(
response => {
console.log(response.data)
},
error => {
console.log(error.message)
}
)
}
}
存在的跨域问题
跨域:违背了同源策略,即协议名、主机名、端口号必须一致。
如图所示,浏览器端口号8080与服务器5000不一致导致跨域问题,需要注意的是跨域问题并不是没有发送响应请求,而是在服务器响应给浏览器时,浏览器发现跨域而将数据隐藏了起来
解决跨域的策略
1 cors
大致思路:服务器在响应给浏览器数据时会在响应体中携带一些特殊的响应头,以告知浏览器可以无视跨域问题。
但是在开发中响应头是不能随便修改的,而且这种策略需要完全由后端进行
2 jsonp
大致思路:利用script标签的src属性不受同源跨域问题影响的特性
但是需要前后端同时进行修改,而且只能处理get请求
3 使用代理服务器(常用)
![](file://D:\资料\学习笔记\Vue\8.png?msec=1653396919454)
如此一来,8080端口的浏览器端和8080代理服务器通过ajax请求通信就不存在跨域问题,而且同时服务器和代理服务器是通过http通信,更不存在跨域问题
代理服务器的配置 方式一
vue.config.js
module.exports = {
pages: {
index: {
entry: 'src/main.js'
}
},
devServer: {
proxy: 'http://localhost:5000'
}
}
同时修改前端页面的请求端口号为代理服务器的8080
Test2.vue
export default {
name: 'Test2',
methods: {
getStuInfo() {
axios.get('http://localhost:8080/students').then(
response => {
console.log(response.data)
},
error => {
console.log(error.message)
}
)
}
}
}
但是这样存在两个个问题:请求会首先在8080端口号下查找student资源,当发现没有的时候才去向代理服务器发送请求;另一个问题是只能给一台服务器转发请求
代理服务器的配置 方式二
devServer: {
proxy: {
'/hikaru': {
target: "http://localhost:5000",
pathRewrite: {'^/hikaru':''},
ws: true,
changeOrign: true
}
}
}
【Vue】二的更多相关文章
- Vue(二) 计算属性
模板内的表达式常用于简单的运算,当过长或逻辑复杂时,难以维护,计算属性就是解决该问题的 什么是计算属性 表达式如果过长,或逻辑更为复杂,就会变得臃肿甚至难以维护,比如: <div> {{ ...
- vue 二维码长按保存和复制内容
效果图: 二维码用了 qrcode.vue npm install qrcode.vue --save 复制内容用了 vue-clipboard2 npm install vue-clipboard2 ...
- 一步一步学Vue(二)
接上篇,在本篇中,我们将要实现如下,功能,编辑和查询,我们当前的todolist程序,和线上其它的demo程序不同,我们会对其进行增删改查的基本操作,之后进行进一步的完善,按照常规的系统使用经验,一般 ...
- Vue (二) --- Vue对象提供的属性功能
--------------------------------------------不是井里没有水,而是你挖的不够深. 3. Vue对象提供的属性功能 3.1 过滤器 过滤器,就是vue允许开发者 ...
- vue二、脚手架搭建
1:安装nodeJs(下载一路回车) https://nodejs.org/zh-cn/ 2:检验nodeJs是否安装成功 (注意nodeJs是否添加到window路径中) 进入cmd -> n ...
- springboot+VUE(二)
入element-ui cnpm install element-ui -S 执行后,会下载element-ui的包到本地,同时会将配置加入到package.json的依赖块中. 通过命令行可以将最新 ...
- Vue(二)基础
01-vue的起步 1.引包 a) 直接下载,并用<script>标签引入 b) CDN方式引入: <script src="https://cdn.bootcss.com ...
- vue二次实战(二)
https://www.cnblogs.com/jellify/p/9522477.html install的弹出框中输入sublimeTmpl,找到sublimeTmpl这个插件后回车 Vue路由 ...
- vue二次实战(一)
创建好项目(npm run dev 运行项目:先不用运行,或先运行再关闭) 先安装axios! npm install axios 然后! npm install --save axios vue-a ...
- vue二次实战
vue爬坑之路 npm uninstall 模块名(删除指定模块) https://www.cnblogs.com/wisewrong/p/6255817.html vue快速入门 https://s ...
随机推荐
- web后端之连接mysql
1建立java enterprise项目 2在WEB-INF目录下建立lib目录把jdbc用的mysql-connector-java.jar包复制过来 3添加依赖 4编写class 或在 ...
- AT ARC092F Two Faced Edges
题意:给定一个有向图,保证无重边自环,求将图中的每条边反向后强联通分量的个数是否会改变. 数据范围:$n$ $≤$ $1e3$,$m$ $≤$ $2e5$. 首先考虑一条边的影响. 因为一条边只能连接 ...
- C# 图片 等 文件 读取操作 的一点提示
源于:在读取图片时,总喜欢首先采用:Image img=Image.FromFile("");操作,这种方式由于 调用图片的程序与图片文件是通过 绝对地址关联的,会造成 当前进程或 ...
- lisp入门资料收集
1.一些文档 http://acl.readthedocs.io/en/latest/zhCN/index.html http://daiyuwen.freeshell.org/gb/lisp.htm ...
- 007使用IDEA开发
007使用IDEA开发 1.什么叫IDE? 集成开发环境(IDE,Integrated Development Environment)是用于提供程序开发环境的应用程序,一般包括代码编辑器.编译器.调 ...
- jedis使用分布式锁
import redis.clients.jedis.Jedis;public class A { public static void main(String[] args) throws Exce ...
- 如何像Facebook一样构建数据中心 – BGP在大规模数据中心中的应用(3)
如何像Facebook一样构建数据中心 – BGP在大规模数据中心中的应用(3) superrace• 18-06-12 作者简介:史梦晨,曾就职于国内金牌集成商, 现就职于EANTC( 欧洲高级网络 ...
- npm & cnpm 淘宝源
前提:如果确实需要多版本的情况可以使用nvm 可以方便的安装和切换多版本! --nvm ls --nvm use 12.4.0 永久npm 设置淘宝源npm config set registry h ...
- 导出生成word
用XML做就很简单了.Word从2003开始支持XML格式,大致的思路是先用office2003或者2007编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板(后缀为.ft ...
- warning: the `gets' function is dangerous and should not be used.
LINUX下编译C程序时,出现了:warning: the `gets' function is dangerous and should not be used. 原因:Linux 下gcc编译器不 ...