vue起步

生命周期

 

1.npm安装:

(1)安装vue:npm install vue
(2)安装vue-cli:npm install -g vue-cli
(3)创建基于webpack新项目my-project:vue init webpack my-project
(4)进入项目,安装运行:cd my-project
npm install
npm run dev

 

2.Vue组件包含三个模板:

template:视图
script:逻辑
style:样式

 

3.vue基本指令:

Mustache语法:{{}}:用于js单行语句,且不适用于html属性
v-html:渲染html
v-text:渲染文本
v-bind:绑定属性值

 

4.条件渲染:

v-if:<p v-if="seen">我可以显示或隐藏</p>
v-if,v-else
v-if,v-else-if
v-show
v-if与v-show区别:v-if为false元素根本不加载,v-show为false元素加载但是display:none。
如果频繁的切换则用v-show,条件很少改变则用v-if

 

5.循环:

v-for:每个列表最好添加key,给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素。
             (1)对与数组中的对象:list:[
                                    {name:'John',age:12},
                                    {name:'Amy',age:12},
                                            {name:'vskd',age:12}
                                              ];
     有两个参数(数据,索引):<li v-for="(person,index) in list" v-bind:key="index">{{person.name}}:{{index}}</li>


(2)对于对象:object: {
                  firstName: 'John',
                  lastName: 'Doe',
                  age: 30
                      }
       有三个参数(值,键名,索引):<li v-for="(item,name,index) in object">{{person.name}}:{{index}}</li>
 

6.事件监听:v-on

v-on:click="btnChange"
 

7.创建组件:

(1)在components文件夹中创建Events.vue文件:

<template>
	<!-- template中只能存在一个根组件 -->
	<div id="events">
		<p>{{msg}}</p>
	</div>
</template>
<script>
	export default {
		data() {
			return {
				msg:'信息'
			}
		}
	}
</script>
<style>
	
</style>

(2)在App.vue的script中导入组件:

import Events from './components/Events';
export default {
  name: 'App',
  components:{
    Events
  }
}

(3)在App.vue的template中加载组件:

<template>
  <div id="app">
    <Events />
  </div>
</template>

 

8.数组更新检测:

(1)变异方法,都是改变原数组,所以能响应更新:push(),pop(),shift(),unshift(),splice(),sort(),reverse()
(2)替换数组,都是生成新数组,所以不能响应更新:filter(), concat() 和 slice()
        filter():对数组进行过滤。lists.filter(function(item){return item >= 10;});

 

 

 

9.计算属性:

 

 

计算属性computed会有缓存,没有改变时直接使用上次的计算结果,而methods里的函数每次都会重新计算。

computed中的方法调用时不需要加括号,methods中的需要括号

 

10.v-model:

    v-model.lazy:失去焦点后才会反应

     v-model.number:将输入值转为数值
     v-model.trim:自动去除首尾空白
 

11.组件内容:

template:只能有一个根元素
script:需导出组件export default {...}
style:添加scoped 属性是表示样式只作用于当前组件
 

12.子父级交互:

父 ->子:props

子 -> 父:emit Event

 

13.插槽:slot:子组件给父组件传递数据

(1)子组件: 在想插入html 的地方加上<slot></slot>标签,可以使用name属性设置名字来区分

                <header>
			<slot name="header"></slot>
		</header>
		<main>
			<slot>我是默认插槽</slot>
		</main>
		<footer>
			<slot name="footer"></slot>
			<slot name="test">我是test插槽</slot>
			<slot name="msgTest"></slot>
		</footer><header>
			<slot name="header"></slot>
		</header>
		<main>
			<slot>我是默认插槽</slot>
		</main>
		<footer>
			<slot name="footer"></slot>
			<slot name="test">我是test插槽</slot>
			<slot name="msgTest"></slot>
		</footer>

父组件:在将插到子组件的内容最外层标签中加上slot属性且值为子组件设置的name属性值

<template slot="header">
        <h4>我是header</h4>
      </template>
      <template>
        <h4>我是main</h4>
      </template>
      <template slot="footer">
        <h4>我是footer</h4>
        <p slot="test">我是test插槽覆盖物</p>
        <p slot="msgTest">{{msg}}</p>
      </template>
      <template>
        <h4>我是main</h4>
      </template>
      <template slot="footer">
        <h4>我是footer</h4>
        <p slot="test">我是test插槽覆盖物</p>
        <p slot="msgTest">{{msg}}</p>
      </template>

 

(2)子组件给父组件传递数据

 

子组件:

<div>
    <slot name="s1" text="我是传递给父组件的数据"></slot>
