vue2.0+vue3.0资料(五)

简介: vue2.0+vue3.0资料(五)

二、Vue-CLI


分区作者:Cool小陈


1、Vue脚手架安装与部署


1-1、依赖软件 nodejs


1、下载nodejs


http://nodejs.cn/download/


https://registry.npmmirror.com/binary.html?path=node/


    X86  适用 32 windows


    X64  适用 64 windows


2、下一步


   安装目录: 不要中文不要有空格


   c:/program files/nodejs


1.3:  检测(windows->开始->运行->cmd)


node -v


网络异常,图片无法展示
|


1-2、安装cnpm 工具(nodejs工具 npm 安装软件)


npm install -g cnpm --registry=https://registry.npm.taobao.org
#npm 安装工具
#install 安装 uninstall 删除
#-g  全局
#https://registry.npm.taobao.org 淘宝镜像站点
#检测

网络异常,图片无法展示
|


1-3、安装vue-cli脚手架(安装一个3.x版本的Vue脚手架)


npm install -g @vue/cli
//npm i -g @vue/cli


1-4、安装创建项目


1-4-1、vue create xxx安装


//protest是项目名,自定义的
vue create protest

这里会有选项出来,可以选第一项,但是建议选第三项,自定义(高手就选这个),选择特性以创建的项目为准


使用键盘上下键移动,回车选定,勾选特性用空格进行勾选


选了第三项之后,接下来出现的页面:


网络异常,图片无法展示
|


网络异常,图片无法展示
|


网络异常,图片无法展示
|


网络异常,图片无法展示
|


选择Router


网络异常,图片无法展示
|


接下来,选择2.x,回车:


网络异常,图片无法展示
|


接下来,是否选用历史模式的路由,输入n或者y,看个人情况即可,回车:


网络异常,图片无法展示
|


接下来,ESLint选择选择第三项,回车:


网络异常,图片无法展示
|


接下来,何时进行ESLint语法效验,选第一项,回车:


网络异常,图片无法展示
|


接下来,babel,protcss等配置文件如何放置,选默认的第一项:单独使用文件进行配置,回车:


网络异常,图片无法展示
|


最后,是否保存为模板,以后创建项目的模板。看个人n和y都可以:


网络异常,图片无法展示
|


整个模板:


网络异常,图片无法展示
|


加载完成后出现的页面:


输入cd 建的项目名称


网络异常,图片无法展示
|


执行npm run serve后出现的页面:


网络异常,图片无法展示
|


Local和Network的两个地址(服务器的地址)都可以直接点开页面


到这里,项目创建完成


1-4-2、基于ui界面创建vue项目


执行一下命令,可以打开ui界面


vue ui


安装Element-UI
Element-UI:是一套2.0的桌面组件库


1.在终端输入:


npm install element-ui -S

2.在入口文件(src/main.js)导入添加:


import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
Vue.use(ElementUI);


额外的步骤:


网络异常,图片无法展示
|


网络异常,图片无法展示
|


2、分析脚手架


2-1、脚手架文件结构


├── node_modules 放置node模块
├── public
│   ├── favicon.ico: 页签图标
│   └── index.html: 主页面//网站访问入口
├── src         项目源码
│   ├── assets: 存放静态资源
│   │   └── logo.png
│   │── component: 存放组件
│   │   └── HelloWorld.vue
│   │── App.vue: 汇总所有组件
│   │── main.js: 入口文件
├── .gitignore: git版本管制忽略的配置
├── babel.config.js: babel的配置文件
├── package.json: 应用包配置文件 
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件


index.html


<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
  <!-- 针对IE浏览器的一个特殊配置,含义是让IE浏览器以最高的渲染级别渲染页面 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <!-- 开启移动端的理想视口 -->
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <!-- 配置页签图标 -->
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  <!-- 引入第三方样式 -->
  <link rel="stylesheet" href="<%= BASE_URL %>css/bootstrap.css">
  <!-- 配置网页标题 -->
    <title>脚手架基础</title>
  </head>
  <body>
  <!-- 当浏览器不支持js时noscript中的元素就会被渲染 -->
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
  <!-- 容器 -->
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>


