当前位置: 首页 > news >正文

网站的html/长春seo关键词排名

网站的html,长春seo关键词排名,中山网站建设文化价位,舟山市普陀区建设局网站组件 组件是实现应用中局部功能的代码(HTML,CSS,JS)和资源(图片,声音,视频)的集合,凡是采用组件方式开发的应用都可以称为组件化应用 模块是指将一个大的js文件按照模块化拆分规则进行拆分成的每个js文件, 凡是采用模块方式开发的应用都可以称为模块化应用(组件包括模块) 传…

组件

组件是实现应用中局部功能的代码(HTML,CSS,JS)和资源(图片,声音,视频)的集合,凡是采用组件方式开发的应用都可以称为组件化应用

模块是指将一个大的js文件按照模块化拆分规则进行拆分成的每个js文件, 凡是采用模块方式开发的应用都可以称为模块化应用(组件包括模块)

传统方式开发的一个网页通常包括三部分: 结构(HTML)、样式(CSS)、交互(JavaScript)

  • 关系纵横交织复杂,牵一发动全身不利于维护
  • 代码复用率不高., 页面中复用的代码需要通过复制的方式在其他页面中使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

组件化方式开发的应用

  • 每一个组件都有独立的js,css以及HTML片段,这些独立的代码只供当前组件使用,不存在纵横交错问题便于维护
  • 代码复用性增强, 页面中复用的代码通过引入组件的方式在其他页面中使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

组件的创建、注册和使用

创建组件调用Vue.extend({该配置项和new Vue的配置项几乎相同只是略有差别})

  • 配置项中不能使用el配置项配置模板语句而是使用template配置项(组件具有通用性,不特定为某个容器服务而是为所有容器服务)
  • 配置项中的data不能使用对象的形式(数据是共享的只有一份),必须使用函数形式返回一个对象(组件的数据是独立的不能共享)
  • 配置项中的name是设置Vue开发者工具中显示的组件的名字不是设置组件的名字(默认都是驼峰式显示)
  • 创建组件的简写形式:省略Vue.extend()直接写{配置项},底层在注册组件的时候还是会调用Vue.extend()静态方法

注册组件进行管理

  • 局部注册(只能在父组件绑定的容器中或模板语句中使用):在创建Vue实例时的配置项当中使用components配置项, components:{组件的名字:组件对象}
  • 全局注册(可以在所有父组件绑定的容器中或模板语句中使用):Vue.component('组件的名字(标签名)', 组件对象)

在容器中中以HTML标签的方式使用组件

  • 使用组件时可以使用自闭合标签,但是如果不在脚手架环境中使用这种方式除了第一个元素渲染后续元素都不会渲染

组件的名字规范(不可以是HTML内置的标签名)

  • 第一种:全部小写
  • 第二种:首字母大写,后面都是小写
  • 第三种:kebab-case串式命名法(如user-login)
  • 第四种常用:CamelCase驼峰式命名法(UserLogin), 这种方式只允许在脚手架环境中使用
<script>// 创建组件实例对象(结构HTML 交互JS 样式CSS)const myComponent = Vue.extend({template : `<ul><li v-for="(user,index) of users" :key="user.id">{{index}},{{user.name}}</li></ul>`,// 每次调用data方法都会返回一个对象,这个对象中的数据是独立的data(){return {users : [{id:'001',name:'jack'},{id:'002',name:'lucy'},{id:'003',name:'james'}]}}})// 创建组件时省略Vue.extend()const myComponent = {template : `<ul><li v-for="(user,index) of users" :key="user.id">{{index}},{{user.name}}</li></ul>`,data(){return {users : [{id:'001',name:'jack'},{id:'002',name:'lucy'},{id:'003',name:'james'}]}}}// 在Vue实例中注册组件进行管理const vm = new Vue({el : '#app',data : {msg : '第一个组件'},// 局部注册组件的只能在父组件绑定的容器中使用components : {// userlist是组件的名字,myComponent组件实例对象userlist : myComponent,}})
</script>
<!--在页面中以html标签的方式使用组件-->
<div id="app"><h1>{{msg}}</h1><userlist></userlist><userlist></userlist><userlist/>
</div>

全局注册的组件可以在所有父组件绑定的容器中或模板语句中使用

<body><!--容器1--><div id="app"><h1>{{msg}}</h1><userlogin></userlogin></div><!--容器2--><div id="app2"><userlogin></userlogin></div><script>// 创建组件const userLoginComponent = {// template只能有一个根元素template : `<div><h3>用户登录</h3><form @submit.prevent="login">账号:<input type="text" v-model="username"> <br><br>密码:<input type="password" v-model="password"> <br><br><button>登录</button></form></div>`,data(){return {username : '',password : ''}},methods: {login(){// this是vcalert(this.username + "," + this.password)}},}// 全局注册组件,自动调用Vue.extend()方法Vue.component('userlogin', userLoginComponent)// Vue实例const vm2 = new Vue({el : '#app2'})// Vue实例const vm = new Vue({el : '#app',data : {msg : '第一个组件'},})</script>
</body>

组件嵌套

组件的划分粒度很重要,粒度太粗会降低组件的复用性, 为了让复用性更强Vue 的组件也支持父子组件嵌套使用

  • 子组件由父组件来管理,父组件由父组件的父组件管理, 在Vue中根组件就是Vue实例vm
  • 局部注册的子组件只能在父组件绑定的容器或者template配置项配置的模板语句中使用,一般是在哪注册在哪使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

