{}相当于new object,
先把基础的Vue学好,之后再用脚手架,就能够融会贯通了!!!
vue对象中的几个主要对象:
new Vue({
el:'app', //作用于哪个模板
data:{} //存放vue组件的数据
methods:{} //dom绑定事件的书写区
computed:{} //计算属性,对于任何复杂逻辑,你都应当使用计算属性,里面放的是函数!
directives: {} //自定义指令
components:{} //自定义组件
});
//根组件
new Vue({
data:{} //存放vue组件的数据
methods:{} //dom绑定事件的书写区
computed:{}
//子组件
component:{
data:{} //存放vue组件的数据
methods:{} //dom绑定事件的书写区
computed:{}
}
});
一:页面渲染( Rendering )
1,数据绑定
数据绑定最常见的形式就是使用“ Mustache” 语法 ( 双大括号 ) 的文本插值
{{msg}}
可以在双大括号中使用 Javascript 表达式
{{ message.split('').reverse().join('') }}
2,计算属性
模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的
逻辑会让模板过重且难以维护。
<div id="example">{{ message.split('').reverse().join('') }}</div>
对于任何复杂逻辑,你都应当使用计算属性
<div id="example">
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var app = new Vue({
el: '#example',data: {message: 'Hello'},
computed: {
reversedMessage: function ()
{
return this.message.split('').reverse().join('')
}
}})
3,属性的绑定
指令 (Directives) 是带有 v- 前缀的特殊属性,指令的职责是,当表达式的值改变时,将
其产生的连带影响,响应式地作用于 DOM 。一些指令能够接收一个“ ” 参数 ,在指令名称
之后以冒号表示。
v-bind 指令可以用于响应式地更新 HTML 属性,简写形式为 ":"
<a v-bind:href="url"></a>
4,事件的绑定
v-on 指令用于监听 DOM 事件,参数为事件名称,引号内为绑定的事件处理函数或者是
Javascript 代码(不推荐)。简写形式为 "@"
<a v-on:click="doSomething"></a>
4-2
事件修饰符
<form v-on:submit.prevent="onSubmit"></form>
类似的还有停止冒泡( .stop ) , 只当事件在当前元素本身时触发( .self ),仅触发一次 事件( .once )
键值修饰符
<input v-on:keyup.13=“submit”> 13 可以使用 .submit 代替
.enter 、 .tab 、 .delete 、 .esc 、 .space 、 .up 、 .down 、 .left 、 .right
5,条件渲染( v-if )
根据给定条件判断决定是否显示元素
<h1 v-if="type === 'A'">A</h1>
<h1 v-else-if="type === 'B'">B</h1>
<h1 v-else>C</h1>
条件渲染( v-show )
与 v-if 不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。 v-show 是简单地切换元素的 CSS 属性 display
注意, v-show 不支持 <template> 语法,也不支持 v-else 。 如果需要非常频繁地切换元素,则使用 v-show 较好
6, 列表渲染( v-for )
v-for 指令根据一组数组的选项列表进行渲染,使用 item in items 形式的特殊语法
items 是源数据数组并且 item 是数组元素迭代的别名
7,表单输入绑定
v-model 指令可以在表单控件元素上创建双向数据绑定(不会用于文本元素)
1 . 单行文本、多行文本框、单选按钮、下拉菜单简单使用 v-model 绑定即可
<input v-model="message"><p>Message is: {{ message }}</p>
2 . 复选框(绑定到一个数组中)
<input type="checkbox" value="Jack" v-model="checkedNames">
<input type="checkbox" value="Jack" v-model="checkedNames">
data:{checkedNames:[]}
二:动画(animation)
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。 包括以下工具:
1,在 CSS 过渡和动画中自动应用 class
2,可以配合使用第三方 CSS 动画库,如 Animate.css
3,在过渡钩子函数中使用 JavaScript 直接操作 DOM
4,可以配合使用第三方 JavaScript 动画库,如 Velocity.js
Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添 加 entering/leaving 过渡
在进入 / 离开的过渡中,会有 6 个 class 切换, v- 是这些类名的前缀,可以在transition 标签中设定 name 属性改变该前缀。
v-enter(进入前) v-enter-active(进入中) v-enter-to(进入后) v-leave(离开前) v-leave-active(离开中) v-leave-to(离开后)
1,自定义过渡样式
<button @click='show = !show'> 切换 </button>
<transition name='fade'>
<p v-if='show'> hello vue </p>
</transition>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s
}
.fade-enter, .fade-leave-to {
opacity: 0
}
</style>
2,自定义过渡的类名,和其他第三方动画库,animate.css结合使用
enter-class 、 enter-active-class 、 enter-to-class
leave-class 、 leave-active-class 、 leave-to-class
<link rel="stylesheet" href="../css/animate.css">
<button @click='show = !show'> 切换 </button>
<transition
enter-active-class='animated bounce'
leave-active-class='animated bounce'>
<p v-if='show'> hello vue </p>
</transition>
3,javascript 钩子,可以通过 js 钩子定义动画,结合第三方动画库 Velocity.js( 以及插件Velocity.ui.js)
before-enter 、 enter 、 after-enter 、 before-leave 、 leave 、 after-leave
<script src="../js/velocity.min.js"></script>
<script src="../js/velocity.ui.js"></script>
<button @click='show = !show'> 切换 </button>
<transition @enter='enter' @leave='leave'>
<p v-if='show'> hello vue </p>
</transition>
methods:{
enter:function(el,done){
Velocity(el,"callout.pulse", { duration: 650 ,complete:done}) },
leave:function(el,done){
Velocity(el,"callout.bounce", { duration: 1500 ,complete:done}) }
}
4,列表过渡
为了同时渲染整个列表,使用 <transition-group> ,不同于 <transition> ,它会
以一个真实元素呈现:默认为一个 <span> 。你也可以通过 tag 特性更换为其
他元素,内部元素 总是需要 提供唯一的 key 属性值
<script src="../js/velocity.min.js"></script>
<transition-group tag="ul" @enter="enter" @leave="leave" >
<li v-for='name in nameList' :key='name'>{{name}}</li>
</transition-group>
methods:{
enter:function(el,done){
Velocity(el,{ opacity: 1, height: '1.6em' },{ complete: done })},
leave:function(el,done){
Velocity(el,{ opacity: 0, height: 0 },{ complete: done })}
}
三:组件
组件 (Component) 是 Vue.js 最强大的功能之一。在较高层面上,组件是自定义元素,template用反引号``, 比用引号方便
1,全局注册
Vue.component('my-component', {
// 构造 Vue 实例时传入的选项大多数都可以在组件里使用。 data 为函数
template : '<div>A custom component!</div>'
})
组件在注册之后,便可以作为自定义元素 <my-component></my-component> 在一个实例的模板中使用。注意确保在初始化根实例之前注册
组件(即 new Vue({}))
2,局部注册
局部注册 不必把每个组件都注册到全局。我们可以通过某个 Vue 实例 / 组件的实例
选择 components 注册仅在其作用域中可用的组件。
var app = new Vue({
el:'#app',
components:{
'my-component':{ template:'<h2>hello component</h2>'}
}
});
3,自定义组件的使用
1,直接使用
<my-row></my-row>
2,通过 is 关键字使用
第一种方式会受到 HTML 本身的限制,因为 Vue 只有在浏览器解析、规范化模
板之后才能获取其内容,像 <ul> 、 <ol> 、 <table> 、 <select> 这样的元素里允
许包含的元素有限制。
<table>
<my-row></my-row>
</table>
变通方法:
<table>
<tr is="my-row"></tr>
</table>
4,父子组件通信
在 Vue 中,父子组件的关系可以总结为 prop 向下(子)传递,事件向上(父)传递 。
父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息
1,父子组件 -props
子组件要显式地用 props 选项声明它预期的数据,父组件使用 props 中声明
的同名属性进行注入
var app = new Vue({
el:'#app',
data:{name:'hello parent'},
components:{
'my-son':{
props:['name'],// 不区分大小写
data:function(){return {msg:'hello son' }},
template:'<div> 子组件, {{msg}},{{name}}</div>'
}
}
});
<div id="app"><my-son :name='name'></my-son></div>
2,父子组件 - 自定义事件
子组件使用自定义事件系统与父组件通信,每个 Vue 实例都实现了事件接口,使用 $on(eventName) 监听事件,
使用 $emit(eventName) 触发事件 。父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件
<div id="app">
<p><b>total:</b>{{total}}</p>
<button-counter @increment='incrementTotal'></button-counter> //监听
<button-counter @increment=‘incrementTotal’></button-counter>
</div>
components:{
'button-counter':{
‘template’:‘<button @click=“incrementCounter”>{{counter}}</button>’,
data:function(){ return {counter:0}},
methods:{
incrementCounter:function(){
this.counter++;
this.$emit('increment'); // 向父组件发射事件
}
} }
3,插槽
要想在子组件中使用父组件提供的模板就需要使用到插槽。除非子组件模板包含至少一个 <slot> 插口,否则父组件的内容将会被丢弃。
<div id="app">
<my-component><h3>hello Vue</h3></my-component>
</div>
components:{
'my-component':{
template:'<div><h2>hello my-component</h2><slot>default slot</slot></div>'
}
}
也可以为插槽提供名字,这样可以在一个子组件中插入多个父组件提供的模板。
<slot name="header"></slot>
<slot name="footer"></slot>
<h1 slot="header"> 这里可能是一个页面标题 </h1>
<p slot="footer"> 这里有一些联系信息 </p>
4,作用域插槽
作用域插槽是一种特殊类型的插槽,用作一个 ( 能被传递数据的 ) 可重用模板,来代替已经渲染好的元素。
在子组件中,只需将数据传递到插槽,在组件中,具有特殊特性 slot-scope 的 <template> 元素必须存在,
表示它是作用域插槽的模板。
Vue.component('my-ul',{
template:‘<ul><slot v-for=“name in names”
:text="name"></slot></ul>',
data:function(){return {names:['terry','larry','tom','jacky']}}
});
Vue.component('my-list',{
// 允许使用者自定义如何渲染列表的每一项
template:‘<my-ul><template slot-scope=“props” >
<li>{{props.text}}</li></template></my-ul>'
});
<div id=’app’>
<my-list></my-list>
</div>
5,动态组件---可以用vue插件--路由来代替
通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以让 多个组件可以使用同一个挂载点,并动态切换。
new Vue({
data:{ currentView:'my-com2' },
components:{
'my-com1':{ template:'<div>component1</div>' },
'my-com2':{ template:'<div>component2</div>' },
'my-com3':{ template:'<div>component3</div>' }
}
})
<component v-bind:is="currentView"></component>
学习组件后的总结:
vue就相当于一个组件,它作用于 el:#app 这个模板,这个模板里的方法,写在methods对象中,模板里的数据写在data对象中.....
一个组件是一个作用域,它们各自的方法,数据写在相应的组件里。
template模板中,一定要用一个根标签包裹!
四:其他
1,自定义指令
全局注册
vue.directive(directiveName,options)
局部注册
new Vue({
directives: {
directiveName:options
}
});
指令定义函数提供了几个钩子函数:
bind 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
inserted 被绑定元素插入父节点时调用
钩子函数参数
el 指令所绑定的元素,可以用来直接操作 DOM
binding 一个对象,包含了指令相关的信息(参数 binding.argument )
2,过滤器
Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两
个地方: mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达
式的尾部,由“ |” 管道 符指示。
<div id="app"> {{msg | toUpper(arg1,arg2)}}</div>
new Vue({
el:"#app",
data:{msg:'hello world' },
filters:{
toUpper:function(val,arg1,arg2){return val.toUpperCase();}
}
});
3,插件的使用
1,通过 script 标签导入,则不需要
2,npm,如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装该功能
var Vue = require('vue')
var VueRouter = require('vue-router')
// 不要忘了调用此方法
Vue.use(VueRouter)
VUEX:
特点:将组件的数据进行集中化管理,将数据以及数据相关操作抽离出来进行统一管理
只有mutations可以修改state的值(虽然actions也可以,但是不要这样做)
1,state,mutations,actions作用
<script>
var store = new Vuex.Store({
//保存所有的数据
state:{
number:0
},
//突变,用于修改state的值 必须是同步
mutations:{
updateNumber:function(state,value){
state.number = value;
}
},
//动作,用于调用突变,执行数据的改变 context即store存贮对象 ,可以包含任意异步操作
actions:{
increment:function(context){
var value = context.state.number+2;
context.commit('updateNumber',value);
},
decrease:function(context){
var value = context.state.number-2;
context.commit('updateNumber',value);
}
}
});
new Vue({
el:'#app',
store:store,
//用computed计算传值
computed:{
...Vuex.mapState(['number'])
},
methods:{
...Vuex.mapActions(['increment','decrease'])
}
});
</script>
2,vue组件怎么访问到state中的数据
通过在根实例中注册 store 选项,该 store 实例会注入到根组件
下的所有子组件中,且子组件能通过 this.$store 访问到。
new Vue({
el:'#app',
store:store,
computed: {count () {return this.$store.state.count}}
})
2-1访问简化方式:
--------
<div>{{num}}---{{name}}</div>
--------
state:{
number:0,
name:'kb'
}
--------
computed:{
//div显示的值要和state的值一致
// ...Vuex.mapState(['number','name'])
//若不一致,可用如下方法
...Vuex.mapState({'num':'number','name':'name'})
}
3, 定义 Getter
当我们要过滤从state获取到的数据,可以在 store 中定义“ getter” (可以认为是 store 的计算属性)
3-1mapGetters 辅助函数
getters:{
boys:function(state){
return state.students.filter(
function(item){
return item.gender == 'male'
}
)
}
}
...Vuex.mapGetters(['boys'])
//若不一致,可用如下方法
//...Vuex.mapGetters({'boys2':'boys'})
4,怎么在vue中调用mutations方法(使用commit)
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation ,必须是同步操作。
4-1,提交载荷( 就是传参的意思 )
mutations:{
add:function(state,e){
state.events.push(e)
}
}
----------------
methods{
方法1: this.$store.commit('add',Object.assign({},this.form));
//Object.assign({目标对象},{源对象}),Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
}
方法2:
...Vuex.mapMutations({add:‘increment'}) // 将 `this.add()` 映射为 `this.$store.commit('increment')`
this.add(param);
5,怎么在vue中调用Actions方法(使用dispatch方法)
Action 类似于 mutation ,不同在于, Action 提交的对象的是 mutation ,而不是直接变更状
态,并且 Action 可以包含任意异步操作, Action 函数接受一个与 store 实例具有相同
方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation ,或
者通过 context.state 和 context.getters 来获取 state 和 getters 。
-------------
methods:{
//方法1:this.$store.dispatch('increment',{amount:10})
方法2:...Vuex.mapActions(['increment'])
this.increament();//直接执行actions中的increment方法 方法2
}
什么时候需要承诺?当调用者需要知道这个异步操作执行成功与否的时候!
6,当A调用B,A需要当B成功后执行一段代码,失败后执行一段代码(或者需要等B返回一个结果),而B是异步操作,怎么做?(eg:调用删除方法,等待方法返回结果,但是是异步的,没法等)
在B中使用Promise方法,当B执行成功或失败后,会执行相应的成功,失败方法
deleteBatch:function(context,ids){
//promise用于返回状态给调用者的!!!
return new Promise(function(resolve,reject){
//$.ajax()......
$.ajax({
type: "GET",
url: 'http://localhost:8080/hello4',
success: function (data) {
console.log("访问成功");
// alert(data);
//刷新,当删除成功后重新执行查询操作
context.dispatch('findAll');
resolve('success'); //成功执行该方法
},
error:function (data) {
console.log("访问失败");
reject(data); //失败执行该方法
}
});
});
}
--------------------
methods: {
handleDelete:function(index,row){
this.deleteBatch(row.age).then(function(msg){alert(msg)}).catch(function(e){alert(e)})
//当访问的函数返回Promise对象是,可以用.then(成功执行).catch(失败执行)
}
}
webpack结合Vue:
webpack作用:将模块打包,简化前端开发,导入模块用import,再不用script,link引入js,css了。css,js,图片都写在src目录下,因为
一切皆模块,dist存放打包后的文件
1,本地安装
npm install –-save-dev webpack
2,使用方式
初始化项目并安装 webpack
npm init –y
npm install --save-dev webpack
2-1, 编写配置文件 webpack.config.js (放在项目目录下)
——
module.exports = {
entry: './src/app.js', //打包入口文件(从哪开始打包!)
output:{ //打包输出目录
path: __dirname+'/dist', //—__dirname:代表本文件目录的绝对路径
filename:'app.bundle.js' //表示打包后文件名
}
};
使用 npm 脚本执行打包操作 在package.json中添加
"scripts": { "build": "webpack" } //npm run build 就可以打包项目了
以上为webpack环境的搭建!!!
Loader:加载器(将其他类型的文件加载成可打包类型,css,png...)
3,如何将es6代码打包成es5代码,需要通过babel(浏览器默认是不支持es6的,除了火狐可以解析)
3-1,安装命令 npm install --save-dev babel-core babel-preset-env babel-loader //babel一系列东东
//配置
3-2,需要在项目目录下新建一个.babelrc文件
{
"presets":["env"]
}
3-3,在webpack.config.js文件内的module 添加{ test:/.js$/, exclude: /node_modules/, use: 'babel-loader' }
3-4,
安装过程可能遇到的错误:
1, "babel-core": "^6.26.3"和"babel-loader": "^7.1.5"版本不兼容,按照报错提示再次安装即可
2,webpack.config.js文件的module属性配置不对,可以按照官网的方法配置!(即rules,不用loaders)
4,如何将css也弄成模块化(webpack默认只将js文件模块化,图片,css等等得安装loader才可以模块化)
4-1 安装npm install --save-dev css-loader style-loader
4-2 配置:在webpack.config.js文件内的module 添加{ test: /.css$/, use: [
{loader: 'style-loader' },
{ loader: 'css-loader'}
]}
4-3 使用:在入口文件中import './css/style.css';
5,如何将图片模块化,安装loader
5-1 安装 npm install --save-dev file-loader
5-2 配置 {test:/.(jpg|png|gif)$/,use:'file-loader'}
插件:插件目的在于解决 loader 无法实现的其他事。(前端优化可以想这一点)
1,压缩插件,为了最小化压缩后的代码,提高加载速度
2,webpack4已经升级不支持在plugins里面进行操作,而是放在了optimization里面
3,先安装这个插件 npm install --save-dev uglifyjs-webpack-plugin
4,配置 :在webpack.config.js
var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
output: { comments: false, } //去除注释
}
})
]
}
5,定位错误插件
module.exports = {
devtool: 'eval-source-map'
}
6,webpack-dev-server
webpack-dev-server 是一个简单的 web 服务器,在代码修改后能重新构建代码并且
刷新浏览器。
//安装 npm install --save-dev webpack-dev-server
//配置 module.exports = {
devServer: {
contentBase: './dist' // 服务器服务目录
}
}
//配置 package.json
"scripts":{"start": "webpack-dev-server --open"}
利用 vue 脚脚手架开发 手架开发企企业级应 业级应用
# 全局安装 vue-cli
npm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
vue init webpack my-project
# 安装依赖,走你
cd my-project
npm install
npm run start
安装会出现如下选项,如下选择即可:
? Project name app03
? Project description sc html
? Author kuangbin <981393967@qq.com>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
node_modules文件夹有什么用:
首先要说明,devDependencies与Dependencies都是依赖。你用npm install就会把里面二者所有的模块都安装到node_modules。
那为什么还要个devDependencies呢,这里,devDependencies一般用来放一些对项目运行无用,但能帮助开发的依赖(如测试模块),在实际生产环境中执行npm install --production就只安装Dependencies里的模块,而不会安装devDependencies的模块。
编写项目所需的其它依赖:
npm install element-ui jquery vuex moment(日期格式处理)--save //--save才会保留在package.json中
结合vuex:
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
state模块化他不会为全局声明的,其余是全局声明。
可以调用getter方法,而不直接调用state获取数据(要用命名空间才可以),但是要避免方法名重复!!!,因为都当做全局声明。
App.vue 主视图
index.html 是我们的首页
如何写一个登陆页面以及结合增删改查?
1,app.vue不用动,它包含公共部分,然后添加其他组件,放在这个公共app.vue即可,只需用<router-view/>
2,在router js文件中写上对应的路由映射,记住子路由可以嵌套!
3,写增删改查页面体悟:只需一个saveOrUpdate方法即可,模态框能重复利用就不用重复写!
4,登陆之后应该把登陆数据放在store(公共)中,index页面就根据store的数据进行对应登入者展示
5,注册思想也一致
6,注意后台传null给前台的话,是转化为"空"字符串,因为家里responseBody!(以后判断为:data!=null&&data!=""就不会错)