Vue简述
Vue是一套构建用户界面的前端框架。
建用户界面的意思是:往html中填充数据。
框架的意思是:一套开发规范。
Vue的特点
1.数据驱动视图
当页面是一个普通的展示时,数据改变了,Vue会充当中间驱动者的角色,把视图更新。
2.双向数据绑定
当做form表单时,表单的默认展示数据来自于特点1, 当用户在form表单添加数据时,对的数据模型会同步更新到本地维护的data上。![](/i/l/?n=23&i=blog/826860/202212/826860-20221214231819790-814180142.png)
Vue的原理
Vue采用MVVM设计模式,View指html页面, Model指Ajax获取的数据,ViewModel指Vue。 Vue是一个实例对象,它内部通过监听的方式进行工作。 1.监听数据改变,更新UI页面 2.监听DOM变化,更新数据Model![](/i/l/?n=23&i=blog/826860/202212/826860-20221214231856603-1006422260.png)
Vue简单的使用场景
要3个条件 1.提供一个让Vue控制的视图View, 让View帮我们把数据自动填充到里面 2.内部维护一组数据源,用于在View视图上展示 3.创建一个Vue实例对象,通过对象的MVVM双向绑定,让View与Mode直接实现数据的双向流动。<body> <!-- 希望Vue实例管理的区域,帮我们把数据填充到该区域里 --> <div id="root">{{username}}</div> <script src="./lib/vue-2.6.12.js"></script> <script> // vue实例对象负责处理View, Model之间的双向流动。 // vue实例的入参是它要监听的两头,el: 使用选择器寻找它要监听管理的View容器, data: 数据源与view做双向绑定。 const vm = new Vue({ el: "#root", data: { username: 'Frog' } }); </script> </body>
Vue脚手架vue-cli vue-cli是一个帮助开发者自动配置webpack的工具,使用vue-cli可以快速开启一个项目,让开发者只关注自己的业务开发。 安装与使用
npm install -g @vue/cli
vue-cli版本降级
从vue-cli v4的版本 降回v3
npm uninstall -g @vue/cli //安装指定版本 npm install -g @vue/cli@版本号//vue cli3 的最高版本 3.12.1 npm install -g @vue/[email protected]
使用vue -V验证是否安装成功
zhoufeideMacBook-Pro-2:lession0 zhoufei$ vue -V @vue/cli 5.0.8
vue create 项目名称
vue2模板选择![](/i/l/?n=23&i=blog/826860/202212/826860-20221214232239063-1670068691.png)
SPA 单页面应用:所有的功能都在一个页面中实现,一个项目就一个页面。
vue默认用于开发SPA 单页面应用。 如:vue-cli工具生成的工程中只有一个index.html入口文件。![](/i/l/?n=23&i=blog/826860/202212/826860-20221214232341202-1157394456.png)
并且vue编写的js代码编译打包后,会嵌入到div#app的下面
![](/i/l/?n=23&i=blog/826860/202212/826860-20221214232351094-1225190385.png)
main.js是项目的入口,webpack打包的入口在这里
App.vue根组件,项目的结构在这里定义 components: 定义的组件放置在这个目录下![](/i/l/?n=23&i=blog/826860/202212/826860-20221214232432036-875902267.png)
Vue的运行流程
在工程化项目中,vue是通过main.js把App.vue渲染到index.html指定的区域中。 App.vue用来编写待渲染的模板结构 index.html中需要预留一个el区域 main.js把App.vue渲染到index.html预留的区域中。 main.js项目入口// 导入vue框架,在js全局当如Vue构造方法 import Vue from 'vue' // 导入App.vue根组件,将根组件替换到index.html的#app标签 import App from './App.vue' Vue.config.productionTip = false new Vue({ el: '#app', //#app标签,占位标签 render: h => h(App), // 返回要替换#app占位标签的根组件 })
App.vue根据组件
<template> <div> <p>这是第1篇文章</p> <p>这是第2篇文章</p> <p>这是第3篇文章</p> <p>这是第4篇文章</p> <p>这是第5篇文章</p> <p>这是第6篇文章</p> <p>这是第7篇文章</p> <p>这是第8篇文章</p> </div> </template>
Vue挂载方式,下面2种是一样的。
new Vue({ render: h => h(App), }).$mount('#app') new Vue({ el: '#app', //#app标签,占位标签 render: h => h(App), // 返回要替换#app占位标签的根组件 })
Vue组件化开发
Vue是一个支持组件化开发的框架,其中定义的组件是以.vue结尾。 App.vue文件本质上也是一个vue组件。 组件是一个可以复用的UI结构。 template是组件的模板结构。script和style是为模板提供交互和样式的。 除了data, props, 生命周期 使用函数的方式定义,其他定义都和Vue实例的设置一样。<template> <!-- template模板是组件的结构,下面的style和script都是模板的修饰 --> <div id="app"> 自定义组件 --- {{ username }} <button @click="changeName">修改名字</button> </div> </template> <script> export default { // 组件中的data定义和vue实例对象中data的定义不一样 // 组件中的data定义是一个函数,在函数的return里返回一个对象 data: function (params) { return { username: 'Lilei' } }, // 除了data需要使用函数,其他定义都和Vue实例的传参一样。 methods: { changeName () { this.username = '娃哈哈' } }, watch: {}, filters: {}, computed: {} } </script> <!-- 修改css的预处理器使用lang来设置 --> <style lang="less"> .app { background-color: antiquewhite; button { font-size: 20; } } </style>
Vue指令 内容渲染指令 有三种: v-text:直接覆盖指令,不常用 {{ }}: 差值表达式,在位置上展示,常用 v-html:标签内容展示,可以展示html标签样式。
<!-- 内容渲染指令 --> <p v-text="username">姓名:</p> <p v-text="gender">性别:</p> <hr> <p>姓名: {{ username }}</p> <p>性别: {{ gender }}</p> <hr> <p v-html="info">内容:</p>
属性绑定指令
属性动态绑定使用v-bind:修饰, 或者可以省略v-bind, 直接一个:就可以了<input type="text" v-bind:placeholder="placeholder"> <input type="text" :placeholder="placeholder">
其中属性绑定v-bind:和差值表达式里面都可以写一些简单的js语句
<p>1+2: {{ 1+2 }}</p> <input type="text" :placeholder=" '1+2:'+ 1+2 ">
事件绑定指令
视图上,通过v-on:绑定一个事件,比如v-on:click绑定一个点击事件。<!-- 事件绑定指令 --> <p>统计结果: {{ count }}</p> <!-- v-on:可以简写成@, @click; 如果方法要传参,可以直接在方法的”“里面使用add(1)进行表示 --> <button v-on:click="add(2)" >加二</button> <!-- 如果方法sub没有传参,系统会默认传递一个event参数, 如果sub(1)传参,那么这个默认事件event参数就会被覆盖--> <button v-on:click="sub" >减一</button> <!-- 如果即要传参又要传递事件event, 可以使用Vue提供的系统事件$event当做普通参数传递sub(1, $event) --> <button v-on:click="sub2(2, $event)" >减二</button>
处理方法的添加是放在Vue({methods})项上
并且在methods上,方法推荐使用sub(){},简写的形式,无需显示使用key:value的形式。<script> const vm = new Vue({ el: '#app', data: { username: 'Frog', }, methods: { add: function (n) { vm.count += n }, sub(e) { //推荐这样简写 //vm就等于this, 是一个实例对象 this.count -= 1 console.log(e); if (this.count % 2 === 0) { // e.target是事件的响应对象 e.target.style.backgroundColor = 'red'; } else { e.target.style.backgroundColor = ''; } }, sub2(n, e) { console.log(n); console.log(e); } } }) </script>
<div id="app"> <!-- 事件修饰符:阻止默认行为,停止冒泡 --> <a href="http://www.baidu.com" @click.prevent="goBaidu">跳转到百度</a> </div>
<script> const vm = new Vue({ el: '#app', data: { username: 'Frog', }, methods: { goBaidu(e) { e.preventDefault() console.log('跳转到baidu'); } } }) </script>
按键修饰符
<div id="app"> <!-- 按键修饰符 --> <input type="text" @keyup.esc="cleanHandler" @keyup.enter="commitHandler"> </div>
<script> const vm = new Vue({ el: '#app', data: { username: 'Frog', }, methods: { cleanHandler(e){ //当esc键 弹出时回调 console.log(e.target); }, commitHandler(e){ console.log('提交'); } } }) </script>
双向数据绑定指令
双向数据绑定是用于表单提交数据的场景 model数据与表单中的input输入框的value通过v-model进行双向绑定, 当用户输入数据时,Vue实例监听到,然后将数据更新到Model中。 因为Vue有数据驱动视图的特点,当数据改变了就会驱动视图上数据的更新。 这个一去,一回的循环构成了双向绑定的效果。<div id="app"> <p>用户名:{{ username }}</p> <input type="text" v-model="username"> <hr> <input type="text" :value="username"> <hr> <select v-model="city"> <option value="0">请选择城市</option> <option value="1">北京</option> <option value="2">上海</option> <option value="3">广州</option> </select> </div>
<script> const vm = new Vue({ el: '#app', data: { username: '', city: '0' } }) </script>
v-model指令修饰符
双向绑定有三种指令修饰符 number: 将输入的字符串自动转成数字 trim: 自动剪裁掉输入数据两头的空格 lazy:只在输入完成,点击enter时才触发数据更新<!-- v-model双向绑定修饰符 --> <input type="text" v-model="num1"> + <input type="text" v-model ="num2"> = <span>{{ num1 + num2}}</span> <hr> <input type="text" v-model.number="num1"> + <input type="text" v-model.number ="num2"> = <span>{{ num1 + num2}}</span> <hr> <input type="text" v-model.trim="username"> <hr> <!-- 当点击enter时才更新,而不每次修改都更新 --> <input type="text" v-model.lazy="username">
const vm = new Vue({ el: '#app', data: { username: '', city: '0', num1: 1, num2: 1 } })
条件渲染指令
<div id="app"> <!-- v-if隐藏时,p标签会从Dom中移除 --> <p v-if="flag">这是用v-if渲染的</p> <!-- v-show隐藏时,只是display:none --> <p v-show="flag">这是用v-show渲染的</p> <div v-if="scoe === 'A'">优秀</div> <div v-else-if="scoe === 'B'">良好</div> <div v-else-if="scoe === 'C'">及格</div> <div v-else>不及格</div> </div>
<script> vm = new Vue({ el: '#app', data: { flag: true, scoe: 'A' } }) </script>
列表渲染指令
<div id="app"> <table class="table table-bordered table-hover table-striped"> <thead> <th>索引</th> <th>id</th> <th>姓名</th> </thead> <tbody> <!-- 列表渲染,需要展示哪种列表,就在那个上面写v-for --> <!-- 写了v-for,同时要写一个key作为唯一标识,这个key只能是数字或字符串,并且拥有有效的唯一性 --> <tr v-for="(item, index) in list" :key="item.id" :title="item.name + index"> <td>{{ index }}</td> <td>{{ item.id }}</td> <td>{{ item.name }}</td> </tr> </tbody> </table> </div>
<script> vm = new Vue({ el: '#app', data: { list: [ {id:1, name:'zhangsan'}, {id:2, name:'lisi'}, {id:3, name:'wangwu'} ] } }) </script>
过滤器
<div id="app"> <!-- 过滤器:管道符,和linux系统提供的管道操作相似,过滤器是一个函数,定义在filters下面 --> <p>{{ message | capi }}</p> <hr> <p>时间:{{ new Date() | dateFormate }}</p> <!-- 过滤器可以连续调用多次,并且过滤器可以传参,但是传递的参数在接收时是从第2个开始的,第1个默认是管道传参。 过滤在Vue3被剔除了 --> <!-- <p>时间:{{ new Date() | dateFormate1(param1, param2) | dateFormate }</p> --> </div>
// 添加全局过滤器 Vue.filter('dateFormate', function (time) { const dtstr = dayjs(time).format('YYYY-HH-DD HH:mm:ss') return dtstr }) vm = new Vue({ el: '#app', data: { message: 'hello vue.js' }, // 过滤器是一个函数,它定义在filters下面 filters: { capi(val) { // val: 标识通过管道符传过来的值 var one = val.charAt(0).toUpperCase() var two = val.slice(1) return one + two } } })
侦听器
<div id="app"> <input type="text" v-model="username"> <hr> <input type="text" v-model="userBigName"> <hr> <input type="text" v-model="userInfo.city"> </div>
侦听器有2种:函数监听器,对象监听器
函数监听器比较简单,只能直接监听,方法执行时直接接收监听的属性或子属性 对象监听器比较复杂,强大,可以设置页面加载完成时默认执行一次回调和对象属性子属性的深层监听var vm = new Vue({ el: '#app', data: { username: '', userBigName: 'admin', userInfo: { city: '' } }, watch: { // 函数监听器,监听哪个属性,方法名就是那个属性名 // 第一个是新值,第二个是旧值 // 缺点1:页面初始化时没法自动触发 // 缺点2:当属性是一个对象时,修改对象中的属性,函数监听器无法监听到 username(newV, oldV) { console.log(newV, oldV); $.get('https://www.escook.cn/api/finduser/'+newV, function(res){ console.log(res); console.log($); }) }, // 对象侦听器,侦听哪个属性,key值就设置成哪个属性名 // 优点1:通过设置immediate为true, 可以在页面加载时,默认执行一次调用 userBigName: { handler(newV, oldV) { console.log(newV, oldV); $.get('https://www.escook.cn/api/finduser/'+newV, function(res){ console.log(res); console.log($); }) }, immediate: true }, // 对象侦听器,可以监听对象属性中的子属性 // 优点2:对象侦听器可以开启深度监听,修改属性对象中的一个子属性,收到监听回调 userInfo: { handler(newV) { console.log(newV); }, deep: true }, // 子属性方法监听器,解决缺点2 // 可以使用下面这个'属性.子属性'的方法,做方法监听。可以做到直接监听到子属性,并且newV打印的也是子属性的值 'userInfo.city'(newV) { console.log(newV); } } })
计算属性
定义时按照方法定义,使用时按照属性使用,在内存中的保存形式是属性 data属性和计算属性中的数据是同步更新的。<div id="app"> <input type="text" v-model.number="r"> <input type="text" v-model.number="g"> <input type="text" v-model.number="b"> <div class="box" v-bind:style="{backgroundColor: rgb }"> {{ rgb }} </div> </div>
var vm = new Vue({ el: '#app', data: { r: 0, g: 0, b: 0 }, // 计算属性 // 定义时用方法定义,使用时按属性使用,在内存中保存的也是属性形式 // 优点:1.代码复用,2.data属性修改,计算属性会被同步修改 computed: { rgb() { return `rgb(${this.r}, ${this.g}, ${this.b})` } } })
标签:Vue,vue,app,指令,new,data,与其,属性 From: https://www.cnblogs.com/zhou--fei/p/16983980.html