</div>text="我是传递给父组件的数据"></slot>
</div>

父组件:

<div slot="s1" slot-scope="jie">
    <p>{{jie.text}}</p>
</div>slot-scope="jie">
    <p>{{jie.text}}</p>
</div>

 

14.动态组件切换:

 

<template>
	<div class="active">
		<h3>active</h3>
    	        <button @click="changeView1">菜单1</button>
    	        <button @click="changeView2">菜单2</button>
		<keep-alive>  <compont :is="currentView"></compont>  </keep-alive>  //存放组件的地方 //keep-alive是缓存失活的组件
	</div>
</template>
<script type="text/javascript">
	import Fu from './AFu.vue'
	import BSlot from './BSlot.vue'

	export default {
		data() {
			return {
				currentView:"BSlot"
			}
		},
		components:{
			Fu,
			BSlot
		},
		methods:{
			changeView1:function() {
				this.currentView = "BSlot";
			},
			changeView2:function() {
				this.currentView = "Fu";
			}
		}
	}
</script>
<style type="text/css"></style><keep-alive>  <compont :is="currentView"></compont>  </keep-alive>  //存放组件的地方 //keep-alive是缓存失活的组件
	</div>
</template>
<script type="text/javascript">
	import Fu from './AFu.vue'
	import BSlot from './BSlot.vue'

	export default {
		data() {
			return {
				currentView:"BSlot"
			}
		},
		components:{
			Fu,
			BSlot
		},
		methods:{
			changeView1:function() {
				this.currentView = "BSlot";
			},
			changeView2:function() {
				this.currentView = "Fu";
			}
		}
	}
</script>
<style type="text/css"></style>

15.自定义指令:

<template>
	<div class="active">
		<input type="text" name="" v-myfocus>
		<p v-mycss>会上讲话精神</p>
	</div>
</template>
<script type="text/javascript">
	
	export default {
		data() {
			return {
			}
		},
		directives:{
			myfocus: {
				inserted:function(el) {
					el.focus();
				}
			},
			mycss:{ bind:function(el,binding,vnode) {
					el.style.background="yellow";
				},
				inserted:function(el) {
					el.style.color="red";
				}
			}
		}
	}
</script>
<style type="text/css"></style>v-myfocus>
		<p v-mycss>会上讲话精神</p>
	</div>
</template>
<script type="text/javascript">
	
	export default {
		data() {
			return {
			}
		},
		directives:{
			myfocus: {
				inserted:function(el) {
					el.focus();
				}
			},
			mycss:{ bind:function(el,binding,vnode) {
					el.style.background="yellow";
				},
				inserted:function(el) {
					el.style.color="red";
				}
			}
		}
	}
</script>
<style type="text/css"></style>

16.过滤器:

用于文本格式化,例如:¥10,ajax获取到10后过滤成¥10

<template>
	<div class="active">
		<h3>过滤器:文本格式化</h3>
		<p>{{price | moneyChange }}</p>
	</div>
</template>
<script type="text/javascript">
	
	export default {
		data() {
			return {
				price:10
			}
		},
		filters:{
			moneyChange:function(value) {
				return value = '¥' + value;
			}
		}
	}
</script>
<style type="text/css"></style>{{price | moneyChange }}</p>
	</div>
</template>
<script type="text/javascript">
	
	export default {
		data() {
			return {
				price:10
			}
		},
		filters:{
			moneyChange:function(value) {
				return value = '¥' + value;
			}
		}
	}
</script>
<style type="text/css"></style>

17.axios

(1)安装:npm install axio

(2)在main.js中 :

 import Axios from 'axios'
 Vue.prototype.$axios = Axios;

(3)在组件(如:HelloWorld.vue)中就可以使用:

this.$axios.get(url)

 

18.axios跨域访问:(此方法仅用于测试环境,不用于生产环境,生产环境中跨域问题由后端解决)

(1)项目中的config/index.js中的proxyTable添加:

proxyTable: {
        "/api": {
            target:"http://localhost:80", //target中写入需要访问的域名
            changeOrigin:true,
            pathRewrite:{
                '^/api':'/api'
            }
        }
    },

(2)在main.js中:设置HOST,指向index中的“/api”

Vue.prototype.HOST = '/api'

(3)使用:在组件中:

