文档

Mdn Web 文档

Vue2文档

md教程文档

库(npm)


Vue组件化编程

开发常用

//delete - ask
confirm

//提示框
alert

//当前实例
event.target.value/checked
//值
$event

//遍历
this.list.forEach((c)=>{
if(c.name)
})

//ES6 -- 条件统计-- reduce
// 统计初始值为0,长度为n则被调用几次,pre:上一次值,current:当前值
// 继续调用,则pre为上一次reduce的return值
return this.todos.reduce((pre,current)=>{
return pre + (current.done? 1 : 0)
},0)

//实例销毁
this.$destroy()

//声明原生dom事件
@click.native

//数据占位--不使用
demmo('_',b){}

//.trim 去除头尾空白符

//函数
chen:function(){}
chen(){}

//nanoid 随机生成id
//安装 npm i nanoid -->import { nanoid } from 'nanoid'
id:nanoid()



脚手架

#安装

npm install -g @vue/cli
# OR
yarn global add @vue/cli
#淘宝镜像
npm config set registry https://registry.npm.taobao.org/npm config set registry

#版本

vue --version
vue -V

#创建项目

vue create "Demo_name"

#运行

#VsCode open folder  cd/cd..
npm run serve




脚手架文件结构

├── node_modules
├── 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:包版本控制文件




非单文件组件

Vue中使用组件的三大步骤:

  • ​ 一、定义组件(创建组件)

使用:Vue.extend(options)创建,其中options.和new Vue(options)时传入的那个options.几乎一样,但也有点区别:

区别如下:

​ 1.e1不要写,为什么?—–最终所有的组件都要经过一个vm的管理,由vm中的e1决定服务哪个容器。

​ 2.data必须写成函数,为什么?避免组件被复用时,数据存在引用关系。 data(){ }

​ 备注:使用template可以配置组件结构。


  • ​ 二、注册组件

1.:局部注册:靠new Vue的时候传入components选项

2.:全局注册:靠Vue.component(‘组件名’,组件)


  • ​ 三、使用组件(写组件标签)
    ​ 编写组件标签:< school>< /school>
<body>
<div id="root">
<div id="root2">
<hello></hello>
</div>
<school></school>
<student></student>
<h2 v-text="chen"></h2>
<student></student>
</div>

<div id="root2">
<hello></hello>
</div>

<script type="text/javascript">
Vue.config.productionTip = false;

//1.创建组件
//2.注册组件
//3.编写组件标签

