都2022年了不会还有人不会vue吧
快跟着js同学 学学vue吧
本文章是Vue超详宝典的续集
小案例–>div 透明度渐变
<div id="root">
{{name}}
<div :style={opacity}>
hello
div>
div>
new Vue({
el:'#root',
data:{
name:'小明',
opacity:1
},
// vue完成模板的解析并把初始值的真实dom元素放入页面后,挂在完毕调用mounted
mounted(){
setInterval(()=>{
this.opacity-=0.01
if(this.opacity<=0) this.opacity=1
},30)
}
})
增加需求,现在想让渐渐消失的消失的效果能够随时停止
<button @click="stop">点我停止button>
<button @click="opacity=1">点我恢复button>
methods:{
stop(){
this.$destroy()
}
},
mounted(){
this.timer=setInterval(()=>{
this.opacity-=0.01
if(this.opacity<=0) this.opacity=1
},30)
},
beforeDestroy(){
console.log('vm即将跑路')
clearInterval(this.timer)
}


beforeCreate(){
console.log("beforeCreate")
},
created(){
console.log("created")
},
beforeMount(){
console.log("beforeMount")
},
mounted(){
console.log("mounted")
}

常用的生命周期钩子
销毁Vue实例
传统方式带来的问题代码复用率低,且不好维护

组件方式

我们首先简要的说一下Vue中使用组件的三大步骤
如何定义一个组件
Vue.extend(options) 创建,其中options和new Vue(options)时传入的那个options几乎一样,但是区别如下:template 可以配置组件结构如何注册组件
编写组件标签
<组件名></组将名>
案例演示
<div id="root">
<!-- 3编写组件标签 -->
<school></school>
<hello></hello>
<hr>
<student></student>
</div>
Vue.config.productionTip=false
// 1创建school 组件
const school=Vue.extend({
// el:'#root' 一定不要写el配置项,
template:`
<div>
<h3>学校{{schoolName}}</h3>
<h3>地址{{address}}</h3>
</div>
`,
data(){
return{
schoolName:'Vue学院',
address:'B站'
}
}
})
// 创建student 组件
const student=Vue.extend({
// el:'#root' 一定不要写el配置项理,
template:`
<div>
<h3>学生{{studentName}}</h3>
<h3>年龄{{age}}</h3>
</div>
`,
data(){
return{
studentName:'小明',
age:12
}
}
})
// 1创建全局组件
const hello=Vue.extend({
template:`
<div>
<h2>{{name}}</h2>
</div>
`,
data(){
return{
name:'全局组件'
}
}
})
// 注册全局组件
Vue.component('hello',hello)
new Vue({
el:'#root',
// 2注册组件 (局部注册)
components:{
school:school,
student:student
}
})

关于组件名的注意事项
kebab-case命名 my-school 第二种写法:CamelCase命名 MySchool (但是需要脚手架)组件标签的使用和注意事项
会导致后续组件不能渲染const school= Vue.extend(options) 可以简写为const school=options组件可以像这幅图一样进行嵌套
<div id="root">
<app>app>
div>
Vue.config.productionTip=false
// 创建student组件作为school的子组件
// 子组件一定要在调用之前也就是父组件之前初始化完毕
const student=Vue.extend({
name:'student',
template:`
学生{{studentName}}
年龄{{age}}
`,
data(){
return{
studentName:'小明',
age:12
}
}
})
// 1创建school组件student的父组件
const school=Vue.extend({
template:`
学校{{schoolName}}
地址{{address}}
`,
data(){
return{
schoolName:'Vue学院',
address:'B站'
}
},
// 注册子组件
components:{
student:student
}
})
// 创建hell组件
const hello=Vue.extend({
name:'hello',
template:`
{{name}}
`,
data(){
return{
name:'hello组件'
}
}
})
// 创建一个app组件作为管理组件
const app=Vue.extend({
name:'app',
template:`
`,
components:{
hello,
school
}
})
new Vue({
el:'#root',
// 2注册组件 (局部注册)
components:{
app
}
})

或者 Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)关于this的指向
VueComponent.prototype.__proto__===Vue.prototype
// 定义一个构造
function Demo(){
this.a=1
this.b=2
}
// 创建一个Demo的实例对象
const d=new Demo()
// 显示原型属性
console.log(Demo.prototype)
// 隐式原型属性
console.log(d.__proto__)
// 显示原型属性操作原型对象,追加一个x属性
Demo.prototype.x=99
console.log('@'+d.__proto__.x)

