vue2.0基础知识,及webpack中vue的使用
## 基础指令 ##
[v-cloak]{
Display:none;
}
<p v-cloak>xx{{msg}}xx</p> //解决闪烁问题,xx显示
<p v-text='msg'>xxxx</p> //引入数据,默认没有闪烁问题,xxxx不显示
<p v-html='msg2'>xxxx</p> //引入html
<p v-for='(item,i) in user'>{{item}}</p> //v-for遍历数组
<p v-for='count in 10'>{{ count }}</p> //v-for遍历数字,执行10次
<p v-for='(val,key,i) in user' :key="item.id">{{item}}</p>
//v-for遍历数对象,i为索引,:key为唯一性关联
<input type="button" v-bind:title="mytitle"> //绑定属性的指令,v-bind:可简写为:
<input type="button" v-on:click="show"> //绑定事件方法,v-on: 可简写为@
<p v-if='flag'>xxxx</p> //dom添加删除元素
<p v-show='flag'>xxxx</p> //通过display隐藏元素
var vm= new Vue({
el:"#app",
data:{
msg:"123",
msg2:"<h2>title</h2>",
mytitle:"这是title",
user:[1,2,3,4]
},
methods:{ //绑定事件的方法
show:function(){****
this.msg="改变"
//在方法中改变数据,页面中数据会同步改变,用this引用数据源
}
},
watch:{ //监听data中数据的改变
'mytitle':function(newVal,oldVal){ //oldVal为老的值
Console.log(newVal) //新的值
}
},
computed:{ //设置数据的计算属性,相当于新增数据,有关数据变化,该值也变
'fullMsg':function(){
return this.msg+this.msg2
}
}
})
<p v-cloak>xx{{ fullMsg}}</p> //直接调用计算属性的数据
//{{msg}}双花括号数据显示,其实是省略了该vue对象的this指向,直接调用对象的方法,也可以直接调用类似$route.query等内置的属性和值{{$route.query }}
## 事件修饰符 ##
<input type="button" @click.stop="show"> //阻止事件冒泡
<a href="www.baidu.com" @click.prevent.once="show"></a> //阻止默认行为
## 表单元素中的双向数据绑定v-model ##
<input type="text" v-model="msg"> //input中输入数据,实时更新Vue中data
## 添加样式 ##
### 类名样式 ###
<h1 :class="['thin','italic',flag?'active':'']">xxx</h1>
<h1 :class="['thin','italic',{'active':flag}]">xxx</h1> //两种写法
<h1 :class="{red:true,thin:true}">xxx</h1> //可写对象,key为类名
//其中thin,italic,active都是有样式的类名,flag是Vue中data中设置的数据
### stlye样式 ###
<h1 :style="{color:'red','font-weight':200}">xxx</h1>
<h1 :style="[styleObj1,styleObj2]">xxx</h1>
## 安装Vue调试工具 ##
Vue-devtools chrome插件
## Vue过滤器filer ##
<p>{{ msg | msgFormat }}</p> //过滤显示数据
Vue.filter(‘msgFormat’,function(){ //全局过滤器
return msg.replace(‘a’,’b’);
})
var vm= new Vue({
el:”#app”,
filters:{ //写在实例化Vue对象中filters中的为私有过滤器
fileName:function(data){ //定义过滤器名称
}
}
})
## 按键修饰符 ##
<input type=”text” @keyup.enter=”show”> //enter为按键修饰符,监听回车
//如果不为上述按键可以使用键盘码:@keyup.112=”show”
Vue.config.keyCodes.f2=113; //自定义键盘修饰符
## 自定义指令v-focus ##
Vue.directive(‘focus’,{ //全局设置eyup.112=”show”
bind:function(el,binding){}, //当指令绑定到元素上时,执行,样式相关
inserted:function(el){}, //当元素插入DOM中后执行,js行为相关
updated:function(el){}, //当Vnode更新时执行,可能触发多次
})
var vm= new Vue({ //局部设置
el:”#app”,
directives:{ //自定义私有指令
‘fontWeight’:{
bind:function(el,binding){}
},
‘fontsize’:function(el,binding){
//直接写等同于写入bind和 update中
},
}
})
### 钩函数中,传递的参数意义 ###
## 生命周期 ##
## vue-resource插件发送ajax ##
### 引入插件 ###
Vue.http.options.root=”http://vue.study.rgo”;//全局设置resourse配置项
Vue.http.options.emulateJSON=true
new vue({ //局部配置
http:{
root:’/root’,
headers:{
Authorization:’xxxx’
}
}
})
var vm= new Vue({ //局部设置
el:”#app”,
methods:{ //自定义私有指令
postInfo(){
this.$http.post(url,{params},{options}).then(success,error)
}
}
})
## vue中的动画效果 ##
### 自定义类动画 ###
.name-enter,name-leave-to{ //时间点,动画进入之前/动画离开之后
opacity:0;
transform:translateY(100px);
}
.name-enter-active,name-leave-active{ //入场/离场动画时间段
opacity:0;
transform:translateY(100px);
}
<transition name=”name” mode=”out-in”> //mode设置动画切换模式
<h3 v-if=”flag”>这是动画</h3>
</transition>
### 引入第三方css动画,如animate.css ###
<transition enter-active-class=”bounceIn” leave-active-class=” bounceOut” :duration=”{enter:200}”>
<h3 v-if=”flag” class=”animated”>这是动画</h3>
//加入animated类名动画才生效,也可将类名加在transition标签上
</transition>
### 使用动画钩函数(只演示进场动画) ###
<transition @before-enter=”beforEnter” @ enter=”enter” @after-enter=”afterEnter”>
<h3 v-if=”flag”>这是动画</h3>
</transition>
var vm= new Vue({
el:”#app”,
methods:{
beforeEnter(el){
el.style.transform=”translate(0,0)”
},
enter(el,done){
el.offsetWidth //需要操作offset动画才生效
el.style.transform=”translate(150px,450px)”;
el.style.transition=”all 1s ease”;
done(); //done等同于调用了afterEnter,建议调用
},
afterEnter(el){
this.flag=!this.flag
}
}
})
### v-for创建的标签使用<transition-group>包裹才能实现动画 ###
<transition-group appear tag=”ul”>
//appear属性使整个标签实现渐入效果,tag属性指定transition-group为ul标签,默认为span
<li v-for=”item in list” :key=”item.id”> //如果要为每一个元素设置动画需要key属性
{{item.id}} --- {{item.name}}
</li>
</transition-group>
### 移除动画设置: ###
.v-move{
transition:all 0.6s ease;
}
.v-leave’-active{
position:absolute;
}
## vue中的组件(组件template属性必须用唯一根元素) ##
### 全局组件 ###
var com1=Vue.extend({
template:’<h3>这是组件名称</h3>’;
//使用template定义组件需要的html
})
Vue.component(‘myCom1’,com1) //驼峰命名,标签要变-连接
可合写为:
Vue.component(‘myCom1’, Vue.extend({
template:’<h3>这是组件名称</h3>’;
}))
<div id=”app”>
<my-com1></my-com1>
</div>
### 组件的其他写法 ###
一、
Vue.component(‘myCom1’, {
template:’<h3>这是组件名称</h3>’;
})
二、
<div id=”app”></div>
<template id=”tmp1”> //写在app外面
<h3>这是组件</h3>
</template>
Vue.component(‘myCom1’, {
template:’#tmp1’;
})
### 定义私有组 ###
var vm2= new Vue({
el:”#app2”,
components:{
tmp1:{
template:’<h3>私有组件tmp1</h3>’;
}
}
})
### 组件中的数据和方法 ###
Vue.component(‘myCom1’, {
template:’#tmp1’;
data:function(){ //data必须为返回一个对象的函数
return:{count:0}
},
methods:{
increment(){
this.count++
}
}
})
### 组件切换 ###
<div id=”app”>
<a @click.prevent=”comName=’login’”>登录</a>
<a @click.prevent=”comName=’register’”>注册</a>
<component :is=”comName”></component>
//vue中定义用于组件占位的标签
</div>
### 组件动画 ###
<transition mode=”out-in”> //mode设置动画切换模式
<component :is=”comName”></component>
</transition>
### 父子组件之间数据/方法传递 ###
<div id=”app”>
//在子组件绑定一个私有属性,通过这个属性传递数据
<comp1 v-bind:parentmsg=”msg” v-on:func=”show”></comp1>
</div>
var vm2= new Vue({
el:"#app",
data:{
msg:"123 父组件数据"
},
methods:{
show(data1,data2){
console.log(‘调用了父组件方法’)
}
},
components:{
comp1:{
template:’<h3 @click=”myclick”>私有组件{{ parentmsg }}</h3>’,
data(){ //子组件私有的数据,可读可写
return {title:”123”,content:”xxx”}
},
props:[‘parentmsg’], //在props中引入父组件传入的数据,只读
methods:{
myclick(){
this.$emit(‘func’,112,333) //调用父组件方法,112,333为传入参数
}
}
}
}
})
## 通过ref属性获取dom和子组件的数据/方法 ##
<h2 ref=”myh2”>这是h2标签</h2> //这是dom
<login ref=”mylogin”></login> //这是组件
var login={
template:’<h1>登录组件</h1>’,
data:function(){ //data必须为返回一个对象的函数
return:{msg:”这是登录信息”}
},
methods:{
show(){
console.log(‘show’)
}
}
}
var vm2= new Vue({
el:”#app”,
data:{
msg:”123 父组件数据”
},
methods:{
getElement(){
this.$refs.myh2 //获取dom
this.$refs.login.msg //获取子组件的data
this.$refs.show() //获取子组件的方法
}
},
components:{
login
}
})
## vue中的路由vue-router ##
1. 前端路由原理
hash的使用:
http://www.baidu.com#/login //网页url中#后面的部分称为hash,当页面hash发生改变时,页面不会向后端发送http请求,页面也不会跳转,但是页面本身会发生部分显示改变,例如使用锚点展示显示内容,这样可以使用hash来完成单页面的应用
2.vue-router的安装
在模块化工程(webpack)中必须使用Vue.use()明确安装路由功能
import Vue from ‘vue’
import VueRouter from ‘vue-router’
Vue.use(VueRouter) //给vue注册router功能
3.vue-router的基本使用方法
<div id=”app”>
//使用a标签点击跳转路由
<a href=”#/login?id=10&name=jim”>登录</a> //直接在url中传递参数
<a href=”#/register/10/jack”>注册</a> //url传递参数的第二种方式,传入设置规则的参数
//使用router-link标签点击跳转路由,特殊标签,默认渲染为a标签
<router-link to=”/login”>登录</router-link>
<router-link to=”/ register” tag=”span”>注册</router-link> //渲染为span
<router-view></ router-view > //特殊标签,相当于路由的占位符
//可使用动画标签设置路由动画切换
<transition name=”name” mode=”out-in”> //mode设置动画切换模式
<router-view></ router-view > //此处路由会动画切入
</transition>
</div>
//url第一种传参解析
var login={
template:’<h1>登录组件----{{$route.query.id}}---{{$route.query.name}}</h1>’,
data(){
return {msg:’123’}
},
created(){ //组件生命周期创建之初后,
Console.log(this.$route.query.id) //获取路由url中传递的参数
}
}
//url第二种传参解析
var register={
template:’<h1>注册组件----{{$route. params.id}}---{{$route. params.name}}</h1>’,
data(){
return {msg:’123’}
},
created(){ //组件生命周期创建之初后,
console.log(this.$route.params.id) //获取路由url中传递的参数
}
}
var routerObj=new VueRouter({ //创建路由对象
routes:[
{path:’/’,redirect: login }, //重定向
{path:’/login’,comppnent: login },
{path:’/register/:id/:name’,comppnent: register }, //设置路由参数
],
//被激活的类名为router-link-active,可设置当前选中路径标签的样式,也可如下操作
linkActiveClass:’myactive’ //设置选中高亮的标签的样式类名
})
var vm=new Vue({
el:”#app”,
data:{},
methods:{},
router: routerObj, //引入路由对象
watch:{ //通过$route.path监听路由的改变
‘$route.path’:function(newVal, oldVal){
console.log(oldVal)
}
}
})
4.设置子路由
<div id=”app”>
<router-link to=”/account”>Account</router-link>
<router-view></ router-view >
</div>
<template id=tmp1>
<div>
<h2>这是Account组件</h2>
<router-link to=”/account/login”>登录</router-link>
<router-link to=” /account/ register” tag=”span”>注册</router-link>
<router-view></ router-view >
</div>
</template>
var account={
template:’#tmp1’,
}
var login={
template:’<h1>登录组件</h1>’,
}
var register={
template:’<h1>注册组件</h1>’,
}
var routerObj=new VueRouter({ //创建路由对象
routes:[
{
path:’/account’,
component: account,
children:[ //设置子路由 {path:’login’,component:login}, //路径不要写斜线,不然认为到根路径
{path:’register’,component: register },
]
},
],
})
5.设置多个路由
<div id=”app”>
<router-view></ router-view >
<router-view name=”left”></ router-view >
<router-view name=”right”></ router-view >
</div>
var routerObj=new VueRouter({ //创建路由对象
routes:[
{
path:’/account’,
components: { //显示多个路由使用conponents复数,key为router-view中的name
‘default’:header, //第一个可以用默认组件name:default,不写name
‘left’:leftBox,
‘main’:mainBox
},
},
],
})
## json格式文件中不能写注释 ##
## vue中的render方法替换组件 ##
<div id="app">
<login></login>
</div>
var login={
template:"<h1>这是登录组件</h1>"
}
var vm=new Vue({
el:'#app'
data:{},
methods:{},
render:function(createElements){ //传递的参数是一个方法,能够将指定的模板组件渲染为html
return createElements(login) //这类的return结合会替换vue中el指定的那个容器,本案例中替换id="app"容器
}
})
## 在webpack中使用vue ##
import Vue from 'vue' //引入vue,其实默认引入的是vue.runtime版本在webpack中使用的,在网页中使用的话需要引入vue.js
引入规则:
1. 查找项目中的node_modules文件夹
2. 在node_modules文件夹下找到对应的vue文件夹
3. 在vue文件夹中,找到package.json包的配置文件
4. 在package.json中,查找main属性,里面写入了包的入口路径
修改路径:
//在webpack.config.js文件中添加规则即可
resolve:{
alias:{ //修改vue导入的路径
"vue$":"vue/dist/vue.js"
}
}
//也可直接引入
import Vue from '../node_modules/vue/dist/vue.js'
### 创建.vue文件使用webpack中默认的vue.runtime来构建组件 ###
1. 安装loader:vue-loader vue-template-compiler
2. webpack.config中配置loader:{test:/\.vue$/,use:'vue-loader'}
3. 创建包含template script style的xxxx.vue文件
<template>
<h1>这是登录组件</h1>
</template>
<script></script>
<style></style>
4. 在需要渲染组件的页面使用render引入组件
import xxxx from './xxxx.vue'
var vm=new Vue({
el:'#app'
data:{},
methods:{},
render:function(createElements){
return createElements(xxxx)
}
})
## 在webpack中使用vue-router ##
新建route.js文件并设置路由
import VueRouter from 'vue-router' //导入路由包
Vue.ues(VueRouter) //安装vueRouter
//导入组件
import account from './main/Acount.vue'
import goodsList from './main/GoodsList.vue'
import login from './main/login.vue'
import register from './main/register.vue'
var router = new VueRouter({ //创建路由对象
routes:[
{
path:'/account',
component:account,
children:[ //设置子组件
{path:'login',component:login},
{path:'register',component:register}
]
},
{path:'/GoodsList',component:goodsList,name:'goodsList'}
]
})
export default router //暴露路由对象
在main.js:
import Vue from 'vue'
import app from './App.vue'
import router from './route.js'
var vm=new Vue({
el:'#app',
render:c=>c(app),
router
})
在App.vue文件中:
<template>
<div>
<h1>这是App组件</h1>
<router-link to="/account">Account</router-link>
<router-link to="/account">Account</router-link>
<rounter-view></router-view>
</div>
</template>
在Account.vue中:
<template>
<div>
<h1>这是Account组件</h1>
<router-link to="/account/login">登录</router-link>
<router-link to="/account/register">注册</router-link>
<rounter-view></router-view>
</div>
</template>
<style lang="scss" scoped> //lang属性指定使用语言,此处使用scss,scoped属性表明样式只对当前组件生效,原理是自动加上一个属性选择器
body{
div{
color:"red"
}
}
</style>
在GoodsList.vue中:
<template>
<div>
<h1>这是GoodsList组件</h1>
</div>
</template>
在index.html中:
<body>
<div id="app"></div>
</body>
如果使用编程式导航(window.location.href)跳转则可通过控制$router.push
this.$router.push("/home/goodsList"+id)
//或者
this.$router.push({path:"/home/goodsList"+id}})
//或者使用路由的name
this.$router.push({name:"goodsList",params:{id}})
## 在父组件中引用子组件 ##
<template>
<comment-box :id="this.id"></comment-box> //父组件向子组件传值
</template>
<script>
//引入子组件页面
import comment from "../subcomponent/comment.vue";
export default{
components:{
"comment-box":comment //设置子组件标签名
}
}
</script>
//在comment.vue中接收父组件传递过来的值
props:['id','max']
//也可写成可以设置值类型的形式
props:{
id:Number,
// 多种类型
propB:[String, Number],
// 必传且是字符串
propC:{
type:String,
required:true
},
// 数字,有默认值
propD:{
type: Number,
default: 100
},
}
//可以通过watch监听props中值的变化
watch:{
max:function(newVal,oldVal){ //监听父组件max的值
}
}
## vuex的使用 ##
vuex是Vue配套的组件公共数据管理工具,可以将组件的一些共享数据保存到vuex中,方便整个程序中的任意组件直接获取或修改公共组件
import Vuex from 'vuex'
Vue.use(Vuex)
//创造一个公共
var store=new Vuex.Store({
state:{ //公共数据集,类似vue中的data
count:0
},
mutations:{ //对公共数据的操作方法,;类似vue中的methods
increment(state,params){ //方法中只能传递两个参数,第一个为公共数据集,第二个为向该方法传递的参数
state.count++;
},
subtract(state,params){
state.count-=(params.a+params.b);
}
},
getters:{ //可以对数据进行获取并包装再返回
optCount:function(state){
return '当前最新的count值是:'+state.count
}
}
})
//挂载公共数据集的数据
const vm = new Vue({
el:'#app',
render:c=>c(App),
store
})
//获取store数据集中的数据
<input type="text" v-model="$store.state.count">
//获取getters中的数据
<h3>{{$store.getters.optCount}}</h3>
//调用公共集中的方法并操作公共集中的数据
methods:{
remove(){
this.$store.commit('substract',{a:2,b:4})
}
}
## es6 export语法使用 ##
在test.js文件定义:
var info={
name:"tabb",
age:18
}
export default info //export default只能出现一次
//暴露多个对象
export var title="这是title"
export var content="这是content"
在另一个test2.js文件中接收test.js中的信息
import test123,{title,content as content123} from './test.js'
{title,content} //这种方式称为按需导出
console.log(tset123) //为export default中的内容
console.log(title) //为额外暴露的内容
console.log(content123) //可以使用as给content起别名
## 使用es6 Promise 处理回调嵌套(回调地狱)##
1. Promise是一个构造函数
2. Promise上有两个回调函数:resolve(成功之后的回调函数),reject(失败之后的回调函数)
3. 在Promise构造函数的Prototype属性上,有一个then()方法
4. Promise表示一个异步操作,每当new 一个Promise时,就表示一个具体的异步操作
5. 由于Promise创建的实例是一个异步操作,这个异步操作的结果只有两种状态:成功(resolve);失败(reject)
6. 可以在new出来的Promise实例上,调用then()方法,为这个Promise异步操作,指定成功(resolve)和失败(reject)回调函数
### 以读取文件为例的Promise异步操作示例 ###
const fs = require('fs') //引入文件处理模块
//封装一个读取文件的promise函数
function getFileByPath(fpath){
//此处resolve和reject为成功、失败的形参函数,直接返回promise对象
return new Promise(function(resolve,reject){
fs.readFile(fpath,'utf-8',(err,dataStr)=>{
if(err) return reject(err)
resolve(dataStr)
})
})
}
//promise中then的使用,传入两个函数,第一个监听resolve执行,第二个监听reject执行
getFileByPath('./files/1.text').then(function(data){
console.log(data)
},function(err){
console.log(err)
})
//使用promise的then解决回调地狱,同时使用catch捕获reject的执行
//只执行成功回调的异步操作,如果某次执行失败进入reject,操作终止
getFileByPath('./files/1.text')
.then(function(data){
console.log(data)
return getFileByPath('./files/2.txt') //将新生成的promise对象返回,可以直接在调用新对象的then
})
.then(function(data){
console.log(data)
return getFileByPath('./files/3.txt')
})
.catch(function(err){ //捕获上述方法中的任意执行失败事件
console.log(err)
})
## 如果出现引用第三方callee等报错,修改babel的配置可去除webpack的严格模式 ##
babel-plugin-transform-remove-strict-mode