Vue.js的使用

1、Vue.js是什么?

​ 一位华裔前Google工程师(尤雨溪)开发的前端js库
作用:动态构建用户界面

特点:①遵循MVVM模式
②编码简洁,体积小,运行效率高,移动/PC端开发
③它本身只关注UI,可以轻松引入vue插件和其他第三方库开发项目
与其他框架的关联
①借鉴angular的模板和数据绑定技术
②借鉴react的组件化和虚拟DOM技术
vue包含一系列的扩展插件(库)

vue-cli vue脚手架
vue-resource(axios) ajax请求
vue-router 路由
vuex 状态管理
vue-lazyload 图片懒加载
vue-scroller 页面滑动相关
mint-ui 基于vue的组件库(移动端)
element-ui 基于vue的组件库(PC端)

2、Vue.js基本使用

​ 1)引入vue.js

<script type="text/javascript" src="../js/vue.js"></script>

​ 2)创建Vue实例对象(vm),指定选项(配置)对象
​ el:指定dom标签容器的选择器
​ data:指定初始化状态数据的对象/函数(返回一个对象)

<script type="text/javascript">
	//创建Vue实例
    const vm = new Vue({
    	//配置对象       
        el: '#app',       
        data: {
        	//数据(Model)
            username: ''        
        }
    })
</script>

​ 3)在页面模板中使用{{}}vue指令

//双向数据绑定 : v-model
//显示数据 : {{xxx}}
<input type="text" v-model="username">
<p>Hello {{username}}</p>

3、Vue对象的选项

①el

​ 指定dom标签容器的选择器,Vue就会管理对应的标签及其子标签(默认为文件名的小写)

②components

映射组件标签

<template>
  <div id="app">
    <!--3、使用组件标签-->
    <HelloWorld/>
  </div>
</template>

<script>
  //1.引入组件
  import HelloWorld from './components/HelloWorld.vue'

  export default {
    //2.映射组件标签
    components: {
      HelloWorld
    }
  }
</script>

③data

​ 对象或函数类型
​ 指定初始化状态属性数据的对象,vm也会自动拥有data中的属性,页面中可以直接访问
​ 数据代理:由vm对象来代理对data中所有属性的操作(读/写)

④methods

​ 包含多个方法的对象
​ 供页面中的事件指令来绑定回调,回调函数默认有event参数,但也可以指令自己的参数
​ 所有的方法由vue对象来调用,访问data中属性直接使用this.xxx

⑤computed

​ 在computed属性对象中定义计算属性的方法

​ 计算属性高级:
通过getter/setter实现对属性数据的显示和监视
计算属性存在缓存, 多次读取只执行一次getter计算

<div id="demo" id="app">: <input type="text" placeholder="First Name" v-model="firstName"><br>: <input type="text" placeholder="Last Name" v-model="lastName"><br>
    <!--fullName1是根据fistName和lastName计算产生-->
    姓名1(单向): <input type="text" placeholder="Full Name1" v-model="fullName1"><br>
    姓名3(双向): <input type="text" placeholder="Full Name3" v-model="fullName3"><br>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
    const vm = new Vue({
        el: '#demo',
        data: {
            firstName: 'A',
            lastName: 'B',
        },
        //计算属性,什么时候执行:初始化显示/相关的data属性数据发生改变
        //计算并返回当前属性的值
        computed: {
            //什么时候执行:初始化显示/相关的data属性数据发生变化
            fullName1() {//计算属性中的一个方法,方法的返回值作为属性值
                return this.firstName + ' ' + this.lastName;
            },
            fullName3: {
                //回调函数:1、你定义的 2、你没有调用 3、最终执行了
                //当需要读取当前属性值时回调,根据相关的数据计算并返回当前属性的值
                get() {
                    return this.firstName + ' ' + this.lastName;
                },
                //回调函数,监视当前属性值的变化,当属性值发生改变时回调,更新相关的属性数据
                set(value) {//value就是fullName3的最新属性值
                    const names = value.split(' ');
                    this.firstName = names[0];
                   this.lastName = names[1];

                }
            }
        }     
    });  
</script>

⑥watch

​ 包含多个属性监视的对象,分为一般监视和深度监视
xxx:function(value){ ​ xxx:{ ​ deep:true, ​ handler:fun(value) ​ } ​ }
​ 另一种添加监视方式:vm.$watch('xxx',function(value){})