2-2、关于不同版本的Vue


main.js中的render函数


esm代表es6中的muddle 使用vue.runtime.xxx.js可以节约空间


关于不同版本的Vue:


   1.vue.js与vue.runtime.xxx.js的区别:


        (1).vue.js是完整版的Vue,包含:核心功能+模板解析器。


        (2).vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。


   2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用


    render函数接收到的createElement函数去指定具体内容。


main.js


/* 
 该文件是整个项目的入口文件
*/
//引入Vue,这里的vue是指运行版的Vue,即vue.runtime.xxx.js
import Vue from 'vue'
//引入App组件,它是所有组件的父组件
import App from './App.vue'
new Vue({
 el:'#app',
 //render函数完成了这个功能:将App组件放入容器中
    render: h => h(App),
 // render:q=> q('h1','你好啊') //箭头函数
 // render(createElement) {
 //  return createElement('h1','你好啊')
 // },
 // template:`<h1>你好啊</h1>`,  //精简版不解析template
 // components:{App},
})

2-3、修改默认配置


vue.config.js配置文件


  1. 使用vue inspect > output.js可以查看到Vue脚手架的默认配置。
  2. 使用vue.config.js可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh


2-4、


3、ref属性


3-1、ref属性


  1. 被用来给元素或子组件注册引用信息(id的替代者)
  2. 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
  3. 使用方式:
  1. 打标识:<h1 ref="xxx">.....</h1><School ref="xxx"></School>
  2. 获取:this.$refs.xxx


3-2、案例如下:


App.vue
<template>
 <div>
  <h1 v-text="msg" ref="title"></h1>
  <button ref="btn" @click="showDOM">点我输出上方的DOM元素</button>
  <School ref="sch"/>
 </div>
</template>
<script>
 //引入School组件
 import School from './components/School'
 export default {
  name:'App',
  components:{School},
  data() {
   return {
    msg:'欢迎学习Vue!'
   }
  },
  methods: {
   showDOM(){
    console.log(this.$refs.title) //真实DOM元素
    console.log(this.$refs.btn) //真实DOM元素
    console.log(this.$refs.sch) //School组件的实例对象(vc)
   }
  },
 }
</script>


4、props配置


4-1、props配置项


  1. 功能:让组件接收外部传过来的数据
  2. 传递数据:<Demo name="xxx"/>
  3. 接收数据:
  1. 第一种方式(只接收):props:['name']
  2. 第二种方式(限制类型):props:{name:String}
  3. 第三种方式(限制类型、限制必要性、指定默认值):
props:{
 name:{
 type:String, //类型
 required:true, //必要性
 default:'老王' //默认值
 }
}

备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。


4-2、案例如下


App.vue
<template>
 <div>
  <Student name="李四" sex="女" :age="18"/>
 </div>
</template>
<script>
 import Student from './components/Student'
 export default {
  name:'App',
  components:{Student}
 }
</script>
Student.vue
<template>
 <div>
  <h1>{{msg}}</h1>
  <h2>学生姓名:{{name}}</h2>
  <h2>学生性别:{{sex}}</h2>
  <h2>学生年龄:{{myAge+1}}</h2>
  <button @click="updateAge">尝试修改收到的年龄</button>
 </div>
</template>
<script>
 export default {
  name:'Student',
  data() {
   console.log(this)
   return {
    msg:'我是一个学生',
    myAge:this.age
   }
  },
  methods: {
   updateAge(){
    this.myAge++
   }
  },
  //简单声明接收
  // props:['name','age','sex'] 
  //接收的同时对数据进行类型限制
  /* props:{
   name:String,
   age:Number,
   sex:String
  } */
  //接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
  props:{
   name:{
    type:String, //name的类型是字符串
    required:true, //name是必要的
   },
   age:{
    type:Number,
    default:99 //默认值
   },
   sex:{
    type:String,
    required:true
   }
  }
 }
</script>


5、mixin(混入)属性


5-1、mixin(混入)


  1. 功能:可以把多个组件共用的配置提取成一个混入对象
  2. 使用方式:
    第一步定义混合:
{
data(){....},
methods:{....}
....
}

  1. 第二步使用混入:
    全局混入:Vue.mixin(xxx)
    局部混入:mixins:['xxx']