//创建school组件
const school =Vue.extend({
// 模板结构
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<h2>学校号码:{{number}}</h2>
</div>
`,

// 组件不需要写el配置项,最后要被c实例隔离,由c决定服务哪个容器
data(){
return{
name:'广东东软学院',
address:'广东佛山',
number:'999',
}
}
})

//创建student组件
const student =Vue.extend({
template:`
<div>
<h2>学生名字:{{name}}</h2>
<h2>学生地址:{{address}}</h2>
<h2>学生号码:{{number}}</h2>
</div>
`,

// 组件不需要写el配置项,最后要被c实例隔离,由c决定服务哪个容器
data(){
return{
name:'辰呀',
address:'广东佛山',
number:'9981',
}
}
})

//创建全局hello组件
const hello=Vue.extend({
template:`
<div>
<h2>CP--{{name}}</h2>
</div>
`,
data(){
return{
name:'Liu'
}
}
})

// 全局组件注册
Vue.component('hello',hello)
var c= new Vue({
el:'#root',
// 注册组件(局部注册)--key:value
data:{
chen:99
},
components:{
// xuexiao:school
school:school,
student:student
}
})
new Vue({
el:'#root2'
})

</script>




ref (id替代者)–绑定Dom

#ref属性

  1. 被用来给元素或子件注册引用信息(id的替代者)

  2. 应用在htm1标签上获取的是真实D0M元素,应用在组件标签上是组件实例对象(vc)

  3. 使用方式:

    打标识:< h1 ref=”Xxx”/> 或< Schoo ref=”Xx”/>

    获取:this.$refs,xxxxx

    获取值:const c= this.$refs.Xxx.innerText


<h1 v-text="chen" id="title"></h1>
<h1 v-text="chen" ref="title" @click="log"></h1>

export default {
name:'App',
data() {
return {
chen: '辰呀',
};
},
components:{
School,
Student
},
methods:{
log(){
//绑定dom
const cc=this.$refs.title
cc.style.color="blue"
}
}
}




关于不同版本的Vue

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

  1. vue.js是完整版的Vue,包含:核心功能 + 模板解析器。
  2. vue.runtime.xxx.js是运行版的Vue,只包含:核心功能;没有模板解析器。
  3. 因为vue.runtime.xxx.js没有模板解析器,所以不能使用template这个配置项,需要使用render函数接收到的createElement函数去指定具体内容。




vue.config.js配置文件

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




组件间通讯



一、props – 跨组件传数据

  1. 功能:让组件接收外部传过来的数据

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

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

    (3).使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!

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


  2. 传递数据:<Demo name="xxx"/>

<!--整型传值 v-bind=“value” -->
<School name="广东东软学院" address="广东佛山" :numberc="10999"/>

<!--接收-组件内无需定义 -->
<h1>{{ name }}</h1>
<h1>{{ address }}</h1>
<h1>{{ number }}</h1>

  1. 接收数据(子):

    • 第一种方式(只接收):props:['name']
// 第一种:简单接收     --   常用
props:['name','address','numberc']

  • 第二种方式(限制类型):props:{name:String}
props:{
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
},
number:{
type:Number,
default:199 //默认值
}
}

  • 第三种方式(限制类型、限制必要性、指定默认值):
props:{
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
},
number:{
type:Number,
default:199 //默认值
}
}

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


如需修改,设置中转变量

  data(){
return{
number:this.numberc,
}
},
props:['name','address','numberc']




二、*组件自定义事件 –ref

  • 一种组件间通信的方式,适用于:子组件 ===> 父组件
  • 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。
  • (第一种写法,使用@或v-on)(第二种写法,使用 ref 需要触发 emit )

1、 v-on :name=’name’

  • ​ 父组件设置给子组件绑定一个自定义事件,在methods中配置接收参数和数据处理方法

  • ​ 使用ref,需要在钩子中绑定自定义事件然后被等待调用 –

  • ​ this.$refs.refs名.$on(’自定义事件名‘,回调)


  • 第一种写法,使用  @  /  v-on

    父组件:

通过父组件给子组件传递函数类型的props实现:子给父传递数据

通过父组件给子组件给子组件绑定一个自定义事件实现:子给父传递数据(使用 @ 或 v-on

<School :getSchoolName="getSchoolName"/>

<Student v-on:chen="getStudentName"/>
<Student @chen.once="getStudentName"/>

methods:{
getSchoolName(name){
console.log('App收到了学校名:',name);
},
// getStudentName(name,x,y){console.log('App收到了学生名:',name,x,y)}

// 除了name,剩余包装到params数组中
getStudentName(name,...params){
console.log('App收到了学生名:',name,params)
}
},

  • 子组件 使用 $emit 触发该自定义事件


2、 ref

使用 ref 

通过父组件给子组件给子组件 ref 绑定一个自定义事件实现:子给父传递数据

父组件在钩子中绑定自定义事件** – this.$refs.refs名.$on(’自定义事件名‘,methods函数)

<Student ref="studentc"/>

//钩子中写(第二种写法,使用ref)
mounted(){
//this.$refs.refs名.$on(’自定义事件名‘,methods函数)
this.$refs.studentc.$on('chen',this.getStudentName)//绑定自定义事件
this.$refs.studentc.$on('chen',this.getStudentName)//绑定自定义事情(一次性)
}
  • 子组件 使用 $emit   触发该自定义事件



2、 触发 $emit 

无论是使用 v-on :name=’name’ 还是使用 ref ,子组件都是通过 $emit  进行触发自定义事件 : this.$emit(‘chen’,value)

  • 传递多个数据使用 funcation_name(name,…params):除了name,剩余数据包装到params数组
//子组件
<button @click="sendSchoolName">传递学校名给App</button>
<button @click="sendStudentName">传递学生名给App</button>


methods:{
sendSchoolName(){
this.getSchoolName(this.name)
}
}

methods:{
sendStudentName(){
//触发student组件实例上的chen事件
this.$emit('chen',this.name,1,2,3,4,5)
}
}


3、解绑 – $off

子组件中设置解绑组件实例上的name事件

methods:{
//解绑student组件实例上的chen事件
unbindcc(){
this.$off('chen');//解绑一个自定义事件
this.$off(['chen','demo']);//解绑多个自定义事件
this.$off();//解绑全部自定义事件
}
}




三、数据传递 – 子传父

image-20230406204630440

  • 父组件在methods里面设置一个函数,函数获取调用值,通过v-bind把函数传递到子组件,子组件把要传的值写入该函数的形参中通过传递地址修改值实现

父组件:

<MyHeader :receivea="receivec"/>

data(){
return{
todos:[{id:'01',title:'学习',done:true},]
}},

methods:{
receivec(todoObj){
//接收
this.todos.unshift(todoObj)
}
},

子组件:

props:['receivea'],
methods:{
add(e){
// 将用户输入的内容包装成一个对象
// console.log(event.target.value);
const todoObj = {id:nanoid(),title:e.target.value,done:false}

//传递
this.receive(todoObj)
}
}




四、全局事件总线–bus

image-20230407225625192

1、安装全局事件总线

main.js

  • 安装全局事件总线第一种写法
const Demo=Vue.extend({})
const d=new Demo
Vue.prototype.c=d
//调用c

  • (推荐写法)安装全局事件总线
new Vue({
el:'#app',
render: h => h(App),
beforeCreate(){
Vue.prototype.$bus=this // (推荐)安装全局事件总线
}
})



2、接收数据

  • 使用:this.$bus.$on(‘事件name’,(data)=>{ })

  • 绑定事件

  • 回调留在组件本身

methods:{
demo(data){}
},
mounted(){
//①
this.$bus.$on('hello',(data)=>{
console.log('School组件接收到的数据为:',data)
})
//②
this.$bus.$on('hello',this.demo)
}


3、提供数据

  • 触发:this.$bus.$emit(‘事件name’,data)
  • 绑定事件,传值
methods:{
sendStudentName(){
this.$bus.$emit('hello',666)
}
}


4、销毁

  • beforeDestroy钩子中编写销毁方法
beforeDestroy(){
this.$bus.$off('hello')
}

五、消息订阅与发布 (pubsub)

  1. 一种组件间通信的方式,适用于任意组件间通信


  2. 使用步骤

    安装pubsub

npm i pubsub-js`

② 引入

  • 哪个组件要使用则要导入
import pubsub from 'pubsub-js'

③接收数据

  • A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。
  • this.pubId=pubsub.subscribe(‘ccc’,this.demo)
  • pubId为订阅id,在取消订阅销毁的时候使用到
methods:{
demo(msgName,value){ }
},
mounted() {
//this.pubId=pubsub.subscribe('ccc',(msgName,value)=>{ })
this.pubId=pubsub.subscribe('ccc',this.demo)//订阅消息
},


④.提供数据

  • pubsub.publish(‘xxx’,value)
methods: {
sendStudentName(){
pubsub.publish('ccc',value)
}
}

⑤.取消订阅。

  • beforeDestroy钩子
  • PubSub.unsubscribe(pid)
beforeDestroy() {
pubsub.unsubscribe(this.pubId)
},




mixin混入 – 共享配置

  • 当数据冲突,原数据为主,src创建混合js
  • 新建js文件并配置数据
export const hunhe = {
methods: {
showName(){
alert(this.name)
}
},
mounted() {
console.log('你好啊!')
},
}
export const hunhe2 = {
data() {
return {
x:100,
y:200
}
},
}

  • 引用混合配置

    ①引入混合

import {hunhe,hunhe2} from '../mixin'

②使用

 	<h2>学校地址:{{x}}{{y}}

<script>
import {hunhe,hunhe2} from '../mixin'
export default {
mixins:[hunhe,hunhe2],
}




插件

  1. 功能:用于增强Vue

  2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据

  3. 定义插件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('你好啊')}
}
}


