vue
Vue介绍
vue分为两个版本,开发版本development和生产版本production
开发版本:vue.js
生产版本:vue.js
被压缩成了一行,所有不必要的注释/空格/换行等,都被删除,而且删除了所有的提示,目的是为了减小项目体积,使打开页面更快,项目上线时用。
使用Vue
文本差值
js中的数据,展示在界面上,相当于原生js中的innerText方法
原始html
本指令相当于原生js中的html
Attribute 绑定
V-bind来修改标签的属性,简写用:即可。
布尔型Attribute
同时绑定多个Attribute
使用javascript表达式
注意:每个绑定仅支持单一表达式,也就是一段能够被求值的javascript代码(语句不可以)。
调用函数
可以在绑定的表达式里调用函数,但非常不建议这样做,可以使用Math或Data等全局暴露的函数。
<p>生成一个随机数{{Math.random()}}</p>
computed计算属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <p>{{reverseStr}}</p> <ul> <li><p>{{text.split('').reverse().join('')}}</p></li> <!--上方代码,同样的功能要计算两次,消耗性能,并且导致html代码臃肿,下方的更佳--> <li><p>{{reverseStr}}</p></li> </ul> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { text:'hello world' } }, computed:{ reverseStr(){//这里一定要指定this,text,this指的是当前实例,可以理解为data里的数据 return this.text.split('').reverse().join('') } } }).mount('#app') </script>
事件处理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <p>{{count}}</p> <button v-on:click="add()">+</button> <button @click="add()">+</button> <button v-on:click="less()">-</button> <button @click="less()">-</button> <button @click="add(5)">+5</button> <button @click="add(6)">+6</button> <button @click="less(5)">-5</button> <button @click="less(6)">-6</button> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { count: 0 } }, computed: {//计算属性 }, methods: {//方法 add(a = 1) { // this.count=this.count+a this.count += a }, less(a = 1) { // this.count=this.count-a this.count -= a } } }).mount('#app') </script>
计算属性vs方法
注意:计算属性和方法,在结果上确实是相同的,然而不同之处在于
计算属性会基于其响应式依赖而被缓存
,一个计算属性仅会在其响应式依赖更新时才会被重新计算
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <input type="number" v-model="count"> <p>输入数字乘以2:{{ChengYi2}}</p> <p>methods:{{methodChengYi2()}}</p> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { count: 0 } }, computed: {//当数据来源被改变,则计算属性重新计算 ChengYi2() { return this.count * 2 } }, methods: {//方法 methodChengYi2() { return this.count * 2 } } }).mount('#app') </script>
条件渲染
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <ul> <li v-if="type==='A'">AAAAAA</li> <!-- <li v-else-if="type==='B'">BBBBBB</li>--> <li v-else>CCCCCC</li> </ul> <p v-show="seen">现在你看得到我</p> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { type:'B', seen:true } } }).mount('#app') </script>
列表渲染
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <table> <thead> <tr> <th>id</th> <th>书名</th> <th>价格</th> </tr> </thead> <tbody> <tr v-for="{book,index} of books" :key="index"> <!-- key一般是数据库里的数据上的唯一且不重复的主键-即id--> <td>{{book.id}}</td> <td>{{book.name}}</td> <td>{{book.price}}</td> </tr> </tbody> </table> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { books:[ {id:0,name:'三体',price:68}, {id:1,name:'平凡的世界',price: 89}, {id:2,name:'三国演义',price:40} ] } } }).mount('#app') </script>
表单输入绑定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js/vue.js"></script> </head> <body> <div id="app"> <input type="text" :value="text" @input="ipt($event)"> <input type="text" v-model="text"> <p>{{text}}</p> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { text:'hello world' } }, // methods:{ // ipt(event){ // this.text=event.target.value // } // } }).mount('#app') </script>
多行文本
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../node_modules/vue/dist/vue.global.js"></script> </head> <body> <div id="app"> <textarea v-model="message" placeholder="add multiple lines"></textarea> <!-- 多行文本,即换行符,可以被v-module实时修改数据--> <p style="white-space: pre-line;">{{ message}}</p> <!-- 此css属性可以展示字符串中的换行符--> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { message: '' } }, }).mount('#app') </script>
数据单项绑定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../node_modules/vue/dist/vue.global.js"></script> </head> <body> <div id="app"> <label for="ipt"></label> <input type="checkbox" id="ipt" :checked="checked">打篮球 <!-- 数据单项绑定,data驱动ui,ui不可修改data--> <p>{{checked}}</p> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { checked:false } }, }).mount('#app') </script>
数据双项绑定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../node_modules/vue/dist/vue.global.js"></script> </head> <body> <div id="app"> <label for="ipt"></label> <input type="checkbox" id="ipt" v-model="checked">打篮球 <!-- 数据单项绑定,data驱动ui,ui不可修改data--> <p>{{checked}}</p> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { checked:false } }, }).mount('#app') </script>
将多个复选框绑定到同一个数组或集合
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../node_modules/vue/dist/vue.global.js"></script> </head> <body> <div id="app"> <h2>选中的人是:{{checkedNames}}</h2> <input type="checkbox" v-model="checkedNames" value="Jack"> <input type="checkbox" v-model="checkedNames" value="John"> <input type="checkbox" v-model="checkedNames" value="Mike"> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { checkedNames:[] } }, }).mount('#app') </script>
单选框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../node_modules/vue/dist/vue.global.js"></script> </head> <body> <div id="app"> <h2>选中的人是:{{picked}}</h2> <input type="radio" v-model="picked" value="1">男 <input type="radio" v-model="picked" value="0">女 <input type="radio" v-model="picked" value="-1">自定义 </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { picked:1 } }, }).mount('#app') </script>
选择器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../node_modules/vue/dist/vue.global.js"></script> </head> <body> <div id="app"> <div>Selected: {{ selected }}</div> <select v-model="selected"> <option disabled value="">Please select one</option> <option>A</option> <option>B</option> <option>C</option> </select> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { selected:'' } }, }).mount('#app') </script>
注意
如果
v-model
表达式的初始值不匹配任何一个选择项,<select>
元素会渲染成一个“未选择”的状态。在 iOS 上,这将导致用户无法选择第一项,因为 iOS 在这种情况下不会触发一个 change 事件。因此,我们建议提供一个空值的禁用选项,如上面的例子所示。
多选
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../node_modules/vue/dist/vue.global.js"></script> </head> <body> <div id="app"> <div>Selected: {{ selected }}</div> <select v-model="selected" multiple> <!-- <option disabled value="">Please select one</option>--> <option>A</option> <option>B</option> <option>C</option> </select> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { selected:'' } }, }).mount('#app') </script>
修饰符 lazy number trim
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../node_modules/vue/dist/vue.global.js"></script> </head> <body> <div id="app"> <input type="text" v-model="message"> <input type="text" v-model.lazy="message"> <input type="text" v-model.number="message"> <input type="text" v-model.trim="message"> <p>{{message}}</p> </div> </body> </html> <script> const {createApp} = Vue createApp({ data() { return { message: '' } }, }).mount('#app') </script>
生命周期
侦听器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../node_modules/vue/dist/vue.global.js"></script> <style> @keyframes zhuan { 0%{transform: rotate(0)} 100%{transform: rotate(360deg)} } .active{animation: zhuan 10s linear infinite} </style> </head> <body> <div id="app"> <p>{{message}}</p> <input type="text" v-model="message"> <p>{{name}}</p> </div> </body> </html> <script> const {createApp} = Vue const vm=createApp({ data() { return { message:'1111', name:'xxxx' } }, watch:{ message(){//要监听哪个数据,就对应哪个 // console.log('message changed') if (this.message.length>=10) alert('long') } } }).mount('#app') </script>
vue中的dom操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../node_modules/vue/dist/vue.global.js"></script> <style>#test{width: 100px;height: 100px;background: red}</style> </head> <body> <div id="app"> <div id="test" ref="test"></div> <button @click="big">变大div</button> <input type="text" ref="ipt"> </div> </body> </html> <script> const {createApp} = Vue const vm =createApp({ data() { return { } }, methods:{ big(){ //原始js方法,极不推荐 /*const test=document.getElementById('test') test.style.width='200px'*/ console.log(this.$refs) this.$refs.test.style.width='200px' } }, setup(){console.log(this.$refs())}, beforeCreate(){console.log(this.$refs)}, created(){console.log(this.$refs)}, beforeMount(){console.log(this.$refs)}, mounted(){this.$refs.ipt.focus()} }).mount('#app') </script>
vue脚手架
vue-cli
安装
#首先,确保已安装node和npm node-v npm -v #其次,确保npm镜像地址是国内的淘宝镜像(有梯子除外) npm config get registry #如果结果是:https://registry.npmirror.com/则说明是淘宝镜像 #否则就输入: npm config set registry https://registry.npmirror.com/ #再次安装vue-cli: npm i -g @vue/cli #查看版本 vue -V
基于vue-cli创建vue3.0项目
vue create hello-world #项目名必须是小写英文字母 Manally select features #手动选择分支 Bable #仅选择Bable (上下切换,空格选择/取消,回车确认) choose aversion for Vue? #3.X where do you? #in dedicate config files 保存到本地文件 Save this as a preset #no,不保存为未来分支 cd hello-world npm run serve #复制网址到浏览器打开即可
基于vue-cli vueUI创建项目
非常不建议使用,丢人现眼。
基于Vite创建Vue项目
基于vite,不需要安装,只要有node和npm即可,但是node版本要在15.0以上
$npm init vue
项目目录
vue-project ----.vscode 配置vscode 没用 ----node_modules ----public ----src 关键,程序员写代码都在这里面 ------assets 项目所需的静态文件,图片,css,等 ------components 组文件夹 ------App.vue 根组件 ------main.js ----.gitignore git上传时,不要的文件配置 ----index.html 页面,仅包含一个#app ----package.json ----package-lock.json ----README.md ----vite.config.js vite配置文件
组件
组件是vue中框架的基石,是最重要的部分。
新建组件
在vite创建项目中创建组件:
在components文件夹下,右键新建.vue文件,就是一个组件
<template> <p>这里面写标签 外层的template仅做辅助编译,将来生成的html界面中,不存在template标签</p> <div> 在过去,vue2中,这里的根标签必须仅能有一个(即template的亲儿子只能有一个),vue3不做限制 </div> </template> <script> //这里面写js export default {//对外暴露,ES6模块化的语法,等同于node中commonJs中的module.exports name: "HelloWorld", data() { return { message: '' } } } </script> <style scoped> /*这里是css 这里的scoped,通过给被选中的标签生成独一无二的随机属性名来让当前css仅在本组中生效*/ </style>
引入组件
在组建中引入组件
<template> </template> <script> import HelloWorld from './components/HelloWorld.vue' //编辑器可能会把.vue省略掉,vite中一定要加上 //如果在vue-cli中,可以不加.vue后缀 export default { name: "Header-1", } </script> <style scoped> </style>
注册组件
注册组件分两种,分别为注册局部组件和注册全局组件。
注册局部组件(常用)
<template> </template> <script> import HelloWorld from './components/HelloWorld.vue' //编辑器可能会把.vue省略掉,vite中一定要加上 //如果在vue-cli中,可以不加.vue后缀 export default { name: "Header-1", components:{ //HelloWorld:HelloWorld HelloWorld }//注册组件 } </script> <style scoped> </style>
全局注册组件
main.js
import {createApp} from 'vue' import App from './App.vue' import Header1 from './components/Header-1.vue'//引入 createApp(App).component('Header1',Header1)//全局注册 .mount('#app')
使用组件
父组件
<template> <HelloWorld></HelloWorld> <HelloWorld/> <hello-world></hello-world> <hello-world/> </template>