5-2、案例如下:


mix.js(这里定义了两个混入方法)


//定义了两个的方法
export const hunhe = {
 methods: {
  showName(){
   alert(this.name)
  }
 },
 mounted() {
  console.log('你好啊!')
 },
}
export const hunhe2 = {
 data() {
  return {
   x:100,
   y:200
  }
 },
}
main.js(这里是用了全局混入1和2)
//1、这里引入了两个混入属性在mixin.js中
import {hunhe,hunhe2} from './mixin'
//2、使用mixin.js中的两个混入效果
Vue.mixin(hunhe)
Vue.mixin(hunhe2)
Student.vue(1这里引入混入,2并使用了局部混入)
<template>
 <div>
  <h2 @click="showName">学生姓名:{{name}}</h2>
  <h2>学生性别:{{sex}}</h2>
 </div>
</template>
<script>
    //1、引入混入
 // import {hunhe,hunhe2} from '../mixin'
 export default {
  name:'Student',
  data() {
   return {
    name:'张三',
    sex:'男'
   }
  },
  //2、使用局部混入
  // mixins:[hunhe,hunhe2]
 }
</script>

6、插件


6-1、插件使用步骤


  1. 功能:用于增强Vue
  2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
  3. 定义插件:

对象.install = function (Vue, options) {

 

// 1. 添加全局过滤器
    Vue.filter(....)
    // 2. 添加全局指令
    Vue.directive(....)
    // 3. 配置全局混入(合)
    Vue.mixin(....)
    // 4. 添加实例方法
    Vue.prototype.$myMethod = function () {...}
    Vue.prototype.$myProperty = xxxx
}


  1. 使用插件:Vue.use()


6-2、案例如下:


plugins.js(定义插件)


export default {
 install(Vue,x,y,z){
  console.log(x,y,z)
  //全局过滤器
  Vue.filter('mySlice',function(value){
   return value.slice(0,4)
  })
  //定义全局指令
  Vue.directive('fbind',{
   //指令与元素成功绑定时(一上来)
   bind(element,binding){
    element.value = binding.value
   },
   //指令所在元素被插入页面时
   inserted(element,binding){
    element.focus()
   },
   //指令所在的模板被重新解析时
   update(element,binding){
    element.value = binding.value
   }
  })
  //定义混入
  Vue.mixin({
   data() {
    return {
     x:100,
     y:200
    }
   },
  })
  //给Vue原型上添加一个方法(vm和vc就都能用了)
  Vue.prototype.hello = ()=>{alert('你好啊')}
 }
}
main.js(引入并且使用插件的js)
//引入插件
import plugins from './plugins.js'
//应用(使用)插件
Vue.use(plugins,1,2,3)
School.vue(使用mySlice全局过滤器、使用Vue原型上的hello方法)
<template>
 <div>
  <h2>学校名称:{{name | mySlice}}</h2>
  <h2>学校地址:{{address}}</h2>
  <button @click="test">点我测试一个hello方法</button>
 </div>
</template>
<script>
 export default {
  name:'School',
  data() {
   return {
    name:'abcdefghighlim',
    address:'北京',
   }
  },
  methods: {
   test(){
    this.hello()
   }
  },
 }
</script>
Student.vue(使用fbind全局指令)
<template>
 <div>
  <h2>学生姓名:{{name}}</h2>
  <h2>学生性别:{{sex}}</h2>
  <input type="text" v-fbind:value="name">
 </div>
</template>
<script>
 export default {
  name:'Student',
  data() {
   return {
    name:'张三',
    sex:'男'
   }
  },
 }
</script>

7、scoped样式


7-1、scoped用法


  1. 作用:让样式在局部生效,防止冲突。
  2. 写法:<style scoped>


7-2、案例如下:


App.vue
<template>
 <div>
  <h1 class="title">你好啊</h1>
  <School/>
  <Student/>
 </div>
</template>
<script>
 import Student from './components/Student'
 import School from './components/School'
 export default {
  name:'App',
  components:{School,Student}
 }