4.引入并使用插件(main.js)

import plugins from './plugins'	
Vue.use(plugins,1,2,3)

5.使用插件

  • 直接使用插件里面方法的名字即可
<h2>学校名称:{{name | mySlice}}</h2>




scoped 样式隔离

  • 在编译的时候,全部组件样式汇总到一起,各组件类名相同时会发生冲突,在App.vue中后引用的组件样式会覆盖上层
//Vscode -- vuecss快捷键
<style scoped>

</style>




本地存储

  1. 存储内容大小一般支持5MB左右(不同浏览器可能还不一样)


  2. 浏览器端通过 Window.sessionStorage(会话,关闭丢失) 和 Window.localStorage 属性来实现本地存储机制。


  3. 相关API:

    xxxxxStorage.setItem(‘key’, ‘value’);

该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。

let p = {name:'张三',age:18}

function saveData(){
localStorage.setItem('msg','hello!!!')
localStorage.setItem('person',JSON.stringify(p))
sessionStorage.setItem('person',JSON.stringify(p))
}

  • xxxxxStorage.getItem(‘person’)

该方法接受一个键名作为参数,返回键名对应的值。

function readData(){
console.log(localStorage.getItem('msg'))
const result = localStorage.getItem('person')
console.log(JSON.parse(result))
}

  • xxxxxStorage.removeItem(‘key’);