<div id="demo" id="app">: <input type="text" placeholder="First Name" v-model="firstName"><br>: <input type="text" placeholder="Last Name" v-model="lastName"><br>
    姓名2(单向): <input type="text" placeholder="Full Name2" v-model="fullName2"><br> 
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
    const vm = new Vue({
        el: '#demo',
        data: {
            firstName: 'A',
            lastName: 'B',
            fullName2: 'A B'
        },
        watch: {//配置监视
            //监听firstName
            firstName: function (value) {
                console.log(this);//vm对象
                this.fullName2 = value + ' ' + this.lastName;
            }
        }
    });
    //监视lastName
    vm.$watch('lastName', function (value) {
        this.fullName2 = this.firstName + ' ' + value;
    })
</script>

4、过渡动画

  1. vue动画的理解

操作csstrasitionanimation
vue会给目标元素添加/移除特定的class

  1. 基本过渡动画的编码
    1). 在目标元素外包裹
    2). 定义class样式
    1. 指定过渡样式: transition
    2. 指定隐藏时的样式: opacity/其它
  2. 过渡的类名
    xxx-enter-active: 指定显示的transition
    xxx-leave-active: 指定隐藏的transition
    xxx-enter,.xxx-leave-to: 指定隐藏时的样式

代码示例:

<style type="text/css">
        .fade-enter-active, .fade-leave-active {
            transition: opacity 1s;
        }

        .fade-enter, .fade-leave-to {
            opacity: 0;
        }
</style>

<div id="demo1">
    <button @click="show=!show">
        Toggle1
    </button>
    <transition name="fade">
        <p v-if="show">Hello</p>
    </transition>
</div>

<script type="text/javascript">
    new Vue({
        el: '#demo1',
        data: {
            show: true
        }
    })
</script>

5、生命周期

vue生命周期分析

  • 初始化显示

    beforeCreate()
    created()
    beforeMount()
    mounted()

  • 更新状态:this.xxx = value

    beforeUpdate()

    updated()

  • 销毁 vue 实例:vm.$destroy()

    beforeDestory()
    destoryed()

​ ②主要的生命周期函数:
created()/mounted():启动异步任务(启动定时器,发送ajax请求,绑定监听)
beforeDestory():做一些收尾工作

6、自定义过滤器

①理解
对需要显示的数据进行格式化后再显示
②编码
1). 定义过滤器

Vue.filter(filterName, function(value[,arg1,arg2,...]){
    // 进行一定的数据处理
    return newValue
})

​ 2). 使用过滤器

<div>{{myData | filterName}}</div>
<div>{{myData | filterName(arg)}}</div>

具体示例代码

<div id="test">
    <p>原生:{{date}}</p>
    <p>完整版:{{date | dateString}}</p>
    <p>年月日:{{date | dateString('YYYY-MM-DD')}}</p>
    <p>时分秒:{{date | dateString('HH:mm:ss')}}</p>
</div>
<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript" src="https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js"></script>
<script>
    Vue.filter('dateString', function (value, format) {
    	//如果没有format没有值则使用后面给定的格式
        return moment(value).format(format || "YYYY-MM-DD HH:mm:ss")
    })
    new Vue({
        el: '#test',
        data: {
            date: new Date()
        }
    })
</script>

7、Vue内置指令

指令 属性
v-text/v-html 指定标签体;v-html会将value作为html标签来解析
v-if &v-else
v-show
显示/隐藏元素
v-if:如果value为true,当前标签会输出在页面中
v-else:与v-if一起使用,如果value为false,将当前标签输出到页面中
v-show:就会在标签中添加display样式, 如果vlaue为true, display=block, 否则是none
v-for 遍历
遍历数组:v-for="(persons,index) in persons"
遍历对象:v-for=“value in person”
v-on 绑定事件监听
v-on:事件名,可以缩写为:@事件名
监听具体的按键:@keyup.keyCode @keyup.enter
停止时间的冒泡和阻止时间的默认行为:@click.stop @click.prevent
隐含对象:$event
v-bind 强制绑定解析表达式
html标签属性是不支持表达式的,就可以使用v-bind
可以缩写为: :id='name’
代码示例::style="{color:colorValue}"
v-model 双向数据绑定,自动收集用户输入数据
ref: 标识某个标签
ref='xxx’
读取得到标签对象:this.$refs.xxx
v-cloak 防止页面加载时出现 vuejs 的变量名

示例代码:

