Vue学习笔记

Vue 学习笔记

前言

官网:https://cn.vuejs.org/

官方文档:https://cn.vuejs.org/v2/guide/

热门组件库地址:https://github.com/vuejs/awesome-vue

第三方UI框架:Element、Iview、MintUI

安装

  1. 直接引入方式:下载 vue.js ,直接在项目中引入(和引用 JQuery 一样)

  2. CDN引入方式:

    # 开发环境
    
    # 生产环境
    
    
  3. NPM,使用 vue-cli 构建 vue 项目

初入门


<html>
	<head>
		<meta charset="utf-8">
		<title>Vue-Learntitle>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
	head>
	<body>
		<div id="box1">
			{{name}}
		div>
	body>
	<script type="text/javascript">
		// 初始化 vue,在浏览器控制台可以通过 vm 控制
		var vm = new Vue({
			el: "#box1",
			data:{
				name: "Hello World!"
			},
            // 方法
            methods: {
                
            },
            // 计算属性
            computed: {
                
            }
		})
	script>
html>

Vue 基础

模板语法

# 直接取值
{{ 属性 }}
# 需要解析标签,防止XSS、CSRF攻击
# 表达式 或者简写 # 条件 v-if : 从 dom 中删除 v-else-if : v-else v-show :只是不在页面显示 # 列表 v-for="todo in todos" v-for="(todo,index) in todos" : index 为索引值 或者 v-for="todo of todos" v-for="(todo,index) of todos" # 事件 v-on:click 或者 @click v-model : 实现表单输入和应用状态之间的双向绑定。可以代替输入框value

class 与 style

# 绑定HTML Class
|----对象语法
|----数组语法
# 绑定内联样式
|----对象语法
|----数组语法

数组更新检测

  • 使用以下方法操作数组,可以检测变动

    push()、pop()、shift()、unshift()、splice()、sort()、reverse()
    
  • filter() concat() 和 slice() map(),不会检测变动,可以使用新数组替旧数组

输入框事件

# 事件对象
@input="handleInput"

handleInput(ev){
	// ev 表示事件对象
	console.log(ev)
	// 输入框的值
	console.log(ev.target.value)
}
# 事件对象和传参
@input="handleInput($event, param)"

handleInput(ev, param){
	// ev 表示事件对象
	console.log(ev)
	console.log(ev.data)
}

多选框

# v-model 使用数组,value 表示对应的标识
# 获取 v-model 绑定的值即可获取多选的值
 vue
 react
 jquery

new Vue({
	el: "#box",
	data: {
		checkedGroup: []
	}
})

单选框

# v-model 使用字符串,value 表示对应的标识,name 标识一组单选
# 获取 v-model 绑定的值即可获取单选的值
vue
react
query

Axios 请求

参考链接:https://github.com/axios/axios

计算属性

调用不能使用小括号,必须有返回值。写起来像方法,用起来是属性;

计算属性当属性值发生改变的时候,会自动重新计算属性值,并渲染到页面上;

watch 监听

监听某一个值发生变化,和改变之后需要如何处理

mixins 混入

# 引入js,同名方法优先级低于 methods
new Vue({
	mixins: [funUtils]
})

生命周期

组件注册方式

组件作用域隔离;组件只能有另一个根节点;

全局组件

data 必须是函数式写法,必须有返回值

Vue.component("", {})

局部组件

Vue.component("common", {
    components:{
        "localComponents":{
            // 局部组件,该组件只供common组件使用
        }
    }
})

通信

父传子通信

通过 Prop 向子组件传递数据:不限制类型

父组件在调用子组件的时候赋值

父组件

// 父传子通信,如果动态传值可以对 param 使用 v-bind 绑定

子组件通过 props 属性获取父组件的传参

Vue.component("child", {
    template:
        `
        
        `,
    // props:["param"]
    // 属性验证
    props:{
    	param:String
    }
})

完整示例


<html>
    <head>
        <meta charset="utf-8">
        <title>title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
        <script src="https://unpkg.com/axios/dist/axios.min.js">script>
    head>
    <body>
        <div id="commucation">
            <p>父组件p>
            <child param="君不见黄河之水天上来">child>
        div>
    body>

    <script type="text/javascript">	
        // 组件之间互不影响,没有任何关联,但是可以通信
        // 子组件
        Vue.component("child", {
            template:
            `
            
            `,
            // props:["param"]
            // 属性验证
            props:{
                param:String
            }
        })

        // 父组件
        let vm = new Vue({
            el: "#commucation"
        })
    script>
html>	

子传父通信

通过事件通知父组件

子组件通过事件通知父组件调用子组件时绑定的事件

childClick(){
	console.log("子组件点击调用")
	// 使用 this.$emit 通知父组件的中调用子组件标签中的事件,1000 为参数
	this.$emit("noticeevent", 1000);
}