<body><div id="root"></div><script>// 创建Y1组件const y1 = {template : `<div><h3>Y1组件</h3></div>`}// 创建X1组件const x1 = {template : `<div><h3>X1组件</h3></div>`}// 创建Y组件const y = {template : `<div><h2>Y组件</h2><y1></y1></div>`,// 注册y1组件components : {y1}}// 创建X组件const x = {template : `<div><h2>X组件</h2><x1></x1></div>`,// 注册x1组件components : {x1}}// 创建app组件const app = {template : `<div><h1>App组件</h1><x></x><y></y></div>`,// 注册X组件,对象的属性名和属性值相同时可以省略属性值components : {x,y}}// vmconst vm = new Vue({el : '#root',template : `<app></app>`,// 注册app组件components : {app}})</script>
</body>

VueComponent & Vue

new Vue({})配置项中的this是Vue实例vm(构造函数中的this指向新创建的对象), Vue.extend({})配置项中的this是VueComponent实例vc

  • vm 和vc拥有大量相同的属性和函数,但二者并不相同,只能说vm上有的vc上不一定有,vc上有的vm上一定有
  • vm上有el属性而vc上没有,vc的data 必须是一个函数

Vue.extend()源码: 因为Sub是个局部变量, 所以每一次调用Vue.extend方法返回的都是一个全新的VueComponent构造函数(构造函数也是类型即对应一个对象)

  • 有了构造函数当Vue在解析组件标签时就会创建一个VueComponent实例,每个组件标签都会对应一个VueComponent实例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

<body><div id="app"><h1>{{msg}}</h1><user></user></div><script>// 创建组件const user = Vue.extend({template : `<div><h1>user组件</h1></div>`,mounted(){// this是VueComponent实例,user是一个全新的VueComponent构造函数(函数类型的对象)console.log('vc', this === user)//false}})// Vue实例const vm = new Vue({el : '#app',data : {msg : 'vm与vc'},components : {user},mounted() {// this是Vue实例console.log('vm', this)},})</script>
</body>

回顾原型对象

XX的原型对象是一个共享的对象且只有一个,获取原型对象有两种方式

  • prototype :显示的原型属性(建议程序员使用的),可以通过函数.prototype的方式获取原型对象
  • __proto__:隐式的原型属性(不建议程序员使用的),可以通过实例.__proto__的方式获取原型对象

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

// 构造函数(函数本身也是一种类型,代表User类型有一个prototype属性)
function User(){}
// 通过函数获取User的原型对象
let x = User.prototype
// 通过User构造函数可以创建实例
let a = new User()
// 通过实例获取到Vip的原型对象
let y = a.__proto__
// 获取的是同一个原型对象
console.log(x === y) // true
// 以下不是给User构造函数扩展属性而给“User的原型对象”扩展属性
User.prototype.counter = 1000// 通过a实例可以访问到这个扩展的counter属性
// 访问原理:首先去a实例上找counter属性,如果a实例上没有counter属性的话,会沿着__proto__这个原型对象去找counter属性
console.log(a.counter)
//console.log(a.__proto__.counter)

vc可以访问Vue原型对象上的属性

VueComponent.prototype.__proto__ = Vue.prototype: 这行代码实现了Vue,vm,VueComponent,vc都共享了同一个Vue的原型对象

  • Vue原型对象上有很多属性和方法如$mount(),对于组件VueComponent来说就不需要再额外提供了,直接使用vc调用$mount()即可,代码得到了复用外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
<body><div id="app"><h1>{{msg}}</h1><user></user></div><script>// 给“Vue的原型对象”扩展一个counter属性Vue.prototype.counter = 1000// 创建组件const user = Vue.extend({template : `<div><h1>user组件</h1></div>`,mounted(){// 通过this也就是vc可以访问到Vue原型对象上的属性console.log('vc.counter', this.counter)// msg是vm实例上的属性不是原型对象上的属性所以访问不了//console.log('vc.msg', this.msg)}})// user等价于VueComponent构造函数console.log('user.prototype.__proto__ === Vue.prototype' , user.prototype.__proto__ === Vue.prototype)// true// Vue实例const vm = new Vue({el : '#app',data : {msg : 'vm与vc'},components : {user},mounted() {// this是Vue实例console.log('vm', this)},})// vm实例可以访问console.log('vm.counter', vm.counter)console.log('vm.counter', vm.__proto__.counter)</script>
</body>

单文件组件

单文件组件就是一个文件对应一个组件, 单文件组件的名字通常是xxx.vue,这个文件是Vue框架规定的只有它能够认识,浏览器无法直接打开运行

  • Vue框架将xxx.vue文件进行编译为浏览器能识别的 html js css的代码
  • 单文件组件的文件名命名规范和组件名的命名规范相同
  • xxx.vue文件的内容包括三块:结构HTML代码(template标签),交互JS代码(script标签),样式CSS代码(style)
  • VSCode工具可以安装vetur插件: 在编写xxx.vue文件的时候代码有高亮提示,并且也可以通过输入 <v 生成代码
  • Auto Rename Tag插件方便同时修改标签名

export和import

export用于暴露数据,常见的暴露方式有分别暴露,统一暴漏,默认暴露

// m1.js文件中使用分别暴露属性和方法
export let school = '尚硅谷';export function teach() {console.log("我们可以教给你开发技能");
}// m2.js文件中使用对象的方式统一暴露
let school = '尚硅谷';
function findJob(){console.log("我们可以帮助你找工作!!");
}
export {school, findJob};// m3.js文件中使用默认暴露(可以暴露任意类型,一般是个对象)
export default {school: 'ATGUIGU',change: function(){console.log("我们可以改变你!!");}
}	

