基本代码 MVVM模式
注意:
MVVM在vue中的体现:
vue所控制的区域对应 V
vm实例对应的是 VM
data对应的是 M
Document
{{ msg }}
使用 v-cloak 能够解决 插值表达式闪烁的问题
++++++++ {{ msg }} ----------
使用 v-cloak 能够解决 插值表达式闪烁的问题
注意:v-text会覆盖元素中原本的内容,但是 插值表达式 只会替换自己的这个占位符,不会把 整个元素的内容清空
==================
结果是 msg的值 那些等号会被覆盖掉
v-html能够解析html标签
注意:标签内的内容会被覆盖掉
1212112
msg2的值是 我是h1
v-bind: 是 Vue中,提供的用于绑定属性的指令
注意:
不简写:
简写:
mytitle是data中的数据
Vue 中提供了 v-on: 事件绑定机制
show对应的方法是 function(){ alert('hello') }
使用 v-model 指令,可以实现 表单元素和 Model 中数据的双向数据绑定
注意: v-model 只能运用在 表单元素中
语法:v-for="(item,i) in list"
注意:in 后面我们放过 普通数组,对象数组,对象, 还可以放数字
v-for循环普通的数组
item:循环的每一项
i:索引值
索引值:{{i}} --- 每一项:{{item}}
v-for循环对象数组
item:循环的每一项
i:索引值
Id:{{ user.id }} --- 名字:{{ user.name }} --- 索引:{{i}}
v-for循环对象
val:值
key:键
i:索引
值是: {{ val }} --- 键是: {{key}} -- 索引: {{i}}
v-for迭代数字
注意:如果使用 v-for 迭代数字的话,前面的 count 值从 1 开始
这是第 {{ count }} 次循环
v-for中的 key的使用
注意:
这是一个可以体现出这个问题的小案例运行一下我想你就会明白了
Document
{{item.id}} --- {{item.name}}
比较:
v-if 特点:每次都会重新删除或创建元素,有较高的切换性能消耗
v-show 特点: 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式,有较高的初始渲染消耗
使用:
v-if 有较高的切换性能消耗:如果元素涉及到频繁的切换,最好不要使用 v-if, 而是推荐使用 v-show,因为每次切换都会删除或创建元素
v-show 有较高的初始渲染消耗:如果元素可能永远也不会被显示出来被用户看到,则推荐使用 v-if
比如:
这是用v-if控制的元素
这是用v-show控制的元素
.stop和.self的区别: .stop会阻止冒泡行为,除了被点击元素以为,别的元素的点击事件都不会被触发 而.self只是当前元素自己不点击不会触发,而其他的元素依然会被触发点击事件
使用 .stop 阻止冒泡,点击只会触发 input的点击事件而div的点击事件不会触发
使用 .prevent 阻止默认行为,可以阻止a标签的默认跳转
有问题,先去百度
使用 .native 监听组件的点击事件如果不写,不能确定点击的是组件中的那个元素,加了就相当于组件的根元素,Icon是iview的字体图标组件
使用 .capture 实现捕获触发事件的机制,会先执行div的点击事件,在执行input的点击事件
使用 .self 实现只有点击当前元素时候,才会触发事件处理函数
使用 .once 只触发一次事件处理函数
第一个:只会执行一次点击事件
第二个:只会执行一次点击事件和一次默认事件阻止事件,再点就会跳转百度
百度
百度
直接传递一个数组,注意: 这里的 class 需要使用 v-bind 做数据绑定
这是一个很大很大的H1,大到你无法想象!!!
在数组中使用三元表达式
这是一个很大很大的H1,大到你无法想象!!!
在数组中使用 对象来代替三元表达式,提高代码的可读性
这是一个很大很大的H1,大到你无法想象!!!
在为 class 使用 v-bind 绑定 对象的时候,对象的属性是类名,由于 对象的属性可带引号,也可不带引号,所以 这里我没写引号; 属性的值 是一个标识符
这是一个很大很大的H1,大到你无法想象!!!
也可以把这些对象抽离出来保存到一个变量内
这是一个很大很大的H1,大到你无法想象!!!
对象就是无序键值对的集合
使用对象的方式,注意带横线的 比如 font-weight 要使用引号括起来
这是一个h1
将对象抽离出来保存到变量中
这是一个h1
使用数组的方式
这是一个h1
将对象处理出来
注意:可以传递多个参数,但是函数内的第一个参数是管道符前面的那个值,调用的时候,管道符前面的值不用自己传递,所以在方法内只需要协商自己想要传递的参数就可以了
{{ ctime | dateFormat('过滤的条件') }}
语法:定义全局过滤器,所有的VM实例都可以共享
//参数1 是要被过滤的值 及 管道符前面的那个值
//参数2 是过滤的条件
Vue.filter('过滤器的名字',function('参数1','参数2'){
return '想要返回的结果';
})
例子:过滤时间的过滤器
// 全局的过滤器, 进行时间的格式化
// 所谓的全局过滤器,就是所有的VM实例都共享的
Vue.filter('dateFormat', function (dateStr, pattern = "") {
// 根据给定的时间字符串,得到特定的时间
var dt = new Date(dateStr)
// yyyy-mm-dd
var y = dt.getFullYear()
var m = dt.getMonth() + 1
var d = dt.getDate()
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
//`${y}-${m}-${d}` Es6表示字符串的新语法 ${} 大括号内表示要插入变量
return `${y}-${m}-${d}`
} else {
var hh = dt.getHours()
var mm = dt.getMinutes()
var ss = dt.getSeconds()
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}
})
定义私有过滤器 过滤器有两个 条件 【过滤器名称 和 处理函数】
处理函数内部所做的事情跟全局过滤器所做的事情一样
规则:过滤器调用的时候,采用的是就近原则,如果私有过滤器和全局过滤器名称一致了,这时候 优先调用私有过滤器
var vm2 = new Vue({
el: '#app2',
data: {
dt: new Date()
},
methods: {},
filters: {
//dateFormat 过滤器的名字
dateFormat: function (dateStr, pattern = '') {
// 根据给定的时间字符串,得到特定的时间
var dt = new Date(dateStr)
// yyyy-mm-dd
var y = dt.getFullYear()
var m = (dt.getMonth() + 1).toString().padStart(2, '0')
var d = dt.getDate().toString().padStart(2, '0')
if (pattern.toLowerCase() === 'yyyy-mm-dd') {
return `${y}-${m}-${d}`
} else {
var hh = dt.getHours().toString().padStart(2, '0')
var mm = dt.getMinutes().toString().padStart(2, '0')
var ss = dt.getSeconds().toString().padStart(2, '0')
return `${y}-${m}-${d} ${hh}:${mm}:${ss} ~~~~~~~`
}
}
}
})
f2是被绑定的键 113是键的值
使用方法,与上面的事件修饰符一样
Vue.config.keyCodes.f2 = 113
注意: Vue中所有的指令,在调用的时候,都以 v- 开头
以绑定一个自动获取焦点为例
Vue.directive('focus', {
bind: function (el) { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
// 注意: 在每个 函数中,第一个参数,永远是 el ,表示 被绑定了指令的那个元素,这个 el 参数,是一个原生的JS对象
// 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用
// 因为,一个元素,只有插入DOM之后,才能获取焦点
},
inserted: function (el) { // inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】
// 和JS行为有关的操作,最好在 inserted 中去执行,放置bind JS行为不生效
el.focus();
},
updated: function (el) { // 当VNode更新的时候,会执行 updated, 可能会触发多次
}
})
参数详解:自定指令钩子函数及内部参数
Vue.directive('color', {
// 样式,只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式
// 将来元素肯定会显示到页面中,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素
// 和样式相关的操作,一般都可以在 bind 执行
bind: function (el, binding) {
console.log(binding.name); //自定义指令名字
console.log(binding.expression); //自定义指令属性的值,引号里面是什么内容得到的就是什么内容 比如说v-color="'skyblue'" 那么得到的是'skyblue'
console.log(binding.value); //自定义指令的值,比如说 v-color="'skyblue'" 那么得到的是 skyblue
el.style.color = binding.value
}
})
fontsize 是简写的自定义指令
var vm2 = new Vue({
el: '#app2',
data: {
dt: new Date()
},
methods: {},
directives: { // 自定义私有指令
'fontweight': { // 设置字体粗细的
bind: function (el, binding) {
el.style.fontWeight = binding.value
}
},
'fontsize': function (el, binding) { // 注意:这个 function 等同于 把 代码写到了 bind 和 update 中去
el.style.fontSize = parseInt(binding.value) + 'px'
}
}
})
代码演示:
var vm = new Vue({
el: '#app',
data: {
msg: 'ok'
},
methods: {
show() {
console.log('执行了show方法')
}
},
beforeCreate() { // 这是我们遇到的第一个生命周期函数,表示实例完全被创建出来之前,会执行它
// 注意: 在 beforeCreate 生命周期函数执行的时候,data 和 methods 中的 数据都还没有没初始化
},
created() { // 这是遇到的第二个生命周期函数
// 在 created 中,data 和 methods 都已经被初始化好了!
// 如果要调用 methods 中的方法,或者操作 data 中的数据,最早,只能在 created 中操作
},
beforeMount() { // 这是遇到的第3个生命周期函数,表示 模板已经在内存中编辑完成了,但是尚未把 模板渲染到 页面中
// 在 beforeMount 执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的一些模板字符串
},
mounted() { // 这是遇到的第4个生命周期函数,表示,内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了
// 注意: mounted 是 实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,此时,如果没有其它操作的话,这个实例,就静静的 躺在我们的内存中,一动不动
},
// 接下来的3是运行中的两个事件
beforeUpdate() { // 这时候,表示 我们的界面还没有被更新【数据被更新了吗? 数据肯定被更新了】
// 得出结论: 当执行 beforeUpdate 的时候,页面中的显示的数据,还是旧的,此时 data 数据是最新的,页面尚未和 最新的数据保持同步
},
updated() {
// updated 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的
}
});
vue-resource数据请求
读完下面的代码就会用啦
Vue.http.options.root = ‘http://vue.studyit.io/‘; 配置共有的请求部分
注意: 通过 result.body 拿到服务器返回的成功的数据
Document
显示隐藏 添加删除 都会触发动画
在进入/离开的过渡中,会有 6 个 class 切换。
这是一个H3
Document
这是一个H3
注意:要引入 animate.css
Document
这是一个H3
Document
Document
{{item.id}} --- {{item.name}}
组件的使用:如果要使用组件,直接,把组件的名称,以 HTML 标签的形式,引入到页面中,即可
注意:
组件创建方式一:
组件创建方式二
组件创建方式三
这是通过 template 元素,在外部定义的组件结构,这个方式,有代码的只能提示和高亮
好用,不错!
这是私有的 login 组件
组件可以有自己的 data 数据
组件的 data 和 实例的 data 有点不一样,实例中的 data 可以为一个对象,但是 组件中的 data 必须是一个方法
组件中的 data 除了必须为一个方法之外,这个方法内部,还必须返回一个对象才行;
组件中 的data 数据,使用方式,和实例中的 data 使用方式完全一样!!!
组件中 的methods数据,使用方式,和实例中的 methods使用方式完全一样!!!
这是全局组件 --- {{msg}}
方式一
方式二
mode="out-in" 作用设置组件切换的方式,这个表示当前组件先离开了以后,另一个组件在进来,与之相反的还有 mode="in-out"
:is="comName" 设置要显示组件的名字
Document
通过 属性绑定(v-bind:) 的形式, 把 需要传递给 子组件的数据,以属性绑定的形式,传递到子组件内部
把父组件传递过来的 parentmsg 属性,先在 props 数组中,定义一下,这样,才能使用这个数据
props: ['parentmsg']
全部的代码
父组件向子组件 传递 方法,使用的是 事件绑定机制; v-on, 当我们自定义了 一个 事件属性之后,那么,子组件就能够,通过某些方式,来调用 传递进去的 这个 方法了 func自己定义的名字 随便写 show 父组件中的方法
通过 this.$emit.方法 来调用 emit 英文原意: 是触发,调用、发射的意思
//this.sonmsg 传递的参数 如果需要两个参数可以这样写 this.$emit('func', 参数1,参数2) 需要多个以此类推
this.$emit('func', this.sonmsg)
全部代码:
这是 子组件
render函数中return的页面会把app页面换掉
444444
ref获取DOM元素和组件
哈哈哈, 今天天气太好了!!!
//DOM元素
this.$refs.myh3
//组件
this.$refs.mylogin
全部代码:
哈哈哈, 今天天气太好了!!!
引包
创建一个路由对象, 当 导入 vue-router 包之后,在 window 全局对象中,就有了一个 路由的构造函数,叫做 VueRouter
var routerObj = new VueRouter({
// route // 这个配置对象中的 route 表示 【路由匹配规则】 的意思
routes: [ // 路由匹配规则
// 每个路由规则,都是一个对象,这个规则对象,身上,有两个必须的属性:
// 属性1 是 path, 表示监听 哪个路由链接地址;
// 属性2 是 component, 表示,如果 路由是前面匹配到的 path ,则展示 component 属性对应的那个组件
// 注意: component 的属性值,必须是一个 组件的模板对象, 不能是组件的引用名称,就是使用组件时的标签名;
{ path: '/', redirect: '/login' }, // 意思是当路径是'/'就跳转到'/login'
{ path: '/login', component: login },
{ path: '/register', component: register }
],
linkActiveClass: 'myactive'
})
将路由规则对象,注册到 vm 实例上,用来监听 URL 地址的变化,然后展示对应的组件
var vm = new Vue({
el: '#app',
data: {},
methods: {},
router: routerObj // 将路由规则对象,注册到 vm 实例上,用来监听 URL 地址的变化,然后展示对应的组件
});
router-link 默认渲染为一个a 标签,作用相当于一个a标签,用来实现 url 地址的改变,进行跳转,可以使用 tag 修改默认的渲染标签
router-view 组件渲染地方
linkActiveClass: ‘myactive’ 作用 —修改router-link 标签渲染出来的默认 class ,默认值是 router-link-active
全部代码:
登录
注册
方式一
如果在路由中,使用 查询字符串,给路由传递参数,则 不需要修改 路由规则的 path 属性
登录
获取传递的参数 使用 this.$route 使用?拼接的方式传递的参数在 query属性里
this.$route.query //得到的是获取到的参数
this.$route.query.path ///获取到的是路径 "/login"
this.$route.query.fullPath //获取到的是路径 "/login?id=10&name=zs"
代码:
登录
注册
方式二 占位符的方式
如果在路由中,使用 查询字符串,给路由传递参数,则 不需要修改 路由规则的 path 属性
登录
需要在路由配置项的path 中写下占位符
var router = new VueRouter({
routes: [
{ path: '/login/:id/:name', component: login },
{ path: '/register', component: register }
]
})
获取传递的参数 使用 this.$route 使用?拼接的方式传递的参数在 query属性里
this.$route.query //得到的是获取到的参数
this.$route.query.path ///获取到的是路径 "/login"
this.$route.query.fullPath //获取到的是路径 "/login?id=10&name=zs"
代码:
登录
注册
一个路由里面套着一个路由
注意:
使用 children 属性,实现子路由,同时,子路由的 path 前面,不要带 / ,否则永远以根路径开始请求,这样不方便我们用户去理解URL地址
var router = new VueRouter({
routes: [
{
path: '/account',
component: account,
// 使用 children 属性,实现子路由,同时,子路由的 path 前面,不要带 / ,否则永远以根路径开始请求,这样不方便我们用户去理解URL地址
children: [
{ path: 'login', component: login },
{ path: 'register', component: register }
]
}
]
})
代码:
Account
这是 Account 组件
登录
注册
页面中多个router-view 用name标识出来
创建路由对象 配置routes
var router = new VueRouter({
routes: [
{
path: '/', components: {
'default': header, //默认跳转
'left': leftBox, //渲染到name为left的router-view
'main': mainBox //渲染到name为left的router-view
}
}
]
})
全部代码:
Document