首先我们应该先知道单文件组件是个啥?
据我所了解这个单文件组件就是一个个后缀名为 .vue的文件原本的代码都放在html,css ,js 中但是现在可以放在.vue文件中我们将之前写的非单文件组件写成单文件组件。
学校模块
<template>
<div>
<h3>学校{{schoolName}}</h3>
<h3>地址{{address}}</h3>
</div>
</template>
<script>
export default{
name:'School',
data(){
return{
schoolName:'Vue学院',
address:'B站'
}
}
}
</script>
学生模块
<template>
<div id="abc">
<h3>学生{{studentName}}</h3>
<h3>年龄{{age}}</h3>
</div>
</template>
<script>
export default{
name:'Student',
data(){
return{
studentName:'小明',
age:12
}
}
}
</script>
<style>
#abc{
background-color: aqua;
}
</style>
App.vue
<template>
<div>
<School></School>
<Student></Student>
</div>
</template>
<script>
import School from './School.vue'
import Student from './Student.vue'
export default{
name:'App',
components:{
School,
Student
}
}
</script>
import App from './App.vue'
new Vue({
el:'root',
template:` `
components:{App},
})
但是现在运行并不能运行成功因为浏览器不认识我们写的东西,所以我们需要对我们写的.vue文件进行解析,这里我用到的是vue-cli脚手架,然后在脚手架里写的东西才可以被解析。
vue create 脚手架名称


现在将我们的组件放进脚手架中
npm run serve第一次运行说我的组件名不合乎规范?干

然后我直接修改配置将提示关掉
找到vue.config.js修改配置
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
//关闭eslint校验
lintOnSave: false
})

我们先把rander给注了用我们自己的方式写 template:, components:{App},

然后我们看一下报了一个错,大致的意思就是这个模板的编译不可用,如果说我们用的是vue.js怎么可能会出现这样的情况,所以我们Vue的导入模块发现了问题

从这里可以看出引入的是一个runtime版的js。
关于vue的两个不同的版本
<template>
<div>
<h1 v-text="msg" ref="title"></h1>
<button ref="btn" @click="showDOM()">点我输出上方DOM元素</button>
<School ref="sch"></School>
<Student></Student>
</div>
</template>
<script>
import School from './components/School.vue'
import Student from './components/Student.vue'
export default{
name:'App',
components:{
School,
Student
},
data:{
return{
mas:'同学你好'
}
},
methods:{
showDOM(){
// 真实DOM元素
console.log(this.$refs.title)
console.log(this.$refs.btn)
// School组件的实例对象
console.log(this.$refs.sch)
}
}
}
</script>
让组件接收外部传过来的数据
props:['name'] ,props:{ name :String } props:{
name:{
type:String,//类型
required:true.//必要性
default:'老王' // 默认值
}
}
备注props是只读的,Vue底层会监视你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要进行修改,那么请复制props的内容到data中一份,然后去修改data中的数据
<Student :age="19" name="张三">Student>
<h3>学生{{name}}</h3>
<h3>年龄{{myAge}}</h3>
<button @click="updataAge">点击修改年龄</button>
</div>
</template>
<script>
export default{
name:'Student',
data(){
return{
msg:'我是个学生',
// 找了个中间变量来负责承上启下
myAge:this.age
}
},
methods:{
updataAge(){
this.myAge++
}
},
// 接收的同时对参数进行限制
props:{
name:String,
age:Number
}
}

可以把多个组件共用的配置提取成一个混入对象
使用方式:
{ data() {....}, methods:{....} ...}Vue.mixin(xxx),局部使用:mixins:['xxx']现在假设在多个组件中都有一个相同的方法,我们想把这方法在外部抽取成一个

首先做一个混入
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.js'
//使用混入
mixins:[hunhe,hunhe2]
==============================================
<!-- 正常引入方法即可 -->
<button @click="showName">点我展示名字</button>

全局使用
// 全局使用mixin
import {hunhe} from './mixin'
Vue.mixin(hunhe)
插件 (Plugins) 是一种能为 Vue 添加全局功能的工具代码。一个插件可以是一个拥有 install() 方法的对象,也可以直接是一个安装函数本身。安装函数会接收到安装它的应用实例和传递给 app.use() 的额外选项作为参数:
const myPlugin = {
install(app, options) {
// 配置此应用
}
}
编写一个插件
// plugins/i18n.js
export default {
install: (app, options) => {
// 在这里编写插件代码
}
}
引入插件
import plugins from './plugins'
// 使用插件
Vue.use(plugins)
export default{
install(Vue){
// 全局过滤器
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
}
}
})
}
}

scoped有什么用
scoped 属性是 style 标签上的一个特殊属性(布尔值)。表示当前style 里的样式只属于当前模块。(作用域、私有化的思想),关于css的作用域问题,即使是模块化编程下,在对应的模块的js中import css进来,这个css仍然是全局的。导致在css中需要加上对应模块的html的id/class 使用css选择器 保证css的作用域不会变成全局 而被其它模块的css污染。
本文创作时间 一周
创作不易,你们的点赞和关注便是对我的最大的支持
连更中…