import用于导入js文件中暴露的数据

<body><script type="module">// 通用的导入方式,m1,m2,m3分别存储了暴露的数据import * as m1 from "./src/js/m1.js";import * as m2 from "./src/js/m2.js";import * as m3 from "./src/js/m3.js";// 解构赋值形式通过对象的形式使用暴露的数据,属性方法重名时使用as关键字// import {a, b} from ‘模块标识符'import {school, teach} from "./src/js/m1.js";import {school as guigu, findJob} from "./src/js/m2.js";// default是个关键字不能直接使用,需要使用别名机制import {default as m3} from "./src/js/m3.js";// 导入的简便形式但是只能针对默认暴露,m3是别名存储了暴露的数据和方法// import 任意名称 from ‘模块标识符’import m3 from "./src/js/m3.js";// 访问暴露的属性和方法需要加一层default结构console.log(m3.default.school);</script>
</body>

将所有模块的引入单独写到一个js文件中,在index,html中使用script标签直接引入这个js文件即可

//模块引入的入口文件
import * as m1 from "./m1.js";
import * as m2 from "./m2.js";
import * as m3 from "./m3.js";
 <body><!--引入js文件,类型是module--><script src="./src/js/app.js" type="module"></script>
</body>

“组件嵌套”之单文件组件的形式

创建vm的js代码就不再写成一个组件了, 将这段js代码写到一个main.js入口文件中即可

import App from './App.vue'
new Vue({el : '#root',// 使用组件template : `<App></App>`,// 注册App组件components : {App}
})

不管是单文件组件还是非单文件组件,永远都包括三步:创建组件、注册组件、使用组件