<div id="example">
    <p v-text="msg" ref="message"></p>
    <p v-html="msg"></p>
    <p v-for="(item,index) in arr">{{item}}</p>
    <p v-cloak v-for="(item2,index) in obj">{{item2}}</p>
    <button @click="showMsg">显示Msg</button>
</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
    new Vue({
        el: '#example',
        data: {
            msg: "<b>Hello VUE</b>",
            arr: [111, 2222],
            obj: {'name1': 1, 'name2': 2}
        },
        methods: {
            showMsg() {
                alert(this.$refs.message.textContent);
            }
        }
    })
</script>

8、自定义指令

1). 注册全局指令

Vue.directive('my-directive', function(el, binding){
	el.innerHTML = binding.value.toUpperCase()
})

2). 注册局部指令

directives : {
   'my-directive' : function(el, binding) {
	el.innerHTML = binding.value.toUpperCase()
 }
}

3). 使用指令:v-xxx

具体示例代码

<div id="test">
    <p v-upper-text="msg"></p>
    <p v-lower-text="msg"></p>
</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
    // 注册一个全局指令(不同的vue的id下均可以使用)
    // el: 指令所在的标签对象
    // binding: 包含指令相关数据的容器对象
    Vue.directive('upper-text', function (el, binding) {
        el.innerHTML = binding.value.toUpperCase();
    })
    new Vue({
        el: '#test',
        data: {
            msg: "<b>Where</b> Amazing Happens!"
        },
        //定义局部指令(只能在指定的id下可以使用)
        directives: {
            'lower-text': {
                bind(el, binding) {
                    el.textContent = binding.value.toLowerCase();
                }
            }
        }

    })
</script>

9、表单的输入绑定

<div id="demo">
    <form action="/xxx" @submit.prevent="submitForm">
        <span>用户名: </span>
        <input type="text" v-model="user.username"><br>

        <span>密码: </span>
        <input type="password" v-model="user.pwd"><br>

        <span>性别: </span>
        <input type="radio" id="female" value="女" v-model="user.sex">
        <label for="female"></label>
        <input type="radio" id="male" value="男" v-model="user.sex">
        <label for="male"></label><br>

        <span>爱好: </span>
        <input type="checkbox" id="basket" value="basket" v-model="user.likes">
        <label for="basket">篮球</label>
        <input type="checkbox" id="foot" value="foot" v-model="user.likes">
        <label for="foot">足球</label>
        <input type="checkbox" id="pingpang" value="pingpang" v-model="user.likes">
        <label for="pingpang">乒乓</label><br>

        <span>城市: </span>
        <select v-model="user.cityId">
            <option value="">未选择</option>
            <option :value="p.id" v-for="(p,index) in user.allCity">{{p.name}}</option>
        </select><br>
        <span>介绍: </span>
        <textarea rows="10" v-model="user.desc"></textarea><br><br>

        <input type="submit" value="注册">
    </form>
</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript">
    new Vue({
        el: '#demo',
        data: {
            user: {
                username: "",
                pwd: "",
                sex: "女",
                likes: ['foot'],
                cityId: '',
                allCity: [{id: 1, name: 'BJ'}, {id: 2, name: 'SH'}, {id: 3, name: 'SZ'}],
                desc: ''
            }
        },
        methods: {
            submitForm() {
            }
        }
    })
</script>

10、自定义插件的使用

插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:

  1. 添加全局方法或者属性。如: vue-custom-element
  2. 添加全局资源:指令/过滤器/过渡等。如 vue-touch
  3. 通过全局混入来添加一些组件选项。如 vue-router
  4. 添加Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
  5. 一个库,提供自己的API,同时提供上面提到的一个或多个功能。如vue-router

代码示例:vue-myPlugin.js

(function (window) {
  const MyPlugin = {}
  MyPlugin.install = function (Vue, options) {
	// 1. 添加全局方法或属性
	Vue.myGlobalMethod = function () {
	  console.log('Vue函数对象的myGlobalMethod()')
	}
	// 2. 添加全局资源
	Vue.directive('my-directive',function (el, binding) {
	  el.textContent = 'my-directive----'+binding.value
	})

	// 3. 添加实例方法
	Vue.prototype.$myMethod = function () {
	  console.log('vm $myMethod()')
	}
  }
  window.MyPlugin = MyPlugin
})(window)

使用

<div id="test">
  <p v-my-directive="msg"></p>
</div>