</script>
<style scoped>
 .title{
  color: red;
 }
</style>

7-3、Todo-list案例


网络异常,图片无法展示
|


7-4、总结TodoList案例


1、组件化编码流程:


(1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。


(2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:


1).一个组件在用:放在组件自身即可。


2). 一些组件在用:放在他们共同的父组件上(状态提升)。


(3).实现交互:从绑定事件开始。


2、props适用于:


(1).父组件 ==> 子组件 通信


(2).子组件 ==> 父组件 通信(要求父先给子一个函数)


3、使用v-model时要切记:


v-model绑定的值不能是props传过来的值,因为props是不可以修改的!


4、修改props中的值的情况


props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。


5、数据在哪里,操作数据就在哪里


关于表格中的删除效果和移动高亮


li:hover{
  background-color: #ddd;
 }
 li:hover button{
  display: block;
 }

reduce条件统计


//原来
let i=0
this.todos.foreach((todo))=>{
    if(todo.done) i++
}
//用reduce后
/* const x = this.todos.reduce((pre,current)=>{
     console.log('@',pre,current)
     return pre + (current.done ? 1 : 0)
    },0) */
//简写
    return this.todos.reduce((pre,todo)=> pre + (todo.done ? 1 : 0) ,0)


8、浏览器本地存储


8-1、webStorage


  1. 存储内容大小一般支持5MB左右(不同浏览器可能还不一样)
  2. 浏览器端通过 Window.sessionStorage 和 Window.localStorage 属性来实现本地存储机制。
  3. 相关API:
  1. xxxxxStorage.setItem('key', 'value');
    该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。
  2. xxxxxStorage.getItem('person');
    该方法接受一个键名作为参数,返回键名对应的值。
  3. xxxxxStorage.removeItem('key');
    该方法接受一个键名作为参数,并把该键名从存储中删除。
  4. xxxxxStorage.clear()
    该方法会清空存储中的所有数据。
  1. 备注:
  1. SessionStorage存储的内容会随着浏览器窗口关闭而消失。
  2. LocalStorage存储的内容,需要手动清除才会消失。
  3. xxxxxStorage.getItem(xxx)如果xxx对应的value获取不到,那么getItem的返回值是null。
  4. JSON.parse(null)的结果依然是null。


localStorage.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>localStorage</title>
 </head>
 <body>
  <h2>localStorage</h2>
  <button onclick="saveData()">点我保存一个数据</button>
  <button onclick="readData()">点我读取一个数据</button>
  <button onclick="deleteData()">点我删除一个数据</button>
  <button onclick="deleteAllData()">点我清空一个数据</button>
  <script type="text/javascript" >
   let p = {name:'张三',age:18}
   function saveData(){
    localStorage.setItem('msg','hello!!!')
    localStorage.setItem('msg2',666)
    localStorage.setItem('person',JSON.stringify(p))
   }
   function readData(){
    console.log(localStorage.getItem('msg'))
    console.log(localStorage.getItem('msg2'))
    const result = localStorage.getItem('person')
    console.log(JSON.parse(result))
    // console.log(localStorage.getItem('msg3'))
   }
   function deleteData(){
    localStorage.removeItem('msg2')
   }
   function deleteAllData(){
    localStorage.clear()
   }
  </script>
 </body>
</html>
sessionStorage.html
<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8" />
  <title>sessionStorage</title>
 </head>
 <body>
  <h2>sessionStorage</h2>
  <button onclick="saveData()">点我保存一个数据</button>
  <button onclick="readData()">点我读取一个数据</button>
  <button onclick="deleteData()">点我删除一个数据</button>
  <button onclick="deleteAllData()">点我清空一个数据</button>
  <script type="text/javascript" >
   let p = {name:'张三',age:18}
   function saveData(){
    sessionStorage.setItem('msg','hello!!!')
    sessionStorage.setItem('msg2',666)
    sessionStorage.setItem('person',JSON.stringify(p))
   }
   function readData(){
    console.log(sessionStorage.getItem('msg'))
    console.log(sessionStorage.getItem('msg2'))
    const result = sessionStorage.getItem('person')
    console.log(JSON.parse(result))
    // console.log(sessionStorage.getItem('msg3'))
   }
   function deleteData(){
    sessionStorage.removeItem('msg2')
   }
   function deleteAllData(){
    sessionStorage.clear()
   }
  </script>
 </body>
