2021-10-24发布(25修改) Vue学习笔记

Vue学习笔记

作者 黄姚的黄和姚

  1. 书写Vue基本模板

  • 修改vue中data的值 页面变化 状态变化=> 视图变化 数据响应式
  • 再也不会关心DOM的更新 只关心数据
- 1. 首先要在头部导入Vue的js文件

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>

- 2. 在body里面写一个模板div,id为app,或者其它的名字

<body>
	<div id="app"> 
		<!-- vue的代码就写这里面 -->
		{{message}}     // 插值表达式 app里变量写这里面
	</div>
	
	<script>
	  // Vue是构造函数
	  console.log(Vue);     
	  
	  - 3. 照下面的模板写
	  
	  // 定义一个Vue实例
	  var app = new Vue({  
	    el: "#app",     	  // el 元素 vue需要接管的元素
		
	    data: {               // data vue实例对象的数据(状态)[对象]
	      message: "hello world",
	      t: Date.now(),
	      link: "http://www.baidu.com",
	      name: "百度",
	      show: true,

	    },
		
		//  --------------方法----------------
	    methods: {           // methods 专门用于定义组件方法的地方  [对象]
	      // 普通函数 不要乱用箭头函数 箭头函数没有this
	      clickHandler: function () {
		
	      },
		  
		  fanfa(): {
			  
		  },

	    },
		
		//  --------------计算属性------------
		computed: {          // computed 计算属性 里面的值 不是方法
			//   Vue 知道 val 依赖于 data中的某个值,
			//   因此当 data中的某个值 发生改变时,所有依赖 val 的绑定也会更新
			val: function(){
				// <!-- 事件处理代码 -->
				return 值;   // 需要返回一个值
			},
		
		// 不同的是计算属性是基于它们的响应式依赖进行缓存的。
        // 只在相关响应式依赖发生改变时它们才会重新求值
		
		},
		
		//  --------------监听----------------
		watch: {             // watch 变量监听 监听某个变量的变化 一旦变量发生变化立刻对应的触发方法
			val: function(newVal, oldVal){
				// <!-- 事件处理代码 -->
			},
		
		//  当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的
		
		},
		
		//  --------------组件----------------
		component: {
			
		},
		
		//  ------------生命周期--------------
		//  (创建前、创建后、挂载前、挂载后、更新前、更新后、销毁前、销毁后)
		//  这里只看三个
		
		// 创建后 最早能读到 this
		created: function () {
		  // console.log("创建之后", this, document.querySelector(".test"));
		},
		
		// 挂载后 最早能获取到 DOM
		mounted: function () {
		  // console.log("挂载之后", this, document.querySelector(".test"));
		},
		
		// 销毁后
		destroyed: function () {
		  console.log("销毁之后");
		},
		
	  });
	