<script type="text/javascript" src="../js/vue.js"></script>
<script type="text/javascript" src="vue-myPlugin.js"></script>
<script type="text/javascript">
  // 声明使用插件(安装插件: 调用插件的install())
  Vue.use(MyPlugin) // 内部会调用插件对象的install()

  const vm = new Vue({
	el: '#test',
	data: {
	  msg: 'HaHa'
	}
  })
  Vue.myGlobalMethod()
  vm.$myMethod()
</script>

11、vue脚手架

用来创建vue项目的工具包

创建项目:
npm install -g vue-cli(第一次安装vue-cli)
vue init webpack 项目名
开发环境运行:
cd 项目名->npm install->npm run dev
生产环境打包发布:
npm run build(即生成打包好的文件dist)

​ 安装测试服务器测试
npm install -g serve
serve dist
​ 访问所给的链接即可
​ 使用tomcat服务器
​ 将打包好的dist文件夹放入到webapps下,tomcat默认端口为8080,访问http://localhost:8080/dist即可。

12、eslint

​ 用于做项目编码规范检查的工具
​ 基本原理:定义了很多规则, 检查项目的代码一旦发现违背了某个规则就输出相应的提示信息
有相应的配置, 可定制检查。
​ 关闭编码时候的检查:webstorm:setting->搜索ESLint-<关闭Enable

13、组件化编程

①vue文件的组成

<template>
	<div></div>
<template/>
<script>
	//配置Vue对象
	exprot default{
		//指定属性名和属性值的类型
		props:[]/{},
		//这里只能用函数的方式
		data(){
			return{
				arr:[1,2,3],
				obj:{name:value}
			}
		},
		computed: {},
        methods: {}, 
        watch: {},
        filters: {},
        directives: {},
        components: {}
	}
</script>
<style>
<style/>

②组件化编码的基本流程

  1. 拆分界面,抽取组件

  2. 编写静态组件

  3. 编写动态组件

    初始化数据,动态显示初始化界面,实现与用户交互功能

③组件间通信

1)props

​ 父子组件间通信的基本方式
​ 属性值的2大类型:
​ 一般:父组件->子组件
​ 函数:子组件->父组件
​ 隔层组件间传递:必须逐层传递
​ 兄弟组件间:必须借助父组件

​ 代码示例:

父组件:
<template>
	<div :title='text'></div>
</template>
<script>
	export default{
		data(){
			return{
				text:"Hello Child"
			}
		}
	}
</script>

子组件:
<template>
	<p>{{title}}</p>
</template>
<script>
	export default{
		props:{
			title:String
		}
	}
</script>
2)vue的自定义事件

​ 该方式用的较少

​ 此方式只用于子组件父组件发送消息(数据),不适合隔层组件和兄弟组件间的通信

​ 子组件:this.$emit('addTodo', todo)

​ 父组件:

方式一:通过v-on
	<TodoHeader @addTodo="addTodo"/>
方式二:通过$on
	<TodoHeader ref="header"/>
	
	this.$refs.header.$on('delete_todo', function (todo) {
         this.deleteTodo(todo)
    })
	
3)pubsub第三方库

​ 适合于任何关系的组件间通信
​ 安装:npm install --save pubsub-js

发布消息PubSub.publish('deleteTodo', this.index)

订阅消息

PubSub.subscribe('deleteTodo', (msg, index) => {
	this.deleteTodo(index)
})
4)slot

​ 此方式用于父组件向子组件传递标签数据

5)vuex(推荐)

​ 多组件共享状态(数据的管理),组件间的关系也没有限制
​ 功能比pubsub强大,更适用于vue项目,后面将详细讲解。

14、Ajax

vue-resourcevue插件,多用于vue1.x
axios:第三方库,多用于vue2.x

①vue-resource的使用

//引入模块
import VueResource from 'vue-resource'

//使用插件
Vue.use(VueResource)
//通过vue/组件对象发送ajax请求
this.$http.get('/someUrl').then((response)=>{
	//success callback
	console.log(response.data)
},(response)=>{
	//error callback
	console.log(response.statusText) //错误信息
}
)

②axios的使用

//引入模块
import axios from 'axios'

//发送ajax请求
axios.get(url).then(response=>{
	//得到返回结果数据
	console.log(response.data)
}).catch(error=>{
	console.log(error.message)
})

15、vue-router

vue用来实现SPA漏油的插件,使用vue-router的方法如下:

①创建路由器

[router/index.js]

import Vue from 'vue'

import VueRouter from 'vue-router'
import About from '../components/About.vue'
import Detail from '../components/Detail.vue'