该方法接受一个键名作为参数,并把该键名从存储中删除。

function deleteData(){
localStorage.removeItem('msg2')
}

  • xxxxxStorage.clear()

该方法会清空存储中的所有数据。

function deleteAllData(){
localStorage.clear()
}

  • Vue通过深度监视进行读取本地存储数据进行对vc上的数据进行响应式存储
  watch:{
// 深度监视
todos:{
deep:true,
handler(value){
localStorage.setItem('todos',JSON.stringify(value))
}
}
}



nextTick

进行执行代码,如果存在对Dom元素存在修改行为,Vue会执行所有的代码后更新页面Dom。例:执行focus()获取焦点代码后,上部分代码存在修改Dom行为,则执行focus()后所有的代码后页面会被刷新,获取焦点失败。


  1. 语法:this.$nextTick(回调函数)

  2. 作用:在下一次 DOM 更新结束后执行其指定的回调。

  3. 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。

​ 解决方法:

​ ①使用定时器,等待页面刷新后执行

​ ②使用nextTick

this.$nextTick(function(){
this.$refs.Dom_name.focus()//获取焦点例子
})



动画

  • 动画库animate.css - npm

  • #第二动画库
    npm install vue-kinesis
    

    ```html
    <kinesis-container>
    Here, you can put
    <kinesis-element :strength="10"> whatever </kinesis-element>
    <kinesis-element :strength="20"> content! </kinesis-element>
    </kinesis-container>

  • ​ 原css中设置动画
.come{
animation: chen 1s linear;
}
.go{
animation: chen 1s reverse;/* 反转 */
}

@keyframes chen{
from{
transform: translateX(-100%);
}
to{
transform: translateX(0px);
}
}



过渡 – transition

标签

  • appear:初始渲染加入v-enter-active动画(进入网站)

  • 若有多个元素需要过度,则需要使用:,且每个元素都要指定key值。

  • 元素进入的样式:

    1. v-enter:进入的起点

    2. v-enter-active:进入过程中

    3. v-enter-to:进入的终点


  • 元素离开的样式:

    1. v-leave:离开的起点
    2. v-leave-active:离开过程中
    3. v-leave-to:离开的终点
  • 通过 v-show 判断是否显示该 dom实现动画出现和隐退

<button @click="isShow=!isShow">显示/隐藏</button>
<transition>
<h1 v-show="isShow">你好呀</h1>
</transition>

css中的动画设置

.v-enter-active{
animation: chen 1s linear;
}
.v-leave-active{
animation: chen 1s reverse;
}
@keyframes chen{
from{
transform: translateX(-100%);
}
to{
transform: translateX(0px);
}
}


  • 自定义过渡名字
<transition name='cc'>
<h1 v-show="isShow">你好呀</h1>
</transition>

​ css中类名设置:

.cc-enter-active{
animation: chen 1s linear;
}
.cc-leave-active{
animation: chen 1s reverse;
}



封装过渡

<transition-group name="hello" appear>
<h1 v-show="!isShow" key="1">你好啊!</h1>
<h1 v-show="isShow" key="2">尚硅谷!</h1>
</transition-group>
/* 进入的起点、离开的终点 */
.hello-enter,.hello-leave-to{
transform: translateX(-100%);
}
.hello-enter-active,.hello-leave-active{
transition: 0.5s linear;
}

/* 进入的终点、离开的起点 */
.hello-enter-to,.hello-leave{
transform: translateX(0);
}



封装动画

  • #安装第三方库
npm install animate.css --save

  • 在组件中引入
import 'animate.css'

  • 按照库的要求编写 (name、进入:enter-active-class、隐退:leave-active-class)
<transition-group appear
name="animate__animated animate__bounce"
enter-active-class="animate__swing"
leave-active-class="animate__backOutUp">
>
<h1 v-show="!isShow" key="1">你好啊!</h1>
<h1 v-show="isShow" key="2">尚硅谷!</h1>
</transition-group>




vue脚手架配置代理 – axios


node server

方法一

  • 下载axios
npm i axios

  • 当前组件引用
import axios from 'axios'

  • vue.config.js 文件中添加如下配置:
devServer:{
proxy:"http://localhost:5000"
}

//App
getStudents(){
axios.get('http://localhost:8080/students').then(
response => {console.log('请求成功了',response.data);},
error => {console.log('请求失败了',error.message);}
)
},

说明:

  1. 优点:配置简单,请求资源时直接发给前端(8080)即可。
  2. 缺点:不能配置多个代理,不能灵活的控制请求是否走代理。
  3. 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器 (优先匹配前端资源)


方法二


编写 **vue.config.js **配置具体代理规则:

module.exports = {
devServer: {
proxy: {
'/chen': {// 匹配所有以 '/api1'开头的请求路径
target: 'http://localhost:5000',// 代理目标的基础路径
changeOrigin: true,
pathRewrite: {'^/chen': ''}// 路径重写
},
'/peng': {// 匹配所有以 '/api2'开头的请求路径
target: 'http://localhost:5001',// 代理目标的基础路径
changeOrigin: true,
pathRewrite: {'^/peng': ''}// 路径重写
}
}
}
}

端口欺骗:

​ changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000
​ changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080
​ changeOrigin默认值为true


  • 组件中设置
getStudents(){
axios.get('http://localhost:8080/chen/students').then(
response => {console.log('请求成功了',response.data);},
error => {console.log('请求失败了',error.message);})
},
getCars(){
axios.get('http://localhost:8080/chen/cars').then(
response => {console.log('请求成功了',response.data);},
error => {console.log('请求失败了',error.message);})
}

说明:

  1. 优点:可以配置多个代理,且可以灵活的控制请求是否走代理。
  2. 缺点:配置略微繁琐,请求资源时必须加前缀。




Github案例 – axios


调用Github接口

searchUsers(){
// 请求前更新数据
this.$bus.$emit('updateListData',{isFirst:false,isLoading:true,errMsg:'',users:[]})
axios.get(`https://api.github.com/search/users?q=${this.$keyword}`).then(
response=>{
// console.log("请求成功",response.data.items)
this.$bus.$emit('updateListData',{isLoading:false,errMsg:'',users:response.data.items})
},
error=>{
console.log("请求失败",error.message);
this.$bus.$emit('updateListData',{isLoading:false,errMsg:error.message,users:[]})
}
)
}

  • 拓展运算符 … (解构,数据替换)
  • 接收数据 – 接收对象值dataObj – 与data中的对象info进行比较替换,存在的值则替换为dataOb里面的值