父组件在调用子组件的时候绑定事件,并指定父组件中接收参数的函数

# 调用子组件

父组件

# 接收参数的函数 // 父组件 let vm = new Vue({ el: "#commucation", methods:{ // data 为子组件传的参数 getChildParam(data){ console.log("data", data) } } })

完整示例


<html>
    <head>
        <meta charset="utf-8">
        <title>title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
        <script src="https://unpkg.com/axios/dist/axios.min.js">script>
    head>
    <body>
        <div id="commucation">
            <p>父组件p>
            <child @noticeevent="getChildParam">child>
        div>
    body>

    <script type="text/javascript">	
        // 组件之间互不影响,没有任何关联,但是可以通信
        // 子组件
        Vue.component("child", {
            template:
            `
            
            `,
            methods:{
                childClick(){
                    console.log("子组件点击调用")
                    // 通知父组件的中调用子组件标签中的事件
                    this.$emit("noticeevent", 1000);
                }
            }
        })

        // 父组件
        let vm = new Vue({
            el: "#commucation",
            methods:{
                getChildParam(data){
                    console.log("data", data)
                }
            }
        })
    script>
html>

refs 通信

  1. ref 绑定在标签上, this.$refs 获取原生标签;
  2. ref 绑定在组件上, this.$refs 获取时组件对象;

ref 绑定在标签上


<html>
    <head>
        <meta charset="utf-8">
        <title>title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
        <script src="https://unpkg.com/axios/dist/axios.min.js">script>
    head>
    <body>
        <div id="commucation">
            <input type="text" ref="name"/>
            <button type="button" @click="getDom">GETbutton>
        div>
    body>

    <script type="text/javascript">			
        // 父组件
        let vm = new Vue({
            el: "#commucation",
            methods:{
                getDom(){
                    // this.$refs 获取所有ref
                    // this.$refs.name 获取ref值为name的节点
                    // this.$refs.name.value 获取ref值为name节点的值
                    console.log("获取的值为:", this.$refs.name.value)
                }
            }
        })
    script>
html>

ref 绑定在组件上

父传子

父组件通过 ref 绑定调用子组件的调用标签,通过 this. r e f s . c h i l d C o m p o n e n t ( c h i l d C o m p o n e n t 指 定 的 是 父 组 件 调 用 子 组 件 绑 定 的 r e f 值 ) 获 取 子 组 件 , 通 过 t h i s . refs.childComponent (childComponent指定的是父组件调用子组件绑定的ref值)获取子组件,通过 this. refs.childComponentchildComponentrefthis.refs.childComponent.getParent(params) 调用子组件的函数


<html>
    <head>
        <meta charset="utf-8">
        <title>title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
        <script src="https://unpkg.com/axios/dist/axios.min.js">script>
    head>
    <body>
        <div id="commucation">
            <p>父组件p>
            <input type="text" ref="inputVal"/>
            <button type="button" @click="transferVal">通过refs传值给子组件button>
            <child ref="childComponent">child>
        div>
    body>

    <script type="text/javascript">	
        // 组件之间互不影响,没有任何关联,但是可以通信
        // 子组件
        Vue.component("child", {
            template:
            `
            
            `,
            methods:{
                getParent(data){
                    console.log("获取父组件的值为:", data)
                }
            }
        })

        // 父组件
        let vm = new Vue({
            el: "#commucation",
            methods:{
                transferVal(){
                    console.log("this.$refs.inputVal.value", this.$refs.inputVal.value);
                    let params = this.$refs.inputVal.value;
                    // 获取ref绑定的子组件,并调用子组件的函数(可以传参)
                    // this.$refs.childComponent 获取子组件
                    // this.$refs.childComponent.getParent(params) 调用子组件的函数
                    this.$refs.childComponent.getParent(params);
                }
            }
        })
    script>
html>

bus 通信(简单的非父子通信)

发布订阅模式,通过同一个 vue 实例作为中间件中心


<html>
    <head>
        <meta charset="utf-8">
        <title>title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
        <script src="https://unpkg.com/axios/dist/axios.min.js">script>
    head>
    <body>
        <div id="commucation">
            <p>父组件p>
            <child1>child1>
            <child2>child2>
        div>
    body>

    <script type="text/javascript">	
        // 创建一个 vue 实例,作为中央事件总线
        let bus = new Vue();

        // 子组件 1
        Vue.component("child1", {
            template:
            `
            
            `,
            methods:{
                transferData(){
                    console.log("开始输出数据");
                    // 通知dataMount事件
                    bus.$emit("dataMount", "君不见黄河之水天上来")
                }
            }
        })

        // 子组件 2
        Vue.component("child2", {
            template:
            `
            
            `,
            mounted() {
                // 监听dataMount事件
                bus.$on("dataMount", (data)=>{
                    console.log("the data is ", data);
                })
            }
        })

        // 父组件
        let vm = new Vue({
            el: "#commucation"
        })
    script>
