您的位置:首页 > 娱乐 > 八卦 > 互联网公司怎么起名字_设计公司官网需要发什么_链交换_口碑营销的好处

互联网公司怎么起名字_设计公司官网需要发什么_链交换_口碑营销的好处

2024/12/23 10:20:28 来源:https://blog.csdn.net/weixin_52232901/article/details/144458093  浏览:    关键词:互联网公司怎么起名字_设计公司官网需要发什么_链交换_口碑营销的好处
互联网公司怎么起名字_设计公司官网需要发什么_链交换_口碑营销的好处

Vue组件开发

非单文件组件

创建组件api Vue.extend({})

    const student = Vue.extend({template: `<div>{{studentName}} - {{age}}</div>`,data() {return {studentName: 'jjking',age: 12}}})new Vue({el: '#app',//局部注册components: {student: student}})

不能使用el,因为按理来说,组件不应该固定挂载谁,
并且data返回的是函数,不能写成对象

局部注册
在components里边

使用就是用<student></student>

全局注册
Vue.component('student',student);
前面是组件名,后面是组件

注意事项
组件名相关问题

组件名在开发者工具中,都是首字母大写的

一个单词组成: 大小写都可以
school
School

但是组件注册的时候写什么名字,你的标签就得写什么名字,避免出错

局部注册
多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)

其他,我们可以使用name来指定开发者工具里边的呈现的名字,所以只是为了好看,我么实际用还是用注册用的名字

关于组件的本质

  1. school组件的本质是VueComponent的构造函数,每次vm会帮助我们创建一个全新的VueComponent,但是这样的工作不用我们程序员干
  2. 关于this的指向
    (1) 在组件中,this指向组件实例对象
    (2) 在vm中,指向的是Vue实例对象

一个重要的内置关系

vc的prototype.__proto__ 指向的是Vue的原型对象

也就是vc可以访问到Vue原型对象上的属性和方法

换个意思讲,如果我们在Vue的原型对象上写了一个属性,我们在vc中可以拿得到

单文件组件

默认来看,生成一个vue组件是
const a = Vue.extend({options})

但是我们写单文件组件的时候

<template><div><h2>学校名称: {{name}}</h2><h2>学校地址: {{address}}</h2></div></template><script>
export default {name: 'School',data() {return {name: '光景',address: '白云区'}}
} 
</script><style></style>

export的时候,是直接抛出一个{}也就是一个对象,这里是简写的形式
const a = options
在app页面中,我们导入一个组件的时候,他会自动识别

组件通信

父子组件通信

父传子 -> props

子传父(初级用法)
例如父亲是app.vue
儿子是MyHeader.vue

父组件发一个函数给儿子
儿子在这个函数中把要传的数据传给父亲

准确的说,儿子把要传的数据传到这个函数的参数上

App.vue

<!-- 头部 -->
<MyHeader :addTodo="addTodo"></MyHeader>...
methods: {addTodo(todoObj) {// console.log('我是App组件,我收到了数据x',todoObj);this.todoList.unshift(todoObj)}
}

子组件是MyHeader

export default {name: 'MyHeader',props: ['addTodo'],methods: {add(e) {const todoObj = ...;this.addTodo(todoObj);}}
}

这个方法十分的诡异,但是确实是可以用的

组件自定义事件 子 -> 父

子传父,我们可以通过props 父亲给儿子传递一个函数,儿子在合适的时候触发这个事件,父亲就可以收到儿子传递过来的数据

这里的小项目就是为了说明组件自定义事件的,非常小的项目
父亲是app.vue
儿子分别是student.vue 和 school.vue

App.vue

<template><div class="app"><h1>{{msg}}</h1><School/><Student/></div></template><script>import Student from './components/Student'import School from './components/School'export default {name:'App',components:{School,Student},data() {return {msg:'你好啊!',}}}
</script><style scoped>.app{background-color: gray;padding: 5px;}
</style>

Student.vue

<template><div class="student"><h2>学生姓名:{{name}}</h2><h2>学生性别:{{sex}}</h2></div></template><script>export default {name:'Student',data() {return {name:'张三',sex:'男',}},}
</script><style scoped>.student{background-color: pink;padding: 5px;margin-top: 30px;}
</style>

School.vue

<template><div class="school"><h2>学校名称:{{name}}</h2><h2>学校地址:{{address}}</h2></div></template><script>export default {name:'School',props:['getSchoolName'],data() {return {name:'Tom学校',address:'北京',}}}
</script><style scoped>.school{background-color: skyblue;padding: 5px;}
</style>

页面显示

props传

props传当然是最为简陋的方式,并且传的是,函数
在App.vue上,我们绑定一个函数来接收来自儿子的数据

<School :getSchoolName="getStudentData"/>
...
methods: {getStudentData(data) {console.log('App组件收到了来自儿子的事件',data);}}

在子组件上,我们在合适的时机来触发这个事件,把数据传回App.vue
School.vue

        <!-- 通过props,子传父数据 --><button @click="sendSchoolName">点我发送给父亲app.vue数据</button>...​```bashprops:['getSchoolName'],data() {return {name:'Tom学校',address:'北京',}},methods: {sendSchoolName() {this.getSchoolName(this.name)}}

这样的写法,实在称不上好,但是能用

绑定自定义事件

通过v-on绑定自定义事件

我们给组件绑定绑定自定义事件
在App.vue上

<School v-on:jjking="getStudentData"/>
...
methods: {getStudentData(data) {console.log('App组件收到了来自儿子的事件',data);}
}

这个自定义事件是在vc上的,触发条件就是我们在子组件调用
this.$emit('自定义事件名换',data)

这个emit,意思就是发射,就像子组件发射数据到父组件一样,实际上,也是触发父组件的方法

在这里就是在子组件中,我们绑定了一个事件叫做jjking
我们子组件只要触发这个jjking事件就行

事件的回调方法叫做getStudentData

在子组件

<!-- 通过自定义事件$emit触发父亲给儿子绑定的事件 -->
<button @click="sendSchoolName">点我发送给父亲app.vue数据</button>...
methods: {sendSchoolName() {this.$emit('jjking',this.name)}
}

通过ref绑定自定义事件

<!-- 通过ref绑定自定义事件 -->
<School ref="student"/>methods: {getStudentData(data) {console.log('App组件收到了来自儿子的事件',data);}
},
mounted() {this.$refs.student.$on('jjking',this.getStudentData)
}

this.$refs.student 其实就是组件vc我们在这上面绑定jjking自定义事件,回调函数时this.getStudentData

相比看下来,其实第一种绑定的方式更为简单,但为什么我们要用ref来绑定呢,原因是这样子会更加的灵活

例如我们如果想要触发3秒之后,再启用getStudentData的回调函数,此时第一种方式就直接写死了,模版解析到<School/>组件的时候,啪一下,就执行了回调函数了,然而我们通过ref来绑定,我们可以直接直接写

mounted() {setTimeout(() => {this.$refs.student.$on('jjking',this.getStudentData)},3000)
}

如果我们想要触发一次,我们就可以换成$once

mounted() {this.$refs.student.$once('jjking', this.getStudentData)
}

注意:

这里的this.getStudentData不能写成普通的函数类似于下面这样

    this.$refs.student.$on('jjking', function getStudentData(data) {console.log('App组件收到了来自儿子的事件', data);})

眼下看的时候没有问题,但是如果涉及到this的操作的话,就会出问题,这里的this不再是App这个组件了,而是他的儿子组件School.vue,原因是在Vue中,谁触发了事件,this就指向谁,此时this就是School的vc

这里的解决办法就是我们可以写箭头函数,因为箭头函数没有this,他的this会去外边一层去找this的指向,所以这里的this会找到mounted的this

而vue中,已经把mounted的this指向指向了App,所以箭头函数是不会出bug的

触发事件时传递多个参数

// 方式一school.vue
<script>methods: {sendStudentlName(){this.$emit('atguigu',this.name,666,888,900)},},
</script>app.vue
<script>methods: {getStudentName(name,x,y,z){console.log('App收到了学生名:',name,x,y,z)},},}
</script>开发中的方式
// 方式一 :把数据包装成一个对象传递过去
school.vue
<script>methods: {sendStudentlName(){this.$emit('atguigu',{})},},
</script>// 方式二:es6 写法  正常传递,接收
school.vue
<script>methods: {sendStudentlName(){this.$emit('atguigu',this.name,666,888,900)},},
</script>app.vue
<script>methods: {// name 正常结构,其他的参数不管传递多少,整理到params数组上getStudentName(name,...params){console.log('App收到了学生名:',name,params)},},}
</script>

要么参数一个一个写,要么用...params这是es6的语法

解绑自定义事件

<!-- 解绑自定义事件 -->
<button @click="unbind">点我解绑自定义事件</button>unbind() {this.$off('jjking')// this.$off(['jjking','demo']) //解绑多个自定义事件// this.$off() //解绑所有的自定义事件
}

组件绑定事件默认不使用内置事件

// 这么写会被默认当做自定义事件
<Student ref="student" @click="show"/> //加上native 原生的,本来的,才会使用到内置事件
<Student ref="student" @click.native="show"/> 

必须写native才行

总结

全局事件总线(任意组件间通信)

安装全局事件总线,在main.js中

import Vue from 'vue'
import App from './App.vue'Vue.config.productionTip = falsenew Vue({render: h => h(App),beforeCreate() {Vue.prototype.$bus = this;}
}).$mount('#app')

Student.vue

<template><div class="student"></div></template><script>export default {name:'Student',data() {return {name:'张三',sex:'男',}},mounted() {this.$bus.$on('getData',(data) => {console.log(data);      })}}
</script>

绑定事件

在兄弟组件School.vue发送数据到Student.vue

<template><div class="school"><button @click="sendData">点我发送数据</button></div></template><script>export default {name:'School',data() {return {name:'Tom学校',address:'北京',}},methods: {sendData() {this.$bus.$emit('getData',this.name);}}}
</script>

和子传父里边的写法是一样不过,这里的突然加了一个中间商,不再是App.vue
而是一个新的人$bus

注意
不用这个这个组件的时候,需要自己去解绑当前组件所用到的事件

beforeDestroy() {this.$bus.$off('getData')
}

消息订阅和发布(任意组件)

消息订阅库有很多,这里使用pubsub

安装pubsub

npm i pubsub-js

引入

import pubsub from 'pubsub-js'

组价需要收消息,就订阅消息,回调留在自身

methods: {demo(msgName,data) {...}
},
mounted() {this.pid = pubsub.subscribe('xxx',this.demo);
},
beforeDestroy() {pubsub.unsubscribe(this.pid);
}

需要注意的是,回调的第一个参数是消息名字,第二个才是data,
且和全局事件总线一样,也需要解绑消息

组件发送消息

    pubsub.publish('xxx',数据)

vuex

共享数据,用于多个组件之间的通信

原理

在这里插入图片描述
Actions
Mutations
State
三个都是对象类型

组件想要加2,
然后dispatch(‘jia’,2) 发给Actions,
Actions再commit给Mutations
Mutations进行操作State
最后重新渲染给Vue组件

这三个由store来管理,并且dispatch commit这些api都是store提供的

Actions类似服务员,Mutations类似餐厅后厨,State类似菜
组件类似客人

我们可以跳过Actions(服务员)来直接叫他点菜,但是有时候,服务员需要介入点菜的过程,例如ajax请求,可以在这个时候发

搭建vuex环境

vue2 ,要用vuex3版本
vue3,要用vuex4版本

npm i vuex 默认安装的是vuex4

npm i vuex@3

如上我们的vue2需要vuex3

在src中创建一个store文件夹,添加index.js

在这里插入图片描述

index.js

import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex);const actions = {};
const mutations = {};
const state= {};export default new Vuex.Store({actions,mutations,state
})

main.js

import Vue from 'vue'
import App from './App.vue'
import store from './store'Vue.config.productionTip = falsenew Vue({render: h => h(App),store,beforeCreate() {Vue.prototype.$bus = this;}
}).$mount('#app')

需要注意一个小问题,Vue.use(Vuex)必须写到index.js里边,如果我们在main.js
中使用的话,会报错
在这里插入图片描述
不管你Vuex是否是写到import之前,js解析,会先把所有import的代码先执行,不会先执行你的代码,所以我们得把Vue.use(Vuex)写到index.js里边

基本使用

<template><div class="category"><h1>当前求和为{{$store.state.sum}}</h1><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select><button @click="add">+</button><button @click="minus">-</button><button @click="oddAdd">当前求和为奇数再加</button><button @click="delayAdd">等一等再加</button></div>
</template><script>
export default {name: 'Category',data() {return {n: 1}},methods: {add() {this.$store.dispatch('jia',this.n);},minus() {this.$store.commit('JIAN',this.n);},oddAdd() {if(this.$store.state.sum % 2 == 1) {this.$store.dispatch('jia',this.n);}},delayAdd() {setTimeout(() => {this.$store.dispatch('jia',this.n);}, 5000);},},
}
</script>

拿数据就在$store.state里边拿取

调用的是dispatch,走的就是actions,
如果我们直接调用commit就是跳过actions,直接找到mutations

index.js

import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex);const actions = {jia(miniStore,value) {console.log('actions里边的jia方法',miniStore,value);miniStore.commit('JIA',value);},jian(miniStore,value) {console.log('actions里边的jian方法',miniStore,value);miniStore.commit('JIAN',value);}
};
const mutations = {JIA(state,value) {console.log('mutations里边的JIA方法',state,value);state.sum += value;},JIAN(state,value) {console.log('mutations里边的JIAN方法',state,value);state.sum -= value;},
};
const state= {sum: 0
};export default new Vuex.Store({actions,mutations,state
})

一般来说,mutations里边的方法是大写,actions里边的方法是小写

我们整体的看,actions的存在即合理,如果我们有一些业务逻辑,我们就可以写到actions中,这里的actions有点类似于后端的service层,mutations有点类似mapper层,我们的业务逻辑可以写到service层

getters

getters有点类似于computed
不过数据源是state中的数据

配置
在这里插入图片描述
拿取

{{$store.getters.bigSum}}

mapGetters,mapState

vue建议{{}}插值语法中,里边的方法尽量简写
在这里插入图片描述
类似这种写法不合理,我们一般写到计算属性里边
但是如果全部都写计算属性就会有大量重复的代码,这个时候我们就需要mapState帮我们生成这样的代码

    computed: {sum() {return this.$store.state.sum();},//对象写法...mapState({sum:'sum',school:'school'}),//数组写法...mapState(['sum','school'])}

需要注意的是,mapState()返回的是一个对象,如果我们直接在computed: {},里边给人添加一个对象是不合理的,所以就会用到es6的语法...他可以将里边的内容加到computed这个对象中去

我们也可以看到,生成的代码就是sum()这样类似的计算属性,并且需要注意的是,如果说,你计算属性的名字和state中的名字是一样的,是可以用数组的写法的,如果不是的话,还是老老实实用对象写法的

mapGetters的使用方法和mapState是一模一样的

mapActions,mapMutations

    methods: {add() {this.$store.dispatch('jia',this.n);},oddAdd() {if(this.$store.state.sum % 2 == 1) {this.$store.dispatch('jia',this.n);}},delayAdd() {setTimeout(() => {this.$store.dispatch('jia',this.n);}, 5000);},...mapActions({oddAdd:'jia',delayAdd:'jia'}),minus() {this.$store.commit('JIAN',this.n);},...mapMutations({minus:'JIAN'})},

需要注意的是,如果我们需要传参数的话,需要在模版代码中传
在这里插入图片描述
如果我们不传的话,会是event事件

模块化编程

不同业务写到不同js中

export default {namespaced: true,actions: {jia(miniStore,value) {console.log('actions里边的jia方法',miniStore,value);miniStore.commit('JIA',value);},jian(miniStore,value) {console.log('actions里边的jian方法',miniStore,value);miniStore.commit('JIAN',value);}},mutations: {JIA(state,value) {console.log('mutations里边的JIA方法',state,value);state.sum += value;},JIAN(state,value) {console.log('mutations里边的JIAN方法',state,value);state.sum -= value;},},state: {sum: 0,school: '尚硅谷',subject: '前端'},getters: {bigSum(state) {return state.sum * 10;}}
}

必须写命名空间,这样我们使用mapActions 等等这些map操作的时候,才可以写不同的模块名字

import Vue from 'vue';
import Vuex from 'vuex';
import countoption from './countoption';Vue.use(Vuex);export default new Vuex.Store({modules: {countAbout: countoption}
})

修改非模块化代码

    methods: {...mapActions('countAbout',{add:'jia',oddAdd:'jia'}),...mapMutations('countAbout',{minus:'JIAN'})},computed: {//对象写法...mapState('countAbout',{sum:'sum',school:'school'}),//数组写法// ...mapState(['sum','school'])...mapGetters('countAbout',['bigSum'])}

对于mapGetters这些,都得在前面写一个参数也就是我们在module中配置的模块名countAbout

原始的拿取state中的数据
在这里插入图片描述

getters
在这里插入图片描述
要在前面加个模块名/

commit操作

在这里插入图片描述
要在前面加个模块名/

dispatch纯手写和commit一致

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com