mounted(){
// this.$bus.$on('getUsers',this.demo)
this.$bus.$on('updateListData',(dataObj)=>{
this.info={...this.info,...dataObj}
})
}

data(){
return{
info:{
isFirst:true,
users:[],
isLoading:false,
errMsg:''
}
}
},




Vue-resource

  • 安装(插件)
npm i vue-resource

  • 引用(main.js)
import vueResourcec from 'vue-resource
Vue.use(vueResourcec)

  • 使用 – 和 axios 使用方法类似
//使用 -- this.$http.get
this.$http.get(`API`).then(
response=>{},
error=>{}
)



插槽 slot

  • 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件

  • 分类:默认插槽、具名插槽、作用域插槽

  • 使用方式:(在父组件中使用子组件标签不使用自闭合,在标签内插入内容,在子组件中的slot标签内插入,如果不传内容则slot自身内的内容为默认值


  1. 默认插槽(在父组件把内容插入到子组件中 solt)

父组件中(不使用自闭合组件标签)

在父组件把内容插入到子组件中 solt

<Category>
<div>这是一个html结构</div>
</Category>

  • 子组件:<– 定义插槽 –>
<template>
<div>
</slot>如果不插入内容则显示这里的内容(插槽默认内容...)</slot>
</div>
<template>


  1. 具名插槽
  • 定义插槽:子组件给 solt 设置   name  属性
<template>
<div>
<slot name="center">插槽默认内容...</slot>
<slot name="footer">插槽默认内容...</slot>
</div>
</template>

  • 父组件要插入的内容设置 slot=”name”  / v-slot:name 属性,精确插入
<Category>
<template slot="center">
<div>html结构1</div>
</template>

<template v-slot:footer>
<div>html结构2</div>
</template>
</Category>


  1. 作用域插槽
  • 子组件把 数据传递 回插槽的使用者(父组件)

    子组件传递数据:

    name不必和父组件接收name相同

<template>
<div>
<slot :games="games"></slot>
</div>
</template>

export default {
name:'Category',
//数据在子组件自身
data() {
return {
games:['红色警戒','穿越火线','劲舞团','超级玛丽']
}
},
}

  • 父组件要使用 template标签包裹插入的j结构

    < strong style=”color:blue”>scope</ strong> = “scopeDataName” 接收传递回来的数据

    scopeDataName 名字无任何要求

    当 scopeDataName 是一个对象,使用 scope=”{对象(names)}”进行 解构赋值 直接获取对象值

<template>		
<Category>
<template scope="scopeData">
<!-- 生成的是ul列表 -->
<ul>
<li v-for="g in scopeData.games" :key="g">{{g}}</li>
</ul>
</template>
</Category>

<chen>
<template slot-scope="{games}">
<!-- 生成的是h4标题 -->
<h4 v-for="g in games" :key="g">{{g}}</h4>
</template>
</chen>
</template>



Vuex

image-20230409163041846


  • 安装 – 注意vue2版本要求 – (插件)
#Vue2 --> vuex 3.+
npm i vuex@3
#Vue3 --> vuex 4.+
npm i vuex

搭建环境

1.创建配置项

(文档推荐)assets下创建 store 文件夹,创建index.js

该文件用于创建Vuex中最核心的store

    import Vue from 'vue'

//引入Vuex
import Vuex from 'vuex'
Vue.use(Vuex)

-------------------------------------------------------
//准备actions -- 用于响应组件中的动作
const actions={ }
//准备mutations -- 用于操纵数据(state)
const mutations={ }
//准备state -- 用于存储数据
const state={ }
-------------------------------------------------------

//创建并导出store
export default new Vuex.Store({
actions,
mutations,
state
})

//导出store
// export default store




2.传入配置项

  • main.js 中创建vm时传入 store 配置项
//引入store
import store from './store'

new Vue({
render: h => h(App),
store,
}).$mount('#app')





3.简单实操

1、存储变量

  • (index.js)在store的 state
//准备state -- 用于存储数据   
const state={
sum:0,
}

2、获取存储的变量

  • 组件插值语法中直接使用 this.$store.state.dataname  获取store中的数据 (可省略this) $store.state.dataname
{{ this.$store.state.sum }}
{{ $store.state.sum }}

3.调用修改变量

  • this.$store.

  • 调用 actions 中方法使用 dispatch

    this.$store.dispatch(‘方法name’,数据)

  • 调用 mutations 中方法使用commit  – 可跳过dispatch直接进行数据操纵

    this.$store.commit(‘方法name’,数据)

methods:{
increment(){
this.$store.dispatch('jia',this.n)
},
decrement(){
this.$store.commit('JIAN',this.n)
},
},

4.设置响应动作和操纵数据

  • store - index.js
  • actions – 用于响应组件中的动作
  • 要想被调用使用 .dispatch

  • 在actions中引用自身方法:context.dispatch(‘方法’,值)

  • 传话 :其中的方法不对数据进行操纵修改,它会 调用 mutations  中的方法进行对数据操纵修改

  • 其中的方法(context,value):

  • context 为上下文 ,使用 .commit 方法进行调用 mutations 中的方法 – context.commit(‘mutations中的方法名’,读取实例获取的值)

//准备actions
const actions={
jia(context,value){
context.commit('JIA',value)
//引用自身actions中方法
context.dispatch('jian',value)
},
jian(context,value){
context.commit('JIAN',value)
},
}


  • mutations 具体实现– 用于操纵 state 中的数据

操纵数据具体实现步骤,要被想调用则使用 :.commit

**方法(state,value)**:获取state的数据:.state.data_name

//准备mutations
const mutations={
JIA(state,value){
console.log('mutations');
state.sum+=value
},
JIAN(state,value){
console.log('mutations');
state.sum-=value
},
}



Vuex 模块化

  • 开启命名空间:namespace:ture

  • 目的:让代码更好维护,让多种数据分类更加明确。


  • 修改store.js
const countAbout = {
namespaced:true,//开启命名空间
state:{x:1},
mutations: { ... },
actions: { ... },
getters: {
bigSum(state){
return state.sum * 10
}
}
}

const personAbout = {
namespaced:true,//开启命名空间
state:{ ... },
mutations: { ... },
actions: { ... }
}


  • 导出
const store = new Vuex.Store({
modules: {
countAbout:countAbout,
personAbout
}
})

  • 开启命名空间后,组件中读取state数据:
//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取:
...mapState('countAbout',['sum','school','subject']),

  • 开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters读取:
...mapGetters('countAbout',['bigSum'])

  • 开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

  • 开启命名空间后,组件中调用commit
//方式一:自己直接commit  /
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),