<template>
  <div class="hello">
    <div class="qw">{{msg}}</div>
    <ul>
      <li v-for="item in msg">{{ item.username }} - {{ item.psw }} - {{ item.age }} </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: ''
    }
  },
  created: function() {
    var url = this.HOST + '/mypro1';
    // this.$axios.get("http://localhost:80/mypro1")
    this.$axios.get(url)
    .then(res => {
      console.log(res.data);
      this.msg = res.data;
    })
    .catch(error => {
      console.log(error);
    })
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
  background: yellow;
}
a {
  color: #42b983;
}
</style>
 var url = this.HOST + '/mypro1';
    // this.$axios.get("http://localhost:80/mypro1")
    this.$axios.get(url)
    .then(res => {
      console.log(res.data);
      this.msg = res.data;
    })
    .catch(error => {
      console.log(error);
    })
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
  background: yellow;
}
a {
  color: #42b983;
}
</style>

 

(4)跨域访问:豆瓣电影:

豆瓣开发者官网查找所需的接口:如豆瓣电影top250的接口:http://api.douban.com/v2/movie/top250

在config/index.js中设置

proxyTable: {       
        "/api": {
            target:"http://api.douban.com/v2",//豆瓣
            changeOrigin:true,
            pathRewrite:{
                '^/api':''
            }
        }
    },

创建新组件Douban.vue:

<template>
	<div class="douban">
		<ul>
			<li v-for="film in films">
				<img :src="film.images.small">
				<div class="right">
					<p class="title">{{ film.title}}</p>
					<p>{{ film.original_title}}</p>
					<p>{{ film.year}}</p>	
					<p>{{ film.subtype}}	</p>
					<p><span v-for="genre in film.genres">{{genre}},</span></p>
					<p>{{ film.id}}</p>	
				</div>
			</li>
		</ul>
	</div>
</template>
<script type="text/javascript">
	export default {
		data() {
			return {
				films:''
			}
		},
		created:function() {
			var url = this.HOST + '/movie/top250';
			console.log(url);
			this.$axios.get(url)
			.then(res => {
				console.log(res);
				this.films = res.data.subjects;
			})
			.catch(error => {
				console.log(error);
			})
		}
	}
</script>
<style type="text/css">
	ul {
		list-style: none;
		margin: 0;
		padding:0;
	}
	li {
		width: 600px;
		height: 400px;
		display: inline-block;
		border: 2px solid #ccc;
		padding: 20px;
		text-align: left;
		margin: 20px;
	}
	img {
		vertical-align: top;
	}
	.right {
		display: inline-block;
		margin-left: 10px;
	}
	.title {
		font-size: 30px;
		font-weight: bold;
	}
</style>

效果图如下:

 

19.mockjs使用:

(1)安装:npm install mockjs

(2)使用:(在组件中):

<template>
	<div class="mock">
		msg:{{ msg }}
	</div> 
</template>
<script type="text/javascript">
	export default {
		data() {
			return {
				msg:''
			}
		},
		created() {
			var Mock = require('mockjs')
			var data = Mock.mock({		    
			    'list|1-10.2-3':1
			})
			// 输出结果

			console.log(JSON.stringify(data, null, 4))
			var res = data; //JSON.stringify(data, null, 4);
			this.msg = res.list;
			console.log(this.msg);
		}
	}
</script>
<style type="text/css">
	
</style>

20.路由:

在router/index.js中:载入要设置路由的组件,设置路由地址:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Logo from '@/components/BLogo'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    }, 
    {
    	path:'/logo',
    	name:'logo',
    	component: Logo
    }
  ]
})

在父组件中引用路由<router-link to="/"></router-link>

<template>
	<div class="navlist">
		<ul>
			<li>
				<router-link to="/">Hello</router-link>
				<router-link to="/logo">logo</router-link>
			</li>
		</ul>
	</div>
</template>

21.嵌套路由:

(1)在router/index.js中:

import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/components/page/Index'

import Wall from '@/components/third/Wall'
import Cj from '@/components/third/Cj'
import Jb from '@/components/third/Jb'
import Tp from '@/components/third/Tp'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Index',
      component: Index,
      redirect:"/Wall",  //重定向:设置默认显示哪页
      children:[         //index中的子路由
      	{
      		path:"Wall",
      		name:"Wall",
      		component:Wall
      	},
      	{
      		path:"Cj",
      		name:"Cj",
      		component:Cj
      	},
      	{
      		path:"Jb",
      		name:"Jb",
      		component:Jb
      	},
      	{
      		path:"Tp",
      		name:"Tp",
      		component:Tp
      	}
      ]
    }
  ]
})

(2)index.vue中依旧使用<router-link to=""></router-link>标签指示路由

<template>
	<div class="index">
		<ul>
			<li><router-link to="Wall">上墙</router-link></li>
			<li><router-link to="Tp">投票</router-link></li>
			<li><router-link to="Cj">抽奖</router-link></li>
			<li><router-link to="Jb">机霸</router-link></li>
		</ul>
		<div class="right">
			<router-view></router-view>
		</div>
	</div>