</body>


  1. Vue组件模板

  • 只能有根组件,可以有多个子组件
	// 组件要用 component 定义
	Vue.component("todo-item", {
		
		// todo-item 组件现在接受一个
		// "prop",类似于一个自定义 attribute。
		// 这个 prop 名为 todo。
		// 子组件里面的props属性,用来接收根组件传来的值
		props: ["todo"],    
		
		// data 组件里data一定要用函数包着并返回
		data: function(){
			return {
				val: "",
				number: 0,
				
			}
		}
		template: "<li>{{todo.text}}</li>",
		
		// 根组件有的子组件也有
		methods、computed 等
	});

  1. 指令

  • v-bind: 可简写成 : 用来绑定标签里面的属性名,然后传相应的值
	<div v-bind:src="link"></div>
	<div :src="link"></div>
	
	<!-- ----------------------------- 
	data: {     // data vue实例对象的数据(状态)[对象]
	  link: "http://www.baidu.com",
	},
	-->
  • v-for 遍历数组或者对象 生成标签
	<ul>
		<li v-for="arr in arrs">{{arr}}</li>
		<li v-for="arr of arrs">{{arr}}</li>

		<li v-for="obj in objs">{{arr}}</li>
		<li v-for="obj of objs">{{arr}}</li>
		
		<!-- in 和 of 是一样的 of比较接近js语法 建议用of -->
		
		<!-- 多参数用逗号隔开 还要用小括号括起来 -->
		<li v-for="(obj, index) of objs">{{index}} - {{obj}}</li>
		
		
		<!-- ----------------------------- 
		data: {     // data vue实例对象的数据(状态)[对象]
		  arrs: [],
		  objs: {},
		},
		-->
	</ul>
  • v-if / v-else / v-else-if 条件渲染
	<template v-if="show">    <!-- template 空标签 不渲染在页面中 -->
		show = true
	</template>
	
	<template v-if="show1"> 
		show1 = false
	</template>
	
	<template v-if="show1"> 
		show1 = false
	</template>
	<template v-else-if="show2"> 
		show2 = true
	</template>
	<template v-else="show1"> 
		show1 = false
	</template>
	
	<!-- v-if 和 v-else-if 还有 v-else 连用时,要紧挨着,中间不能隔着其他标签 -->

    <!-- ----------------------------- 
	data: {     // data vue实例对象的数据(状态)[对象]
	  show: true,
	  show1: false,
	  show2: true,
	},
	-->
  • v-on: 可简写成 @ 用于绑定事件 click mouseup mousedowm keyup…
	<button v-on:click="方法名"></button>
	<button v-on:click="reverseMessage"></button>
	<button @click="reverseMessage"></button>
	
	<!--  
	methods: {
	  reverseMessage: function () {
		  console.log(111);
	  },
	},
	-->
  • v-model 用于与变量双向绑定
	<input v-model="val">
		{{val}}

		<!-- -----------------------------
		data: {     // data vue实例对象的数据(状态)[对象]
		  val: "",
		},
	-->
  • v-once
  • v-text
  • v-html
  • v-show

  1. class & style

    <style>
      .active {
        background-color: green;
      }
      .text-danger {
        color: red;
      }
    </style>
	
	<body>
	    <div id="app">
	      <!-- class -->
	      <!-- 对象语法 -->
	      <div v-bind:class="{ active: isActive }">{ active: isActive }</div>
	
	      <div
	        class="static"
	        v-bind:class="{ active: isActive, 'text-danger': hasError }"
	      >
	        { active: isActive, 'text-danger': hasError }
	      </div>
	      <!-- 你可以在对象中传入更多字段来动态切换多个 class。
	            此外,v-bind:class 指令也可以与普通的 class attribute 共存 -->
	
	      <div class="static" v-bind:class="classObject">classObject</div>
	
	      <!-- 数组语法 -->
	
	      <div v-bind:class="[activeClass, errorClass]">
	        [activeClass, errorClass]
	      </div>
	
	      <div v-bind:class="[isActive ? activeClass : '', errorClass]">
	        [isActive ? activeClass : '', errorClass]
	      </div>
	
	      <div v-bind:class="[{active: isActive}, errorClass]">
	        [{active: isActive}, errorClass]
	      </div>
	
	      <!-- style -->
	      <!-- 对象语法 -->
	      <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">
	        { color: activeColor, fontSize: fontSize + 'px' }
	      </div>
	    </div>
	
	    <script>
	      new Vue({
	        el: "#app",
	        data: {
	          isActive: true,
	          hasError: true,
	          //   classObject: {
	          //     active: true,
	          //     "text-danger": true,
	          //   },
	
	          activeClass: "active",
	          errorClass: "text-danger",
	          activeColor: "red",
	          fontSize: "12",
	        },
	        computed: {
	          classObject: function () {
	            return {
	              active: this.isActive,
	              "text-danger": this.hasError,
	            };
	          },
	        },
	      });
	    </script>
	
	
	<!-- 
	
	chrome WebKit->Blink
	firefox  Gecko
	ie  Trident
	Opera  chrome Blink WebKit
	sifar WebKit
	edge chrome Blink
	
	排版引擎
	WebCore
	KHTML
	
	 -->
	  </body>
	
  1. 表单

	<style type="text/css">
		p.active {
			text-decoration: line-through;
		}
	</style>
	<body>
		<div id="app">
			<input type="text" v-model.trim.lazy="value" /><br>
			<!-- 输入时不变,失去焦点改变value -->
			<input type="text" v-model.trim.number="num" /><br>
			<!-- 读取数字 -->
			<!-- <textarea cols="30" rows="10">{{value}}</textarea> -->
			<textarea cols="30" rows="10" v-model="value"></textarea>
			<br />
			<hr>
			<!-- 单个复选 布尔 -->
			<input type="checkbox" checked v-model="checked" />
			<p :class="{active:checked}">{{msg}}</p>
			<br />
			<hr>
			<!-- 单个复选 布尔 -->
			<input type="checkbox" checked v-model="checked2" true-value="yes" false-value="no" />

			<br />
			<hr>
			<!-- 多个复选 绑定到数组 -->
			<label>
				<input type="checkbox" value="A" v-model="fav" />
				<span>苹果</span>
			</label>
			<label>
				<input type="checkbox" value="B" v-model="fav" />
				<span>葡萄</span>
			</label>
			<label>
				<input type="checkbox" value="O" v-model="fav" />
				<span>橘子</span>
			</label>

			<br />
			<hr>
			<!-- 单选 -->
			<label>
				<input type="radio" value="male" v-model="gender" />
				<span>男</span>
			</label>
			<label>
				<input type="radio" value="female" v-model="gender" />
				<span>女</span>
			</label>
			<br />
			<!-- 下拉选择 -->
			<select v-model="selected">
				<option value="bmw">bmw</option>
				<option value="volvo">volvo</option>
				<option value="benz">benz</option>
			</select>

			<select v-model="multipleSeleted" multiple>
				<option value="bmw">bmw</option>
				<option value="volvo">volvo</option>
				<option value="benz">benz</option>
			</select>
		</div>
		<script>
			var vm = new Vue({
				el: "#app",
				data: {
					num: "",
					value: "hello",
					checked: true,
					checked2: "yes",
					fav: ["A"],
					gender: "female",
					selected: "benz",
					multipleSeleted: ["volvo"],
					msg: "today mission",
				},
			});
		</script>
	</body>s

  1. 动画过渡

  • v-enter

  • v-enter-active

  • v-enter-to

  • v-leave

  • v-leave-active

  • v-leave-to

	<style type="text/css">
		.active {
			color: #FFA500;

		}

		.slideH1 {
			transition: all .5s;
		}

		.slide-enter {
			transform: translateX(200px);
			opacity: 0;
		}
		
		/* .slide-enter {
		  transform: translateX(300px);
		  opacity: 0;
		} */

		.slide-enter-active {
			transition: all 4s;
		}

		.slide-enter-to {
			transform: translateX(-100px);
		}

		.slide-leave {
			/* transform: translateY(0px); */
			/* opacity: 0.1; */
		}

		.slide-leave-active {
			transition: all 1s;
		}

		.slide-leave-to {
			transform: translateY(100px);
			opacity: 0;
		}
	</style>

	<body>

		<div id="app">
			<button type="button" @click="toggle">toggle</button>
			<h1 :class="{active: awesome}"> VUE VUE VUE VUE</h1>
			<!-- <transition name="move"> -->
			<!-- <h1 v-if="awesome"> VUE comming2222 </h1> -->
			<!-- <h1 v-show="awesome"> VUE comming111 </h1> -->
			<!-- 放两个第二个没显示 -->
			<!-- </transition> -->

			<!-- 	<transition-group name="moves">
				<h1 v-if="awesome" :key="1"> VUElsit comming2222 </h1>
				<h1 v-show="!awesome" :key="2"> VUElist comming111 </h1>
			</transition-group> -->

			<transition name="slide">
				<h1 v-if="awesome" class="slideH1">
					<----vue slide vue silde vue slide</h1>
			</transition>

			<!-- 在<transition标签里面插入或者删除标签时>,
			vue会自动自动嗅探目标元素是否应用了 CSS 过渡或动画,
			如果是,在恰当的时机添加/删除 CSS 类名。-->

		</div>

		<script type="text/javascript">
			let vm = new Vue({
				el: "#app",
				data: {
					awesome: true,
				},
				methods: {
					toggle: function() {
						this.awesome = !this.awesome;
						console.log(this.awesome);
					}
				}
			});
		</script>
	</body>

  1. 事件

	<style>
		.big {
			width: 150px;
			height: 150px;
			background-color: red;
		}

		.box {
			width: 100px;
			height: 100px;
			background-color: lightblue;
		}

		.small {
			width: 50px;
			height: 50px;
			background-color: lightcoral;
		}
	</style>
	</head>
	<body>
		<div id="app">
			<p @click="count++">
				{{count}} 行内 count ++
			</p>
			<p @click="count += 1">
				{{count}} 行内 count += 1
			</p>
			<p @click="increment">
				{{count}} 调用函数不带参
			</p>
			<p @click="incrementN(2)">
				{{count}} 调用函数带参 (2)
			</p>
			<p @click="incrementN(10, $event)">
				<!-- $event 这里代表 DOM事件对象 -->
				可以通过参数 $event 来访问DOM事件对象
			</p>

			<hr />

			<!-- 事件修饰符 stop capture prevent  self once   passive scroll事件 移动端 -->
			<!-- .prevent 阻止默认事件 -->
			prevent 是拦截默认事件,passive是不拦截默认事件。
			<br>
			通俗点说就是每次事件产生,浏览器都会去查询一下是否有preventDefault阻止该次事件的默认动作。我们加上passive就是为了告诉浏览器,不用查询了,我们没用preventDefault阻止默认动作。
			<br>
			这里一般用在滚动监听,@scoll,@touchmove。因为滚动监听过程中,移动每个像素都会产生一次事件,每次都使用内核线程查询prevent会使滑动卡顿。我们通过passive将内核线程查询跳过,可以大大提升滑动的流畅度。
			<br>
			注:passive和prevent冲突,不能同时绑定在一个监听器上。

			<a @click.prevent="increment" href="http://ww.baidu.com">baidu</a>
			<a @click.prevent href="http://ww.baidu.com">baidu</a>
			<!-- 空的也可以 即不调用函数-->

			<!-- .self -->
			<div class="big" @click.self="big">
				big
				<div class="box">box</div>
			</div>

			<hr />
			<!-- stop 阻止冒泡事件 -->
			<!-- capture 事件捕获 -->
			<!-- 会先 执行带有事件捕获修饰符的事件,
			再执行冒泡事件,
			遇到.stop修饰符会停下来,
			所有事件执行并只执行一次
			 -->

			<div class="big" @click.capture="big">
				big
				<div class="box" @click.self="box">
					box
					<div class="small" @click.capture="small">
						small
						<div @click="btn">btn</div>
					</div>
				</div>
			</div>

			<!-- once -->
			<p @click.once="count ++ ">
				{{count}} 使用.once后事件只能触发一次
			</p>

			<!-- self -->
			<p @click.prevent.self="btn">
				btn .self设置后,自身事件只能由自身去触发
				不能通过冒泡触发
			<p @click="btn2">
				btn2
			</p>
			</p>

			<!-- 按键修饰符 up down left right enter space esc tap delete -->
			<!-- 系统修饰键 ctrl alt shift 要按下之后才能按下一个键 -->
			<input type="text" placeholder="@keyup.up.down.left.right" @keyup.up.down.left.right="keyupHandler"
				v-model.trim="value" />
			<input type="text" placeholder="@keyup.ctrl.alt.up" @keyup.ctrl.alt.up="keyupHandler"
				v-model.trim="value" />
			<input type="text" placeholder="@keyup.ctrl.up" @keyup.ctrl.up="keyupHandler" v-model.trim="value" />
			<input type="text" placeholder="@keyup.ctrl.up.exact" @keyup.ctrl.up.exact="keyupHandler"
				v-model.trim="value" />
			<input type="text" placeholder="@keyup.Backspace" @keyup.Backspace="keyupHandler" v-model.trim="value" />


			<!-- .exact允许你控制由精确的   系统修饰符 (ctrl alt shift)   组合触发的事件 -->
			<!-- 只能同时出现组合的按键才触发,多一个其他按键都不行 -->
			<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
			<button v-on:click.ctrl="keyupHandler">A</button>

			<!-- 有且只有 Ctrl 被按下的时候才触发 -->
			<button v-on:click.ctrl.exact="keyupHandler">A</button>

			<!-- 没有任何系统修饰符被按下的时候才触发 -->
			<button v-on:click.exact="keyupHandler">A</button>
			
			

			<!-- 鼠标按钮修饰符 left right middle -->
			<button v-on:mousedown.left="keyupHandler">B</button>
			<button v-on:mousedown.right="keyupHandler">B</button>
			<button v-on:mousedown.middle="keyupHandler">B</button>
			
			
		</div>

		<script type="text/javascript">
			let vm = new Vue({
				el: "#app",
				data: {
					count: 10,
					value: "",
				},
				methods: {
					increment: function(event) {
						this.count += 1;
						console.log(this.event);
					},
					incrementN: function(n, e) {
						this.count += n;
						console.log(n, e);
					},
					clickHandler(event) {
						cconsole.log("click", event);
					},
					big() {
						console.log("big");
					},
					box() {
						console.log("box");
					},
					small() {
						console.log("small");
					},
					btn() {
						console.log("btn");
					},
					btn2() {
						console.log("btn2")
					},
					keyupHandler($event) {
						console.log($event);
					},
				},
			});
		</script>
	</body>

  1. 反向传值

  • 第一种

  • 子组件 : template(<标签名 @事件名="$emit(‘自定义事件名’, 参数1, 参数2…)"></标签名>)

  • 根组件 : <子组件 @自定义事件名=“根组件方法”></子组件> 传多少个参数过来,就在方法里面定义多少个参数接收

  • 第二种

  • 子组件 : template(<标签名 @事件名=“子组件方法(参数…)”></标签名>)
    在子组件的方法里面用 this.$emit(“自定义事件名”, 参数1, 参数2…);

  • 根组件 : <子组件 @自定义事件名=“根组件方法”></子组件> 传多少个参数过来,就在方法里面定义多少个参数接收

  • 第三种

  • 子组件 : 直接在子组件的方法里面用 this.$emit(“自定义事件名”, 参数1, 参数2…);

  • 根组件 : <子组件 @自定义事件名=“根组件方法”></子组件> 传多少个参数过来,就在方法里面定义多少个参数接收

  <body>
    <div id="app">
      <!-- 自定义事件 -->
      <!-- 父级组件可以像处理 native DOM 事件一样通过 v-on 监听子组件实例的任意事件 -->
      <counter :n="n" @decrement="zengjia"></counter>
      <counter :n="n" v-on:decrement-n="zengjiaN"></counter>
      <!-- <counter :n="n" v-on:decrement-n="n-=$event"></counter> -->
      <!-- $event 自定义事件抛出的值 -->
    </div>
    <script>
      Vue.component("counter", {
        props: ["n"],

        data: function () {
          return {
            count: 5,
          };
        },
        template: `
         <div>
            <p>parent n is {{n}},  you clicked {{count}} times </p>
            <button @click='count++'>count++</button>
            <button @click='$emit("decrement")'>--</button>
            <button @click='$emit("decrement-n", 5)'>-n</button>
         </div>`,
      });
      // 同时子组件可以通过调用内建的 $emit 方法并传入事件名称来触发一个事件
      // 子组件methods内部 用this.$emit

      var vm = new Vue({
        el: "#app",
        data: {
          n: 10,
        },
        methods: {
          zengjia() {
            // console.log(123);
            this.n--;
          },
          // 自定义事件触发的方法 默认参数就是 子组件抛出的值
          zengjiaN(num) {
            // console.log(456, a);
            this.n -= num;
          },
        },
      });
    </script>
  </body>

  1. 传值

  • 根传子
  • 直接在标签中绑定 子用props接收
  • 子传根
  • 要使用$emit()方法 根要在标签中接收
  • 子传子
  • 子先传给根,根再传给另一个子

  1. 组件基础

  <body>
    <div id="app">
      <h1>根组件内容: {{msg}}</h1>
      <test :xxx="msg"></test>
      <counter :n="n"></counter>
      <counter :n="n"></counter>
      <counter :n="n"></counter>

      <ul>
        <post-item
          v-for="item in posts"
          :post="item"
          :title="item.title"
        ></post-item>
      </ul>
    </div>
    <script>
      Vue.component("post-item", {
        props: ["post", "title"],
        template: `
        <div>
            <h3>title:{{post.title}}</h3>
            <p>content:{{post.content}}</p>
        </div>
        `,
      });
    //   每个组件必须只有一个根元素

      Vue.component("test", {
        props: ["xxx"],
        template: "<p>test组件 {{xxx}}</p>",
      });

      Vue.component("counter", {
        props: ["n"],
        // data: {
        //   count: 5,
        // },
        data: function () {
          return {
            count: 5,
          };
        },
        // 组件内的data 必须是一个 函数 返回一个对象
        // 因此每个实例可以维护一份被返回对象的独立的拷贝
        template:
          "<p @click='count++'>parent n is {{n}},  you clicked {{count}} times </p>",

        // template:
        //   "<p @click='n++'>parent n is {{n}},  you clicked {{count}} times </p>",
        //   不能直接修改props的值 只能修改自己的data
        // 所有的组件都只能修改自身的data
      });

      var vm = new Vue({
        el: "#app",
        data: {
          msg: "hello vue",
          n: 10,

          posts: [
            { title: "123", content: "123content" },
            { title: "456", content: "456content" },
            { title: "789", content: "789content" },
          ],
        },
      });
    </script>
  </body>

  1. 修饰符

  • 事件修饰符

    • .stop
    • .prevent
    • .capture
    • .self
    • .once
    • .passive
  • 按键修饰符

    • .enter
    • .tab
    • .delete (捕获“删除”和“退格”键)
    • .esc
    • .space
    • .up
    • .down
    • .left
    • .right
  • 系统修饰符

    • .ctrl
    • .alt
    • .shift
    • .meta
    • .exact
    • .left
    • .right
    • .middle

  1. vue-cli

安装
npm install -g @vue/cli

查看版本
vue --version

创建项目
vue create hello-world

一路回车

运行服务器
npm run serve

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值