全局计算属性

1.getters 配置项

  • 当state中的数据需要加工后再使用时,使用 getters 加工:
//追加 getters 配置项
const getters={
bigSum(state){
return state.sum*10
}
}


//追加创建并导出store
export default new Vuex.Store({
...
getters
})
  • 调用store里面getters数据 – $store.getters.数据
//获取getters返回的值
{{this.$store.getters.bigSum }}
{{$store.getters.bigSum }}

2.mapGetters – 获取getters数据

<h2>当前值:{{ bigSum }}</h2>

import {mapGetters, mapState} from 'vuex'

computed:{
//借助mapState生成计算属性,从state中读取数据。(对象写法)
...mapState({bigSum:'bigSum'})

//借助mapGetters生成计算属性,从state中读取数据。(数组写法。要求键名和值名相同=>简写)
...mapGetters(['bigSum'])
}

3.mapState – 获取state数据

<h2>{{ sum }}{{ school }}{{ c }}</h2>


import {mapGetters, mapState} from 'vuex'

computed:{
//借助mapState生成计算属性,从state中读取数据。(对象写法)
...mapState({sum:'sum',school:'school',c:'age'})

//借助mapState生成计算属性,从state中读取数据。(数组写法。要求键名和值名相同=>简写)
...mapState(['sum','school','age']),
}



