vue功能
数据渲染/数据同步
组件化/模块化
其他:路由,ajax,数据流
js、css、html在同一个文件里
还可以在组件里例如 <style lang=less>的方式用less来编译样式
vue实例对象
el决定了把这个对象挂载到哪里 例如 el: 'body 放在body下
template 模板
data数据
components 可以把其他组件引用到根组件里
new Vue({
components:{other-component}
})
通常在开头创建这个根组件
Vue组件
main.js入口文件 内容为
import Vue from ‘vue’ //es6的写法类似于require()
组件树
*data最好不要直接赋值
最好这样做
实例选项 option就是在创建实例时内部的template data等等
文本渲染
v-once 执行一次性地插值,当数据改变时,插值处的内容不会更新。
*{{ }}在2.0中已经不能使用到属性里 例如 <div title={{xxx}}> 是被禁止的
{{}}中可以这么写{{num + 1}} 甚至三目运算符等一些简单表达式
v-html和v-text
这两种写法的区别在于v-text会将内容转化为字符串 而v-html会自动将标签部分转为标签
结果如下
列表渲染
v-for
在需要循环的项添加v-for 而不是在父级添加
结果如下
为奇数列表添加odd的class
当然也可以在模板中使用对象的方式
那么相应的html中内容
将其他组件的内容渲染进app.vue
将组件componentA引入 记得要在当前的组件中添加components: {componentA}
列表更新
支持的列表更新方法
不支持的方法
filter、concat、slice
还有
1.直接为列表某一项赋值 2.改变列表的长度
html写法
组件
点击一次就添加一个 pinaapple256
*如果想直接点击按钮时更新第二项列表呢?
标签属性、条件渲染
v-bind绑定属性
*可以缩写 直接写:href=“link”也是可以的
通过v-bind还可以绑定class 和普通的class不冲突
通过控制组件中的classStr的布尔值来达到显示哪个class
例如
为true就显示出来 false不显示
*还可以数组和对象混合绑定
条件渲染
v-if v-show
配置isPartA为true
添加一个method
点击按钮就可以实现partA和B的切换
注意v-if 和v-show的区别
v-if的内容所以<!---->的形式存放的
v-show是以display:none来控制隐藏与显示
v-if
vs v-show
v-if
是“真正的”条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下, v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说, v-if
有更高的切换开销,而 v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show
较好;如果在运行时条件不太可能改变,则使用 v-if
较好。
v-else
用于与v-if和v-show配合
事件绑定
v-on缩写 例如v-on:click=“xxxx” 缩写为@click=“xxx”
阻止冒泡的修改器写法
另外一种常见的修改写法
摁下13的时候触发
onkeydown方法
自定义事件
引入子组件
自定义了一个事件 my-event
如何触发这个事件呢?
转到子组件中
回到父组件
点击按钮 结果如下
表单事件绑定
v-model
结果
实现了双向绑定
v-model的修饰符
v-model.lazy会在输入完成之后会修改右侧的内容或者是点enter或者失去焦点的时候更新
v-model.number会将myVal转为number类型 例如 修改 {{typeof myVal}} 输入数字 右侧显示number 输入字母 显示string(默认都是string)
v-model.trim会自动裁剪掉空格 在输入框中输入空格会被自动滤过
checkbox
修改myVal:[ ]
结果如下
type=radio同理 只不过myVal又改回了 “ ”;
select
myVal改成0
选项也是列表 通常配合v-for来使用
自定义组件v-select
vSelect.vue文件
后面会有更细致的讲解
tips:
VUE 单页面中,如何使用JQUERY 插件,如:ckplayer.js 这些插件,用VUE单页会报错的,报的是插件内部的一些API 找不到了
建议先去github上找找有没有已经集成好的vue 类似或者相同的插件。如果实在没有,你可以把jquery和ckplayer.js放到static目录下,在index.html直接在头部用 <script> 引入进来。
这样引入的对象也可以在组件里用,因为通常对象都放在顶层window下。
计算属性
模板内的表达式是非常便利的,但是它们实际上只用于简单的运算。在模板中放入太多的逻辑会让模板过重且难以维护。例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
|
在这个地方,模板不再简单和清晰。你必须看一段时间才能意识到,这里是想要显示变量 message
的翻转字符串。当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。
这就是对于任何复杂逻辑,你都应当使用计算属性的原因。
基础例子
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
|
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
})
|
结果:
Original message: "Hello"
Computed reversed message: "olleH"
这里我们声明了一个计算属性 reversedMessage
。我们提供的函数将用作属性 vm.reversedMessage
的 getter 函数:
console.log(vm.reversedMessage) // -> 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // -> 'eybdooG'
|
你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage
依赖于 vm.message
,因此当 vm.message
发生改变时,所有依赖于 vm.reversedMessage
的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有连带影响 (side effect),这使得它易于测试和推理。
计算属性和method方法
我们可以将同一函数定义为一个 method 而不是一个计算属性。对于最终的结果,两种方式确实是相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的
计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message
还没有发生改变,多次访问 reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数。
这也同样意味着下面的计算属性将不再更新,因为 Date.now()
不是响应式依赖:
computed: {
now: function () {
return Date.now()
}
}
|
相比之下,每当触发重新渲染时,method 调用方式将总是再次执行函数。
我们为什么需要缓存?假设我们有一个性能开销比较大的的计算属性 A,它需要遍历一个极大的数组和做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用 method 替代。
如果改成return this.myValue + ‘end’
再或者改成return this.myValue.replace(/\d/g, "")
就会自动将数字替换掉
第二种实现方法
通过在methods中编写一个函数
*两者的区别 computed对myValue依赖大 myValue不更新那么computed就固定了
例如将return的语句都换成 Date.now() 那么computed的时间是最开始的时间 固定了 而methods的时间随着每次变化而变化
数据监听
<input type="text" v-model="myVal">
打印结果为
监听的使用小例子
假设有这么一组列表
绑定几种事件 需要在每次改变列表的时候提醒一下 于是定义了一个methods tellUser
这样每次写在其他函数后面很麻烦
于是通过watch
组件之间的通信
根组件main.js
通过实例化对象
中间通过配置文件 app.vue
父组件和子组件
需要注意的有三点:
1.把子组件import进来
2.components:{
a,
b,
...
}
3.使用子组件的标签 例如 ComAHasChild 最好是转为<com-a-has-child>的形式 在1.0版本支持这种写法 而2.0可以直接的<ComAHasChild>
第二种方式(好处在于可以动态引入模板组件)
用变量的形式 可以修改变量来达到修改模板的效果
父子组件之间传递信息
假如父组件中有这么一个number
要把这个number渲染到子组件中
子组件应该用props
这样渲染后 number相当于子组件的data中的一个属性了(就像hello一样)
需要注意的是 驼峰和-之间的转换
我们这里的number-to-do传递是静态值
那么如何传递动态值呢
子组件中
my-value接受number或者string类型
emit在前面自定义组件中使用过
如果父组件想把一个模板传给子组件呢
在子组件中通过<slot>标签接受
假如<com-a>
<p>xxxx</p>
<span>xxxx<span>
</com-a>
中让p成为插孔 那么例如这样
子组件中如下
结果如下
动态组件
如果有两个子组件 com-a com-b 需要来回切换 我们可以使用keep-alive这个内置标签来缓存
过渡效果
可以实现在文字出现和隐藏的中间有一个过渡的动画效果
不同的阶段有不同的类名
name是自己定义的 具体动画效果在style中写
来定义另外一种效果
name=my-trans
当然也可以对动态组件添加过渡
添加一个toggle方法
这样做有一个问题
在页面中显示的顺序是在另外一个切换进页面后之前一个才会消失 视觉效果不好
默认的model是in-out 先进后出 修改一下就可以啦
*还有一个问题是遇到标签名相同时 动画不起作用了?
记得要使用key来区分
使用js来实现过渡
js通过绑定事件控制
例子
.animate-p{
position:absolute;
left:0;
top:0;
}
!!!如果需要使用vue的同时使用jquery怎么办
建议放到index的head中引入jquery文件
jquery放在static目录下,在index.html里直接用script标签直接引入,这是我总结下来最简单的方法,当时通常来说,用了vuejs就不要再用jquery了,过渡效果vuejs都能用,如果仅为了过渡效果就引入jquery这么大一个库不太值得,可以去找一些专门过渡效果的库
自定义组件
第一种方法
局部自定义组件
第二种方法 全局组件
在main.js中
vue.director有inserted和bind 在内部console 先打印出bind 再打印insert
vue.director中的内容
接受v-css的value遍历后整合传入arr中 再设置为当前元素的css内容
*在main.js写全局指令Vue.directive报错了
Vue.directive不能写在new vue后面不然会报错的
插件
在pakeage.json中
可以看到项目所依赖的dependencies
它们都是独立于vue的
下载引入后
需要vue.use才能生效
*Var vueRouter=require();和 Import vueRouter from vue-router;有什么区别吗
没区别,require是 AMD那套模块化规则, import是es6的语法,原来为什么会有require,是因为js本身没法实现模块化,现在es6(es2015)有了。
这两种在vue脚手架项目里都会被处理,import会被babel处理,然后被webpack处理,具体的没看,babel可能也是把import转成require。 require直接会被webpack的模块处理机制处理掉。
对开发者来说是一样的,没啥区别。
*<style scoped> scoped限制css只对这个组件生效
安装vue-cli
cnpm install vue-cli -g
vue --help 查看
vue -V显示版本号
vue list查看可以使用的模板
vue init webpack 使用webpack这个模板
初始完毕后
cd vuedemo3 (这里是自己的项目名称)
在vuedemo3(也就是有package.json的文件夹里) cnpm install 会将项目的依赖安装到node_modules中
最后npm run dev 给出一个端口 打开
npm run build 会生成一个dist文件
vue-router 路由 根据不同的url跳转到不同页面
单页面应用 不刷新页面实现跳转
安装路由 cnpm install vue-router --save
然后在main.js中
vue.use(router);
history模式直接访问页面就是不带#的。
app.vue
<template> <div id="app"> <img src="./assets/logo.png"> <router-view></router-view> <router-link :to="{path:'apple'}">to apple</router-link> <router-link :to="{path:'banana'}">to banana </router-link> </div> </template> <script> import HelloWorld from './components/HelloWorld.vue'//./必须要有 export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
main.js
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import Apple from './components/apple' import Banana from './components/banana' Vue.config.productionTip = false Vue.use(router); let rout = new router({ mode: 'history', routes: [ { path: '/apple', component: Apple }, { path: '/banana', components: Banana } ] }); /* eslint-disable no-new */ new Vue({ el: '#app', router : rout, components: { App }, template: '<App/>' })
设置路由参数
* :后面的是被注册到params中的参数 而后面如果不带: 需要严格按后面的来 例如 /apple/:color/detail 这个detail不能改动
然后在页面中设置 例如 red
通过$route.params 在控制台中会打印出red
当然也可以<p>{{$route.params.color}} </p>显示在页面中
路由参数有什么具体的应用场景
页面跳转要传参,比如用户列表点到用户页面,可以把用户id放到路由参数里
VUE怎么引JQuery
最方便的方法是在index.html里引入 jquery用线上的或者放到static目录下
路由嵌套
如果一个项目有个100个子组件 ,这些子组件都要在main.js import?
不用,在哪里用在哪里import, webpack会处理路由视图 路由重定向
地址前面加/代表根目录
这样可以直接在router-link里设置参数
默认是a标签 如果想改成其他标签 可以使用tag
导航还可以使用编程式导航
在main.js中
通过router.push的方式
beforeEach在每次路由跳转前生效
命名导航
通过name的方式
以示区分
重定向
在访问根目录的时候重定向到apple
路由视图中<router-view></router-view>使用name的话在main.js中component要改成components
路由重定向和多个<router-view/>有什么用
路由重定向,比如首页叫做 index页面,访问是 localhost:8080/index, 就可以把根目录的访问重定向到index, 把 / 重定向到/index。 还有就是有些页面是不允许被访问的,或者两个地址关联到同一个页面,比如你可以设定 /dt 重定向到/detail 。
多个router-view可以多重控制路由组件,每块view展示不同的组件内容,还可以实现子路由
没理解命名视图,能讲个应用场景?
命名视图可以通过name来区分router-view,可以给一个路径设置不同的 视图组件,相当于吧页面的内容,边栏等部分拆分开,我想到的应用场景是,有个页面用sidebarA,有的用sidebarB,在路由配置的时候就可以简单得设置,不需要在页面组件层级来做,同时不同的sidebar还都是独立的非耦合组件。
过渡动画应用到路由中
keep-alive实现缓存 避免浪费资源
vuex
假如有一个购物车 存在页面各处 在某一处改变购物车的存放商品 其他地方都会改变
示意图
安装vuex
cnpm install vuex --save
全局使用
?????
异步请求
actions 状态里的 函数内 参数 context是什么啊
context是一个内容对象,包含这个vuex整体的其他属性,state,mutation等等,你可以打印出来看看