<!--App.vue-->
<template><div><h1>App组件</h1><!-- 使用组件 --><X></X><Y></Y></div>
</template>
<script>import X from './X.vue'import Y from './Y.vue'// 把组件暴露出去export default {// 注册组件components : {X, Y}}
</script><!--X.vue-->
<template><div><h2>X组件</h2><!-- 使用组件 --><X1></X1></div>
</template>
<script>import X1 from './X1.vue'export default {// 注册组件components : {X1}}
</script>
<!--X1.vue-->
<template><div><h3>X1组件</h3></div>
</template>
<script>export default {// 暴露X1组件}
</script><!--Y.vue-->
<template><div><h2>Y组件</h2><!-- 使用组件 --><Y1></Y1></div>
</template>
<script>// 导入组件Y1(Y1可以使用其它名字)import Y1 from './Y1.vue'export default {// 注册组件components : {Y1}}
</script><!--Y1.vue-->
<template><div><h3>Y1组件</h3></div>
</template><script>export default {// 暴露Y1组件}
</script>

剩下的HTML代码一般写到index.html文件中

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>单文件组件</title>
</head>
<body><div id="root"></div><script src="../js/vue.js"></script><script src="./main.js"></script>
</body>
</html>

组件化开发的流程: 浏览器不认识.vue文件并且也不认识 ES6 的模块化语法, 需要安装Vue脚手架

  • 第一步:浏览器打开index.html页面,加载容器
  • 第二步:加载vue.js文件,有了Vue
  • 第三步:加载main.js文件导入组件, 完成了所有组件以及子组件的创建和注册
  • 第四步:创建Vue实例vm,编译App.vue(以此类推)中的模板语句然后渲染页面

使用脚手架组件开发

安装Node.js

第一步: Node.js 的下载地址

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第二步: 一路点击下一步,添加命令到PATH环境变量,剩下按照默认选项安装即可

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第三步: 打开dos命令窗口,输入 npm -version查看npm的版本号

第四步: 配置npm镜像npm config set registry https://registry.npm.taobao.org, 执行npm config get registry返回成功即表示设置成功

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

调用管理员界面,查看nodejs安装版本:输入node -v命令 ,以及查看npm版本:输入npm -v命令;

安装Vue CLI(脚手架)

Vue 的脚手架(Command Line Interface)是Vue官方提供的标准化开发平台,为我们Vue的开发提供了一条龙服务

  • Vue CLI 4.x需要Node.js v8.9及以上版本(推荐v10以上)

第一步:执行npm install -g @vue/cli命令安装脚手架(全局方式:表示只需要做一次即可)

  • 安装完成后,重新打开 DOS 命令窗口,输入 vue 命令可用表示成功了

第二步:选择一个目录使用Vue2的方式创建项目vue_provue creat vue_pro, 项目中自带脚手架环境(内置了 webpack loader),自带一个 HelloWorld 案例

  • babel:负责将ES6语法转换成ES5
  • eslint:负责语法检查

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第三步:在创建的项目根目录下vue_pro执行 npm run serve命令编译Vue程序自动生成html css js代码放入内置服务器并自动启动服务(ctrl + c 停止服务)

  • 打开浏览器访问http://localhost:8080

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

认识脚手架项目结构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

yarn

更改全局模块安装路径和缓存cache的路径(1)、打开nodejs安装目录,在里面创建node_global和node_cache两个文件夹
配置全局安装的模块路径和缓存路径;
在nodejs根目录创建node_global,node_cache文件夹;以管理员身份打开命令窗口,配置安装路径以及缓存路径,分别执行以下命令即可;
npm config set prefix "D:\dev\nodejs\node_global"
npm config set cache "D:\dev\nodejs\node_cache"右键此电脑——属性——高级系统设置——高级——环境变量——系统变量,
配置环境变量,然后添加,变量值名为:NODE_PATH,变量值为npm安装路径:D:\Program Files\nodejs\node_modules;编辑用户变量的 path,将默认的 C 盘下的  C:\Users\18280\AppData\Roaming\npm, 在path中添加:D:\Program Files\nodejs以及D:\Program Files\nodejs\node_global路径;配置cnpm,配置淘宝镜像,默认路径下载比较缓慢,配置淘宝镜像可以加速下载速度,打开命令窗口执行以下命令即可,如果不想配置cnpm,可直接跳过此步骤;
npm install -g cnpm --registry=https://registry.npm.taobao.org
1
3.4. 直接为npm设置淘宝镜像仓库即可,命令如下:
npm config set registry https://registry.npm.taobao.org
1
以管理员打开cmd,输入npm config list 命令,查看npm的配置信息# 临时更改为淘宝镜像源npm --registry https://registry.npm.taobao.org install node-red-contrib-composer@latest2、 全局使用淘宝源# 修改为淘宝镜像源npm config set registry https://registry.npm.taobao.org3、 全局使用官方源# 修改为官方镜像源npm config set registry http://www.npmjs.org

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

npm与cnpm其实没什么大的区别,npm默认的镜像时国外的,cnpm下载镜像是国内淘宝团队的,下载速度快点,其实直接将npm的下载仓库直接设置为淘宝镜像就可以了。
不同的是在项目中下载项目依赖时包时命令不同,用npm执行npm install -g ,用cnpm时,用cnpm install -g 命令就可以了# 安装cnpm
npm install -g cnpm -registry=https://registry.npm.taobao.org4、安装yarn ,使用npm命令,以管理员打开命令窗口输入:npm install yarn -g命令进行安装,安装完成后,
配置yarn的执行路径;在path中添加。D:\dev\nodejs\node_global\node_modules\yarn\bin
# 全局安装命令
npm install -g yarn
或
cnpm install -g yarn打开命令窗口,输入yarn -v即可查看yarn 版本;使用yarn config list命令即可看到node配置的全局路径、缓存路径、以及淘宝镜像路径,查看是否安装正确;2、更改模块及缓存存储目录同样先在yarn的安装目录下创建yarn_global和yarn_cache文件夹,并打开命令窗口执行以下命令。# 全局安装目录
yarn config set global-folder D:\dev\nodejs\node_global\node_modules\yarn\yarn_global
# 缓存目录
yarn config set cache-folder D:\dev\nodejs\node_global\node_modules\yarn\yarn_cache# 查看当前源
yarn config get registry# 修改为淘宝镜像源
yarn config set registry https://registry.npm.taobao.org# 修改为官方镜像源yarn config set registry https://registry.yarnpkg.com

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

分析index.html

index.html文件只有一个容器,并且没有看到引入vue.js文件和main.js文件

  • Vue脚手架会自动找到main.js文件不需要你手动引入(main.js文件的名字和位置都不要随便修改)
<!DOCTYPE html>
<html lang=""><head><meta charset="utf-8"><!--让IE浏览器启用最高渲染标准,IE8是不支持Vue的--><meta http-equiv="X-UA-Compatible" content="IE=edge"><!-- 开启移动端虚拟窗口(理想视口),可以设置虚拟窗口的宽高以及初始化比例,达到手机端浏览网页时缩放和移动的效果--><meta name="viewport" content="width=device-width,initial-scale=1.0"><!--设置页签图标,BASE_URL是Vue模仿Jsp语法设置的绝对路径,绝对路径比相对路径更加稳定--><link rel="icon" href="<%= BASE_URL %>favicon.ico"><!--webpack会去package.json中找name作为标题,也可以自己手动设置--><title><%= htmlWebpackPlugin.options.title %></title><title>欢迎使用本系统</title></head><body><!--当浏览器不支持JS语言的时候,显示如下的提示信息--><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>

配置文件vue.config.js

分析脚手架默认配置文件vue.config.js,具体配置项可以参考 Vue CLI 官网手册

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,// 保存时是否进行语法检查(如组件的名字应该由多单词组成), 默认值true表示检查,false表示不检查lintOnSave : false,// 配置入口文件的位置和名称pages: {index: {entry: 'src/main.js',}},

main.js

编译template配置项的模板语句报错原因: Vue包含两部分, 一部分是Vue的核心,一部分是模板编译器(占整个vue.js文件体积的三分之一)

  • 程序员最终使用webpack进行打包的时候代码肯定是已经编译好了, 这时候Vue中的模板编译器就没有存在的必要了
  • 为了缩小体积Vue脚手架中默认直接引入的就是一个缺失模板编译器的vue.js文件(Vue的仅运行时版本)
  • 注意: template的标签中的内容可以正常编译(因为package.json 文件中进行了配置)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解决main.js文件中的无法编译template配置项的方式

  • 第一种方式引入一个完整的vue.js: import Vue from ‘vue/dist/vue.js’
  • 第二种方式使用render函数代替template配置项: 这个函数由vue自动调用,并且传递过来一个函数createElemen可以用来创建元素(创建完必须返回)
// 这里默认引入的是dist/vue.runtime.esm.js(esm版本是ES6模块化版本)
import Vue from 'vue'
// 导入App组件(根组件)
import App from './App.vue'// 关闭生产提示信息
Vue.config.productionTip = false// 创建Vue实例
new Vue({el : '#app',// 完整写法render(createElement){ // 创建了一个div元素//return createElement('div', 'render函数')return createElement(App)} // 箭头函数的简写形式,参数只有一个省略括号,函数体只有一条语句可以省略{}和retuenrender : h => h(App)})

App根组件和其他组件

<!--App.vue-->
<template><div><h1>App组件</h1><!-- 使用组件 --><X></X><Y></Y></div>
</template><script>// 修改组件引入时的路径import X from './components/X.vue'import Y from './components/Y.vue'export default {// 注册组件components : {X, Y}}
</script>
<!--剩下的和组件嵌套的内容相同-->

props配置项以及获取子组件

发送组件通过组件标签的属性=""的形式传递数据, 接收组件使用props配置项可以接收其他组件传过来的数据,让组件的数据变为动态数据

  • 简单接收: props : [‘name’,’age’,’sex’]
  • 接收时添加类型限制: props : {name : Stringage : Number}
  • 接收时添加类型限制,必要性限制,默认值: props : {name : {type : Number, required : true}, age : {type : Number, default : 10}}
  • props接收到的数据不能修改(页面会刷新但控制台报错), 一般通过间接修改一个中间变量的值避免父组件重新渲染时子组件修改后的值被覆盖的问题

在App这个父组件当中先找到子组件Car,然后给Car这个子组件通过属性的形式传数据

  • 先在组件标签上使用ref属性进行标识,然后在程序中使用$refs来获取所有子组件, 然后通过标识获取具体的某一个组件
  • 获取子组件时支持嵌套的形式即this.$refs.组件标识.$refs.name表示访问子组件的子组件属性
  • ref也可以使用在普通的HTML标签上,这样使用$refs获取的就是这个 DOM 元素
<template><div><h1 ref="hh">{{msg}}</h1><!--price="10"表示传递过去的数据是字符串"10",:price="10"表示传递过去的数据是数字10(属性绑定,""内的10被看作常量)--><Car brand="宝马520" color="黑色" :price="10" ref="car1"></Car><Car brand="比亚迪汉" color="红色" :price="20" ref="car2"></Car><button @click="printCarInfo">打印汽车信息</button></div>
</template><script>import Car from './components/Car.vue'export default {name : 'App',data() {return {msg : '汽车信息'}},methods : {printCarInfo(){// 使用$refs属性获取子组件console.log(this.$refs.car1)console.log(this.$refs.car2)// 访问子组件的属性console.log(this.$refs.car1.brand)console.log(this.$refs.car1.color)console.log(this.$refs.car1.price)// 使用$refs属性获取普通的DOM元素的值console.log(this.$refs.hh.innerText)}},components : {Car}}
</script>

子组件Car接收父组件传递过来的数据

<template><div><h3>品牌:{{brand}}</h3><h3>价格:{{cprice}}</h3><h3>颜色:{{color}}</h3><button @click="add">价格加1</button></div>
</template><script>
export default {name : 'Car',data() {return {cprice : this.price}},methods : {add(){// props接收到的数据不能修改, 一般通过间接修改一个中间变量的值避免父组件重新渲染时子组件修改后的值被覆盖的问题this.cprice++}},// 在Car这个子组件当中使用props配置项动态的接收其他组件传递过来的数据,不再使用自己配置项data中的静态数据data() {return {brand : '宝马520',price : 10,color : '黑色'}}, // 第一种:简单的接收方式,直接采用数组接收props : ['brand','color','price']// 第二种:添加类型限制(类型不符合会报错)props : {brand : String,color : String,price : Number} // 第三种:添加类型限制,并且还可以添加默认值和必要性(避免直接更改prop,因为每当父组件重新渲染时,该值都会被覆盖)props : {brand : {type : String,required : true},color : {type : String,default : '红色'},price : {type : Number,required : true}}}
</script>

mixins配置项(混入)

Vip.vue和User.vue代码中都有相同的methods,为了复用可以使用mixins配置进行混入(混入时配置项没有限制, 之前所学的配置项都可以混入)

  • 第一步: 提取相同的配置项并单独定义到一个mixin.js文件(一般和main.js在同级目录)
  • 第二步: 引入并在mixins配置中使用

混入时的配置项冲突问题

  • 对于普通的配置项采取就近原则即只执行组件自身的配置不会执行混入的配置(混入的意思就是不破坏)
  • 对于生命周期周期钩子函数来说,混入时会采用叠加方式先执行混入的再执行自己的

混入的方式分为局部导入混入和全局混入两种

export const mix1 = {methods: {printInfo(){console.log(this.name, ',' , this.age) }}
}export const mix2 = {methods: {a(){console.log('mixin.js a.....')}},
}export const mix3 = {mounted() {console.log('mixin.js mounted...')}
}
<template><div><h1>{{msg}}</h1><h3>姓名:{{name}}</h3><h3>年龄:{{age}}</h3><button @click="printInfo">执行printInfo方法打印用户信息</button><button @click="a">执行a方法</button></div>
</template><script>// 导入mixin配置项import {mix1} from '../mixin.js'import {mix2} from '../mixin.js'import {mix3} from '../mixin.js'export default {name : 'User',// 这里先执行混入的mounted函数,再执行自身的mounted函数mounted() {console.log('User mounted...')},data() {return {msg : '用户信息',name : '张三2',age : 20}},// 局部混入,数组接收表示可以混入多个mixins : [mix1,mix2, mix3],}
</script>
<template><div><h1>{{msg}}</h1><h3>姓名:{{name}}</h3><h3>年龄:{{age}}</h3><button @click="printInfo">执行printInfo方法打印用户信息</button><button @click="a">执行a方法</button></div>
</template><script>// 导入mixin配置项import {mix1} from '../mixin.js'import {mix2} from '../mixin.js'export default {name : 'Vip',data() {return {msg : '会员信息',name : '李四2',age : 21}},// 局部混入,数组接收表示可以混入多个mixins : [mix1,mix2],// 这里只调用自身的a方法,不会执行混入的a方法methods: {a(){console.log('vip a....')}},}
</script>

全局混入在所有的组件中(包括根组件root即vm)都自动导入混入的配置项

// 等同于引入vue.js文件
import Vue from 'vue'
// 导入App组件(根组件)
import App from './App.vue'// 导入mixin配置项
import {mix1} from './mixin.js'
import {mix2} from './mixin.js'
import {mix3} from './mixin.js'// 全局混入
Vue.mixin(mix1)
Vue.mixin(mix2)
Vue.mixin(mix3)// 关闭生产提示信息
Vue.config.productionTip = false// 创建Vue实例
new Vue({el : '#app',render : h => h(App)
})

plugins 配置(插件)

插件给用来Vue做功能增强的(可插拔), 插件一般都放到一个plugins.js文件中(一般和main.js在同级目录)

  • 插件是一个对象,对象中必须有install方法并且会被自动调用,一个插件一般对应一个独立的功能
  • 使用插件分为三步: 定义插件对象并暴露,导入插件,使用插件( 通常放在创建Vue实例之前)

插件对象的install方法有两个参数

  • 第一个参数:Vue构造函数
  • 第二个参数:用户在使用这个插件时传过来的数据,参数个数无限制

定义一个插件功能是给Vue的原型对象扩展一个counter属性(通过vm和vc都可以访问)

export const p1 = {install(Vue, a, b, c, d){console.log('这个插件正在显示一个可爱的封面')console.log(Vue)console.log(a,b,c,d)// 获取Vue的原型对象,给Vue的原型对象扩展一个counter属性,通过vm和vc都可以访问Vue.prototype.counter = 1000}
}
// 等同于引入vue.js文件
import Vue from 'vue'
// 导入App组件(根组件)
import App from './App.vue'// 导入插件
import {p1} from './plugins.js'
// 插上插件(删除就是拔下插件),通常放在创建Vue实例之前
Vue.use(p1, 1,2,3,4)// 关闭生产提示信息
Vue.config.productionTip = false// 创建Vue实例
new Vue({el : '#app',render : h => h(App)})
<template><div><button @click="a">执行a方法</button></div>
</template><script>export default {       methods: {a(){console.log('vip a....')// 访问插件给Vue原型对象扩展的一个counter属性console.log('通过插件扩展的一个counter:', this.counter)}},}
</script>

局部样式 scoped

默认情况下vue所有组件中定义的样式最终会汇总到一块,如果样式名一致会导致冲突,此时以后来加载的样式为准(就近原则)

  • vue组件的style样式支持多种样式语言(如css、less、sass), 使用less语法需要安装less-loader:npm i less-loader
  • App根组件中的样式style希望采用全局的方式不建议添加scoped属性,子组件的样式style一般添加scoped属性

由于样式冲突那么User组件的样式会覆盖掉Vip组件的样式

  • 给style加入scoped属性后,Vue底层会给标签加上属性,这样即使样式汇到一块也不会发生冲突了
<template><div class="s"><h1>{{msg}}</h1></div>
</template><script>export default {data() {return {msg : '用户信息',}}}
</script><style scoped>.s {background-color: aquamarine;} 
</style>
<template><div class="s"><h1>{{msg}}</h1></div>
</template><script>export default {data() {return {msg : '会员信息',}}}
</script><style scoped>.s {background-color:bisque} 
</style>
<template><div><User></User><Vip></Vip></div>
</template><script>// 先导入Vip,由于样式冲突那么User组件的样式会覆盖掉Vip组件的样式import Vip from './components/Vip.vue'import User from './components/User.vue'export default {name : 'App',components : {User, Vip}}
</script><style>/* 一般在App根组件当中样式不会添加scoped,因为根组件的样式还是希望采用全局的方式处理。 */
</style>

相关文章:

Vue组件化

组件 组件是实现应用中局部功能的代码(HTML,CSS,JS)和资源(图片,声音,视频)的集合,凡是采用组件方式开发的应用都可以称为组件化应用 模块是指将一个大的js文件按照模块化拆分规则进行拆分成的每个js文件, 凡是采用模块方式开发的应用都可以称为模块化应用(组件包括模块) 传…...

nodejs+python+php+微信小程序-基于安卓android的健身服务应用APP-计算机毕业设计

考虑到实际生活中在健身服务应用方面的需要以及对该系统认真的分析&#xff0c;将系统权限按管理员和用户这两类涉及用户划分。  则对于进一步提高健身服务应用发展&#xff0c;丰富健身服务应用经验能起到不少的促进作用。 健身服务应用APP能够通过互联网得到广泛的、全面的宣…...

SpringCloud 微服务全栈体系(九)

第九章 Docker 三、Dockerfile 自定义镜像 常见的镜像在 DockerHub 就能找到&#xff0c;但是我们自己写的项目就必须自己构建镜像了。 而要自定义镜像&#xff0c;就必须先了解镜像的结构才行。 1. 镜像结构 镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而…...

Mybatis 多对一和一对多查询

文章目录 Mybatis 多对一 and 一对多查询详解数据库需求Mybatis代码注意 Mybatis 多对一 and 一对多查询详解 数据库 员工表 t_emp 部门表 t_dept CREATE TABLE t_emp (emp_id int NOT NULL AUTO_INCREMENT,emp_name varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci…...

MySQL的数据库操作、数据类型、表操作

目录 一、数据库操作 &#xff08;1&#xff09;、显示数据库 &#xff08;2&#xff09;、创建数据库 &#xff08;3&#xff09;、删除数据库 &#xff08;4&#xff09;、使用数据库 二、常用数据类型 &#xff08;1&#xff09;、数值类型 &#xff08;2&#xff0…...

音视频技术开发周刊 | 317

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 MIT惊人再证大语言模型是世界模型&#xff01;LLM能分清真理和谎言&#xff0c;还能被人类洗脑 MIT等学者的「世界模型」第二弹来了&#xff01;这次&#xff0c;他们证明…...

【JavaSE专栏58】“Java构造函数:作用、类型、调用顺序和最佳实践“ ⚙️⏱️

解析Java构造函数&#xff1a;作用、类型、调用顺序和最佳实践" &#x1f680;&#x1f4da;&#x1f50d;&#x1f914;&#x1f4dd;&#x1f504;⚙️⏱️&#x1f4d6;&#x1f310; 摘要引言1. 什么是构造函数 &#x1f914;2. 构造函数的类型与用途 &#x1f4dd;1.…...

Ubuntu系统HUSTOJ 用 vim 修改php.ini 重启PHP服务

cd / sudo find -name php.ini 输出&#xff1a; ./etc/php/7.4/cli/php.ini ./etc/php/7.4/fpm/php.ini sudo vim /etc/php/7.4/cli/php.ini sudo vim /etc/php/7.4/fpm/php.ini 知识准备&#xff1a; vim的搜索与替换 在正常模式下键入 / &#xff0c;即可进入搜索模式…...

案例分析真题-信息安全

案例分析真题-信息安全 2009年真题 【问题1】 【问题2】 【问题3】 2010年真题 【问题1】 【问题2】 【问题3】 2011 年真题 【问题1】 【问题2】 【问题3】 骚戴理解&#xff1a;这个破题目完全考的知识储备&#xff0c;不知道的连手都动不了&#xff0c;没法分析 2013年真题…...

envi5.3处理高分二号影像数据辐射定标大气校正

目录 一、多光谱影像处理 1. 辐射定标 2.大气校正 1. 需要准备一些数据: 2.大气校正过程 3、正射校正 二、全色影像处理 1. 辐射定标 2. 正射校正 三、图像融合 1.几何配准 2.图像融合 高分二号处理流程 envi5.3的安装教程&#xff1a; ENVI5.3安装 安装完ENVI5.3后&#xff0…...

C语言 结构体

结构体的自引用: 自引用的目的&#xff1a; 结构体的自引用就是指在结构体内部&#xff0c;包含指向自身类型结构体的指针。 像链表就会用到结构体的自引用。假如我们要创建链表 链表的没个节点都是一个结构体&#xff0c;它里面存放着它的数据和下个节点的地址。 假如我们用…...

frp-内网穿透部署-ubuntu22服务器-windows server-详细教程

文章目录 1.下载frp2.配置服务器2.1.配置frps.ini文件2.2.设置服务文件2.3.设置开机自启和服务操作2.4.后台验证2.5.服务器重启 3.配置本地window3.1.frpc配置3.2.添加开机计划启动3.3.控制台启动隐藏窗口 4.centos防火墙和端口3.1.开放端口3.2.查看端口 5.关闭进程5.1.杀死进程…...

MySQL内存使用的监控开关和使用查看

参考文档&#xff1a; https://brands.cnblogs.com/tencentcloud/p/11151 https://www.cnblogs.com/grasp/p/10306697.html MySQL如何使用内存 在MySQL中&#xff0c;内存占用主要包括以下几部分&#xff0c;全局共享的内存、线程独占的内存、内存分配器占用的内存&#xff0…...

数据库管理-第113期 Oracle Exadata 04-硬件选择(20231020)

数据库管理-第113期 Oracle Exadata 04-硬件选择&#xff08;2023010290&#xff09; 本周没写文章&#xff0c;主要是因为到上海参加了Oracle CAB/PAB会议&#xff0c;这个放在后面再讲&#xff0c;本期讲一讲Exadata&#xff0c;尤其是存储节点的硬件选择及其对应的一些通用…...

带着问题去分析:Spring Bean 生命周期 | 京东物流技术团队

1: Bean在Spring容器中是如何存储和定义的 Bean在Spring中的定义是_org.springframework.beans.factory.config.BeanDefinition_接口&#xff0c;BeanDefinition里面存储的就是我们编写的Java类在Spring中的元数据&#xff0c;包括了以下主要的元数据信息&#xff1a; 1&…...

C语言修行之函数篇(一)tolower —— 转换为小写字母

文章目录 函数说明函数声明函数返回值函数实现函数实例 函数说明 对于大写字母&#xff0c;如果在当前语言环境中存在小写表示形式&#xff0c;则tolower()返回其小写等效物。否则&#xff0c;tolower()函数执行相同的任务。 函数声明 #include <ctype.h> int tolower(…...

【JavaSE专栏55】Java集合类HashTable解析

&#x1f332;Java集合类HashTable解析 &#x1f332;Java集合类HashTable解析摘要引言Hashtable是什么&#xff1f;Hashtable vs. HashMap&#xff1a;何时使用Hashtable&#xff1f;多线程环境&#xff1a;历史遗留系统&#xff1a;不需要进行特殊操作&#xff1a; Hashtable…...

Apollo上机实践:一次对自动驾驶技术的亲身体验

上机实践 概述自动驾驶通信分布式系统开发模式开发工具 自动驾驶感知传感器特性感知流程及算法部署感知模型 自动驾驶决策规划决策规划流程和算法使用 Dreamview 进行控制在环的规划调试开发规划场景和算法 福利活动 主页传送门&#xff1a;&#x1f4c0; 传送 概述 Apollo 是…...

QTcpServer简单的TCP服务器连接

1、简介 简单实现控制TCP服务器获取连接的套接字。点击断开服务器即可关闭所有连接&#xff0c;最大连接数量为5个。 声明源文件 #include "mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {//设置固定大小setFixedSize(1024,600);b…...

LeetCode热题100——双指针

双指针 1.移动零2.盛最多水的容器3.三数之和 1.移动零 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 // 题解&#xff1a;使用双指针&#xff0c;其中快指针指向非零元素&#xff0c;慢指针指向首个零元素下…...

Ubuntu ARMv8编译Qt源码以及QtCreator

最近需要在NVIDIA小盒子上面跑一个程序&#xff0c;一开始想着在Ubuntu x64下交叉编译一版&#xff0c;后来发现libqxcb.so 这个库在configure时就会一直报错&#xff0c;多方查找怀疑可能是由于硬件不支持在x64环境下编译AMR架构的xcb库。 所以最后在ARM下直接编译Qt源码了&am…...

虚机Centos忘记密码如何重置

1进入开机前的页面&#xff0c;选中第一个&#xff0c;按“e”键&#xff0c;进入编辑模式 2找到ro crashkernel项&#xff0c;将ro替换成 rw initsysroot/bin/sh 3 Ctrlx mount -o remount, rw / chroot /sysroot chroot /sysroot passwd root 输入两次密码 touch /.a…...

OpenGL_Learn02

1. 监听窗口&#xff0c;绑定回调函数 #include <glad/glad.h> #include <GLFW/glfw3.h> #include <iostream>void framebuffer_size_callback(GLFWwindow* window, int width, int height) {glViewport(0, 0, width, height);std::cout << "变了…...

基于STC系列单片机实现外部中断0控制按键调节定时器0产生PWM(脉宽调制)的功能

#define uchar unsigned char//自定义无符号字符型为uchar #define uint unsigned int//自定义无符号整数型为uint sbit PwmOut P1^0;//位定义脉宽调制输出为单片机P1.0脚 uchar PwmTimeCount;//声明脉宽调制时间计数变量 uchar PwmDutyCycle;//声明脉宽调制占空比变量 void Ti…...

vue3中 reactive和ref的区别

在Vue 3中&#xff0c;reactive和ref都是用于响应式数据的API。它们的主要区别在于使用方式和返回值类型。 reactive&#xff1a; reactive函数用于将一个对象转换为响应式对象。它接收一个普通的JavaScript对象&#xff0c;并返回一个被代理的响应式对象。这意味着当响应式对…...

docker的安装部署nginx和mysql

小白自己整理&#xff0c;如有错误请指示&#xff01; 自我理解&#xff1a;docker就是把应用程序所用的依赖程序&#xff0c;函数库等相关文件打包成镜像文件&#xff0c;类似系统光盘&#xff0c;然后可以在任意电脑上安装使用&#xff08;方便运维人员部署程序&#xff09;…...

测试C#调用Aplayer播放视频(1:加载Aplayer控件)

微信公众号“Dotnet跨平台”的文章《开源精品&#xff0c;使用 C# 开发的 KTV 点歌项目》中使用了迅雷开源APlayer播放引擎。最近在学习有哪些能拿来播放视频的组件或控件&#xff0c;于是准备试试&#xff0c;根据文章中的介绍&#xff0c;在迅雷APlayer播放引擎网站中下载了A…...

二叉树的遍历+二叉树的基本操作

文章目录 二叉树的操作一、 二叉树的存储1.二叉树的存储结构 二、 二叉树的基本操作1.前置创建一棵二叉树&#xff1a;1. 定义结点 2.简单的创建二叉树 2.二叉数的遍历1.前序遍历2.中序遍历3.后序遍历4.层序遍历 3.二叉树的操作1.获取树中节点的个数2.获取叶子节点的个数3.获取…...

Go 语言gin框架的web

节省时间与精力&#xff0c;更高效地打造稳定可靠的Web项目&#xff1a;基于Go语言和Gin框架的完善Web项目骨架。无需从零开始&#xff0c;直接利用这个骨架&#xff0c;快速搭建一个功能齐全、性能优异的Web应用。充分发挥Go语言和Gin框架的优势&#xff0c;轻松处理高并发、大…...

Docker底层原理:Cgroup V2的使用

文章目录 检查 cgroup2 文件系统是否已加载检查系统是否已挂载 cgroup2 文件系统创建 cgroup2 层次结构查看 cgroup2 开启的资源控制类型启用 cgroup2 资源控制设置 cgroup2 资源限制加入进程到 cgroup2 检查 cgroup2 文件系统是否已加载 cat /proc/filesystems | grep cgroup…...