</template>

22.vuex

作用:管理共享状态(当组件之间没有关系又想引用共同的数据时使用,但它附带了更多的概念和框架,如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的

(1)安装:npm install vuex --save-dev

(2)在src文件夹中创建store文件夹 => index.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 创建store仓库
export default new Vuex.Store({
	state:{
		count:10
	}, //state设置数据
	mutations:{
		increment(state) {
			state.count ++;
		},
		descrement(state) {
			state.count --;
		}
	}, //mutations:修改数据,使用时用commit
	actions:{
		increment(context) { //context:承上启下
			context.commit("increment");
		},
		descrement(context) {
			context.commit("descrement");
		}
	}, //与mutations作用基本一致,都是修改数据,一般用于异步
	getters:{
		getState(state) {
			return state.count > 0 ? state.count : 0
		}
	} //getters对count数据进行限制
})

(3)在main.js中引入store.js,要在vue实例中引入store

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

(4)组件中使用:

<template>
  <div class="hello">
    <p>{{getCount}}</p>
    <button @click="incre">自增</button>
    <button @click="desc">自减</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: ''
    }
  },
  computed:{
    getCount() {
      // return this.$store.state.count; //直接调用state中的count
      return this.$store.getters.getState; //调用getters中getState处理过后返回的数据
    }
  },
  methods:{
    incre:function() {
      // this.$store.commit('increment'); //mutations用commit      this.$store.dispatch('increment'); //actions用dispatch
    },
    desc:function() { 
      // this.$store.commit('descrement'); 
      this.$store.dispatch('descrement'); 
    }
  }}
</script>

(5)组件中获取并使用state的三种方式 

  1. 直接在模板中使用this.$store.state.count
  2. 在计算属性中将this.$store.state.count赋值给组件中的变量
  3. 使用mapState简洁的将this.$store.state.count赋值给组件中的变量
    <template>
        <div>
            <p>this.$store.state:{{this.$store.state.count}}</p>
            <p>computed中将this.$store.state.count赋值给count1:{{count1}}</p>
            <p>mapState:{{count}}</p>
        </div>
    </template>
    <script type="text/javascript">
    import {mapState} from 'vuex';
    export default {
        data() {
            return {
    
            }
        },
        computed: {
            count1(){
                return this.$store.state.count
            },
            ...mapState({
                count:state=>state.count
            })
        }
    }    
    </script>

     

(6) 组件中修改状态

  1. 直接在组件方法中调用修改状态
  2. 将修改方法赋值给组件中的方法
    <template>
        <div>
            <p>mapState:{{count}}</p>
            <button @click="add1">直接在组件方法中调用修改状态</button>
            <button @click="add2">将修改方法赋值给组件中的方法(对象形式)</button>
            <button @click="add">将修改方法赋值给组件中的方法(数组形式)</button>
        </div>
    </template>
    <script type="text/javascript">
    import {mapState, mapMutations} from 'vuex';
    export default {
        data() {
            return {
    
            }
        },
        computed: {
            ...mapState({
                count:state=>state.count
            })
        },
        methods:{
            // 直接在组件方法中调用修改状态
            add1() {
                this.$store.commit('add');
            },
            // 将修改方法赋值给组件中的方法(参数可为对象亦可为数组)
            ...mapMutations({
                add2: 'add' // 组件中方法: mutations中方法
            }),
            ...mapMutations(['add', 'reduce'])
        }
    }    
    </script>

     

 (7)组件中获取Getter的三种方式

  1. 通过this.$store.getter.newCount属性获取
  2. 通过this.$store.getter.newCount方法获取
  3. 通过mapGetters获取 
    <template>
        <div>
            <p>mapState:{{count}}</p>
            <p>通过this.$store.getter.newCount属性获取:{{this.$store.getters.newCount}}</p>
            <p>通过this.$store.getter.newCount方法获取:{{this.$store.getters.newCount1(10000)}}</p>
            <p>通过mapGetters获取:{{newCount}}, {{newCount1(10000)}}</p>
    
            <button @click="add">将修改方法赋值给组件中的方法(数组形式)</button>
        </div>
    </template>
    <script type="text/javascript">
    import {mapState, mapMutations, mapGetters} from 'vuex';
    export default {
        data() {
            return {
    
            }
        },
        computed: {
            ...mapState({
                count:state=>state.count
            }),
            ...mapGetters(['newCount', 'newCount1'])
        },
        methods:{
            ...mapMutations(['add', 'reduce'])
        }
    }    
    </script>

     

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值