</html>


 

8-2、TodoList案例添加本地存储


把App.vue加一个监视属性并且设置它里面todos的初始值


//1设置todos初始值,将todos:[]改成
todos:JSON.parse(localStorage.getItem('todos')) || []
//2添加一个监视属性,并且进行深度监视
watch: {
   todos:{
    deep:true,
    handler(value){
     localStorage.setItem('todos',JSON.stringify(value))
    }
   }
  },


9、组件自定义事件


9-1、组件的自定义事件


  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件
  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
  3. 绑定自定义事件:
  1. 第一种方式,在父组件中:<Demo @at1="test"/>  或 <Demo v-on:at1="test"/>
  2. 第二种方式,在父组件中:
<Demo ref="demo"/>
    ......
    mounted(){
      this.$refs.xxx.$on('at1',this.test)
    }
  1. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。
  1. 触发自定义事件:this.$emit('at1',数据)
  2. 解绑自定义事件this.$off('at1')
  3. 组件上也可以绑定原生DOM事件,需要使用native修饰符。
  4. 注意:通过this.$refs.xxx.$on('at1',回调)绑定自定义事件时,回调要么配置在methods中要么用箭头函数,否则this指向会出问题!


9-2、TodoList案例添加自定义事件


MyHeader中的:addTodo="addTodo"改成@addTodo="addTodo"


然后把props中的addTodo删掉,然后使用


事件名.$emit(addTodo,value)


//1将这里的<MyHeader :addTodo="addTodo"/>改成
<MyHeader @addTodo="addTodo"/>
//2找到props中可能存在的addTodo,然后删掉
//3在methods里面的add中添加this.$emit('at1',数据)
this.$emit('addTodo',todoObj)


10、全局事件总线


10-1、可以实现任意组件间的通信(图解)


网络异常,图片无法展示
|


x组件需满足


1、所有的组件都能看见x组件


2、x能被调用到(

网络异常,图片无法展示
|
off以及$emit)


10-2、全局事件总线(GlobalEventBus)


  1. 一种组件间通信的方式,适用于任意组件间通信
  2. 在main.js中安装全局事件总线:
    方法一、
const Demo = vue.extend({})
const d = new Demo()
Vue.prototype.x = d

方法二、(提倡这种方法)

  1. 使用事件总线:
  1. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。
methods(){
  demo(data){......}
}
......
mounted() {
  this.$bus.$on('xxxx',this.demo)
}
  1. 提供数据:this.$bus.$emit('xxxx',数据)
  1. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。


10-3、TodoList事件总线


全局事件总线的本质是给组件绑定自定义事件,只不过这里的组件是this.$bus也就是Vue实例对象


目录
相关文章
|
2月前
|
JavaScript
vue3高雅的使用useDialog
vue3高雅的使用useDialog
95 0
|
11月前
|
JavaScript 前端开发 算法
Vue day01
Vue day01
49 0
|
2月前
|
JavaScript 前端开发 编译器
Vue3 究竟好在哪里?
Vue3 究竟好在哪里?
76 0
|
2月前
|
JavaScript
selectpicker 与vue整合
selectpicker 与vue整合
|
9月前
|
设计模式 缓存 JavaScript
|
7月前
|
JavaScript
vue-demi
vue-demi
80 0
|
8月前
|
JavaScript
Vue中,$forceUpdate()的使用
Vue中,$forceUpdate()的使用
45 0
|
10月前
|
JavaScript
Vue3使用less
Vue3使用less
273 0
|
12月前
|
JavaScript 数据可视化 算法
|
缓存 JavaScript
Vue3中name有什么用呢?
<script setup> 只要在script开启setup语法糖模式 单文件组件会自动根据文件名生成对应的 name 选项 例如 Tree.vue 那他的name 就是 Tree 自动生成,这样做有一个弊端如果想修改name需要修改组件名称如果有地方import 该组件需要一并修改。
236 0
Vue3中name有什么用呢?