map生成方法

1.mapMutations – commit

  • 使用 this.$store.commit 写法时,方法触发不需要传值在触发位置传值
<button @click="increment">+</button>
methods:{
//自己写方法进行调用
increment(){
this.$store.commit('JIA',this.n)
},
decrement(){
this.$store.commit('JIAN',this.n)
},

  • …mapMutations 写法需要写入传值 mutayions方法使用
<button @click="increment(n)">+</button>
<button @click="decrement(n)">-</button>

(数组写法)
<button @click="JIA(n)">+</button>
//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations
...mapMutations({increment:'JIA',decrement:'jian'}),

//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法)
...mapMutations(['JIA','JIA']),



2.mapActions– dispatch

  • 使用 this.$store.dispatch写法时,方法触发不需要传值在触发位置传值
<!-- this.$store.commit 写法不需要传值 -->
<button @click="increment">+</button>
methods:{

//自己写方法进行调用
increment0dd(){
this.$store.dispatch('jiaOdd',this.n)
},
incrementWait(){
this.$store.dispatch('jiaWait',this.n)
},

  • …mapActions 写法需要写入**传值 **给 actions 的方法使用
<!-- mapActions 写法需要传值 -->
<button @click="increment0dd(n)">+</button>
<button @click="incrementWait(n)">-</button>

(数组写法)
<button @click="jiaOdd(n)">+</button>
methods:{

//借助mapActions生成对应的方法,方法中会调用commit去联系mutations
...mapActions({increment0dd:'jiaOdd',incrementWait:'jiaWait'}),

//借助mapActions生成对应的方法,方法中会调用commit去联系mutations(数组写法)
...mapActions(['jiaOdd','jiaWait']),
}




路由

1.安装–引入–应用

#vue2 --安装路由插件 -  vue-router@3
npm i vue-router@3

  • main.js
//引入VueRouter插件
import VueRouter from 'vue-router'
//应用插件
Vue.use(VueRouter)



2.配置

①main.js

new Vue({
render: h => h(App),
router:router,
}).$mount('#app')

②创建文件夹(router)– 创建 (name) index.js

  • 该文件专门用于创建整个应用的路由器

import VueRouter from "vue-router";

//引入组件
import About from '../components/About'
import Home from '../components/Home'

//创建一个路由器并导出
// const router = new VueRouter
export default new VueRouter({
routes:[
{
path:'/about',
component:About
},
{
path:'/home',
component:Home
}
]
})


​ ③跳转设置

  • Vue中借助 router-link (等价于html中的 a 标签)标签实现路由跳转

    标签内使用 to=”path” 来指定跳转组件


  • 激活属性: active-class=”active” – 被选中激活高亮

<router-link class="list-group-item"  active-class="active" to="/about">AboutV</router-link>
<router-link class="list-group-item" active-class="active" to="/home">HomeV</router-link>

  • 在指定位置展示路由跳转显示的组件
<router-view></router-view>