Vue.use(VueRouter)
exprot default new VueRouter({
	routes:[
		{
			//一般路由
			path:'/about',
			component:About,
			//嵌套路由
			children:[{
				path:'/about/detail',
				component:Detail
				}]
			},
		{
			//自动跳转路由
			path:'/',
			redirect:'/about'
		}
	]
})	

②注册路由器

[main.js]

import router from './router'

new Vue({
	router
})

③使用路由组件标签

<router-link to="/xxx">Go to XXX</router-link>
<router-view></router-view>

向路由组件传递数据

params: <router-link to="/home/news/abc/123">
props: <router-view msg='abc'>

缓存路由组件

<keep-alive>
  <router-view></router-view>
</keep-alive>

路由的编程式导航

this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面)
this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面)
this.$router.back(): 请求(返回)上一个记录路由

16、vuex

对应用中组件的状态进行集中式的管理(读/写)

①状态自管理应用

state:驱动应用的数据源
view:以声明方式将state映射到视图
actions: 响应在view上的用户输入导致的状态变化(包含n个更新状态的方法)
vue

②多组件共享状态的问题

多个视图依赖于同一状态,来自不同视图的行为需要变更同一状态
以前的解决办法
将数据以及操作数据的行为都定义在父组件
将数据以及操作数据的行为传递给需要的各个子组件(有可能需要多级传递)
vuex就是用来解决这个问题的,vuex结构图如下
vuex

③vuex的核心概念

1.state

vuex管理的状态对象,它应该是唯一的

2.mutations

​ 包含多个直接更新state的方法(回调函数)的对象
​ 谁来触发: action中的commit('mutation名称')
只能包含同步的代码, 不能写异步代码

3.actions

​ 包含多个事件回调函数的对象
​ 通过执行: commit()来触发mutation的调用, 间接更新state
​ 谁来触发: 组件中: $store.dispatch('action名称')
可以包含异步代码(定时器, ajax)

4.getters

​ 包含多个计算属性(get)的对象
​ 谁来读取: 组件中: $store.getters.xxx

5.modules

​ 包含多个module
​ 一个module是一个store的配置对象
​ 与一个组件(包含有共享数据)对应

④项目中Vuex的具体使用

下载: npm install vuex --save

[state.js]
	export default {
		articles: []
	}
	
[actions]
	import {SAVE_ARTICLE} from './mutation-type'
    import axios from 'axios'
    
    export default {
      reqArticles ({commit}) {
      	//异步请求的具体代码只能在action.js中
        axios.get('http://47.106.166.70:8100/get/all/articles').then(response => {
          const articles = response.data
          commit(SAVE_ARTICLE, {articles})
          console.log("success")
        }).catch(error => {
          console.log(error.message)
        })
      }
    }	
	
[mutations.js]
	import {SAVE_ARTICLE,GO_HOME,GO_INDEX} from './mutation-type'

    export default {
      [SAVE_ARTICLE](state,{articles}){
        state.articles=articles
      }
    }

[index.js]
	//向外暴露store对象
	Vue.use(Vuex)

    export default new Vuex.Store({
      state,mutations,actions,getters
    })
  
[main.js]
	//映射store
	import store from './store'
	new Vue({
		store
	})
	
[组件中如何使用]
	第一种(推荐)import {mapGetters, mapActions} from 'vuex'
	
    methods: {
        //映射action中的方法
        ...mapActions(['goHome']),
        goToHome () {
        	//this.$router为传递的对象
            this.goHome(this.$router)
        }
    }
    第二种:至二级使用$store对象
    mounted () {
    	this.$store.dispatch('reqArticles')
    }
    
    注:
    store对象
	1.所有用vuex管理的组件中都多了一个属性$store, 它就是一个store对象
	2.属性:
	  state: 注册的state对象
	  getters: 注册的getters对象
	3.方法:
	  dispatch(actionName, data): 分发action

17.ElementUI的简单使用

下载并导入:npm i element-ui -S
[mian.js]
	import 'element-ui/lib/theme-chalk/index.css';
	import Element from 'element-ui';
	
	Vue.use(Element, { size: 'small', zIndex: 3000 });
	
[.vue页面中]
<template>
  <el-button type="primary" @click="handleClick">主要按钮</el-button>
</template>

<script>
  export default {
    methods: {
      handleClick () {
        this.$message('这是一条消息提示');
      }
    }
  }
</script>
发布了81 篇原创文章 · 获赞 124 · 访问量 38万+

猜你喜欢

转载自blog.csdn.net/qq_38697437/article/details/102891759