html>

Vuex

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    // 共享状态
  },
  mutations: {
    // 用于修改共享状态
  },
  actions: {
    // ajax 异步请求调用 mutations 中的函数,修改共享状态
  },
});

// 其他vue组件通过 "this.$store.state.共享状态属性" 进行访问

动态组件


<component :is="">component>


<keep-alive>
	<component :is="">component>
keep-alive>

slot 插槽

插槽是混合父组件的内容混到子组件中


<html>
	<head>
		<meta charset="utf-8">
		<title>title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
		<script src="https://unpkg.com/axios/dist/axios.min.js">script>
	head>
	<body>
		<div id="commucation">
			<p>父组件p>
			<child>
				
				<ul>
					<li>11111111li>
					<li>22222222li>
					<li>33333333li>
				ul>
			child>
		div>
	body>
	
	<script type="text/javascript">	
		// 子组件 2
		Vue.component("child", {
			template:
			`
				
			`
		})
		
		// 父组件
		let vm = new Vue({
			el: "#commucation"
		})
	script>
html>

具名插槽

插槽具有名字,可以使用name属性指定使用插槽的位置

父组件使用 slot 属性指定插槽名称

子组件使用 指定slot名称


<html>
	<head>
		<meta charset="utf-8">
		<title>title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
		<script src="https://unpkg.com/axios/dist/axios.min.js">script>
	head>
	<body>
		<div id="commucation">
			<p>父组件p>
			<child>
				
				<div slot="slot1">aaaaadiv>
				<div slot="slot2">bbbbbdiv>
				<div slot="slot3">cccccdiv>
			child>
		div>
	body>
	
	<script type="text/javascript">	
		// 子组件 2
		Vue.component("child", {
			template:
			`
				
			`
		})
		
		// 父组件
		let vm = new Vue({
			el: "#commucation"
		})
	script>
html>

动画

推荐:https://github.com/daneden/animate.css

使用方式:

君不见黄河之水天上来

轮播/滑动效果

推荐:https://www.swiper.com.cn/

指令

指令不在 Vue 实例中

指令可以传js对象

指令具有生命周期

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el,binding) {
    // el 是原生节点,binding 表示标签值
    // 聚焦元素 
    el.focus()
  }
})

过滤器

自定义过滤器


<html>
	<head>
		<meta charset="utf-8">
		<title>title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
		<script src="https://unpkg.com/axios/dist/axios.min.js">script>
	head>
	<body>
		<div id="commucation">
			{{name | msgFilter}}
		div>
	body>
	
	<script type="text/javascript">
		let vm = new Vue({
			el: "#commucation",
			data:{
				name: "君不见黄河之水天上来"
			},
			filters:{
				msgFilter: function(value){
					console.log("value", value)
					// 处理数据
					return value.split('之')[1];
				}
			}
		})
	script>
html>

路由

路由容器


hash 路由

location.hash 切换
window.onhashchange 监听路径的切换

history 路由

// 路径没有 # 
const router = new Router({
	mode : "history",
})

history.pushState 切换
window.onpopstate 监听路径的切换

嵌套路由

import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'

// 注册路由模块
Vue.use(Router)

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'home', 
      alias: "/index", // 别名
      component: Home,
      children:[
        {
          path: '/',
          name: 'home',
          component: Home,
        }
      ]
    },
    // 重定向
    {
      path: '/li',
      name: 'li',
      redirect: "/about"
    }
  ]
})

动态路由配置

{
    # 使用 :id 做动态路由配置,: 是做一个占位符
    path: '/detail/:id1/:id2/:id3',
    name: 'home'
    component: Detail
}
# 编程式路由
## 路径跳转
this.$router.push(`/path/{id}`)
## 路由名称跳转
this.$router.push({name:"",params:{}})
# 声明式路由

获取hash值

# 获取当前路由
let hashVal = location.hash
# 获取当前路由信息
this.$route

路由守卫

全局守卫

在 router.js 配置

router.befaoreEach((to, from, next) => {
	if(to.path === '/center'){
		// 拦截判断
		if(usre.isLogin()){
			// 有登录信息,可以访问
			next();
		}else{
			// 无登录信息,需要登录
			next('/login')
		}
	}else{
		// 允许过去
		next();
	}
})

Vuex

  1. 管理共享状态——解决非父子通信
  2. 数据快照——缓存后端数据,避免重复请求,影响用户体验
  3. 时光旅行——调式

你可能感兴趣的:(前端)