Web|Web学习(十一) Vue

Web学习(十一) Vue 1.配置环境
1.1 安装Nodejs 1.2 安装@vue/cli

npm i -g @vue/cli

1.3 启动vue自带的图形化项目管理界面
vue ui

常见问题1:Windows上运行vue,提示无法加载文件,表示用户权限不足。
解决方案:用管理员身份打开终端,输入set-ExecutionPolicy RemoteSigned,然后输入y
2.基本概念
script部分 【Web|Web学习(十一) Vue】export default对象的属性:
  • name:组件的名称
  • components:存储中用到的所有组件
  • props:存储父组件传递给子组件的数据
  • watch():当某个数据发生变化时触发
  • computed:动态计算某个数据
  • setup(props, context):初始化变量、函数
    • ref定义变量,可以用.value属性重新赋值
    • reactive定义对象,不可重新赋值
    • props存储父组件传递过来的数据
    • context.emit():触发父组件绑定的函数
template部分
  • :存放父组件传过来的children。
  • v-on:click或@click属性:绑定事件
  • v-if、v-else、v-else-if属性:判断
  • v-for属性:循环,:key循环的每个元素需要有唯一的key
  • v-bind:或::绑定属性
style部分
  • 标签添加scope属性后,不同组件间的css不会相互影响。
第三方组件
  • view-router包:实现路由功能。
  • vuex:存储全局状态,全局唯一。
    • state: 存储所有数据,可以用modules属性划分成若干模块
    • getters:根据state中的值计算新的值
    • mutations:所有对state的修改操作都需要定义在这里,不支持异步,可以通过$store.commit()触发
    • actions:定义对state的复杂修改操作,支持异步,可以通过$store.dispatch()触发。注意不能直接修改state,只能通过mutations修改state。
    • modules:定义state的子模块
项目组成
  • views:用于写各个页面,每个页面对应一个 view,里面也可以写组件。 components:组件。
  • router:路由。
  • main.js:整个的入口,根组件,将根组件挂载到 index.html 里。
  • .vue:每个页面是一个 .vue 文件,是 vue 自定义的文件类型,每个 .vue 文件都有三部分组成,分别是 html,css 和
    js。每个 .vue 文件都会 export 一个对象。
    Web|Web学习(十一) Vue
    文章图片
3.Vue3实战
安装插件后,启动项目
Web|Web学习(十一) Vue
文章图片

在输入栏找到运行地址后打开网页。
Web|Web学习(十一) Vue
文章图片

3.1 实现导航栏 在App.vue中添加需要导入的包
> import 'bootstrap/dist/css/bootstrap.css'; import 'bootstrap/dist/js/bootstrap'; import NavBar from './components/NavBar'; export default { name: "App", components: { NavBar, } }>

在component中添加NavBar.vue,html部分直接利用bootstrap:
> export default { name: "NavBar", } >

3.2 实现contentBase组件 由于多个页面存在相似的部分,所以外面在component中创建contentBase.vue,这样在其他页面直接调用countentBase组件即可:
> export default { name: "ContentBase", } > .container { margin-top: 20px; }

在homeview.vue中使用contentBase:
> import CountentBase from '@/components/CountentBase.vue'export default { name: 'HomeView', components: { CountentBase } }

3.3 编写LoginView.vue,notFoundView.vue,RegisterView.vue等,并添加路由 在router/index.js中添加路由:
import { createRouter, createWebHistory } from 'vue-router' import HomeView from '../views/HomeView.vue'; import UserListView from '../views/UserListView.vue'; import UserProfileView from '../views/UserProfileView.vue'; import LoginView from '../views/LoginView.vue'; import RegisterView from '../views/RegisterView.vue'; import NotFoundView from '../views/NotFoundView.vue'; const routes = [ { path: '/', name: 'home', component: HomeView }, { path: '/userlist', name: 'userlist', component: UserListView }, { path: '/userprofile', name: 'userprofile', component: UserProfileView }, { path: '/login', name: 'login', component: LoginView }, { path: '/register', name: 'register', component: RegisterView }, { path: '/404', name: '404', component: NotFoundView }, ]const router = createRouter({ history: createWebHistory(), routes })export default router

添加路由后已经可以按网址目录实现网页的跳转。
将NavBar中a标签全部换为router-link,在页面的NavBar上实现链接的跳转。
> export default { name: "NavBar", } >

Web|Web学习(十一) Vue
文章图片

3.4 实现UserProfileInfo,UserProfilePosts与UserProfileWrite: Web|Web学习(十一) Vue
文章图片

用户动态主页面UserProfileView.vue:
> import ContentBase from '../components/ContentBase' import UserProfileInfo from '../components/UserProfileInfo'; import UserProfilePosts from '../components/UserProfilePosts'; import UserProfileWrite from '../components/UserProfileWrite'; import { reactive } from 'vue'; export default { name: 'UserList', components: { ContentBase, UserProfileInfo, UserProfilePosts, UserProfileWrite },// 初始化变量、函数 setup() { const user = reactive({ id: 1, username: "YanYuchen", lastName: "Yan", firstName: "Yuchen", followerCount: 0, is_followed: false, }); const posts = reactive({ count: 3, posts: [ { id: 1, userId: 1, content: "今天上了web课真开心", }, { id: 2, userId: 1, content: "今天上了算法课,更开心了", }, { id: 3, userId: 1, content: "今天上了acwing ,开心极了", }, ] }); // 关注函数 const follow = () => { if (user.is_followed) return; user.is_followed = true; user.followerCount ++ ; }; // 取消关注函数 const unfollow = () => { if (!user.is_followed) return; user.is_followed = false; user.followerCount -- ; }; //发送文本信息 const post_a_post = (content) => { posts.count ++ ; posts.posts.unshift({//最前面添加元素 id: posts.count, userId: 1, content: content, }) }; return { user, follow, unfollow, posts, post_a_post } } } >

UserProfileInfo.vue:
> import { computed } from 'vue'; export default { name: "UserProfileInfo", props: { user: { type: Object, required: true, }, },// computed:动态计算某个数据 // props:存储父组件传递给子组件的数据 setup(props, context) { // 从UserProfileView中读取user数据 let fullName = computed(() => props.user.lastName + ' ' + props.user.firstName); // 关注函数 const follow1234 = () => { context.emit('follow123'); //context.emit():触发父组件绑定的函数 }; // 取消关注函数 const unfollow1234 = () => { context.emit("unfollow123"); // 触发父组件UserProfileView中unfollow函数 }return { fullName, follow1234, unfollow1234, } } } > img { border-radius: 50%; }.username { font-weight: bold; }.fans { font-size: 12px; color: gray; }button { padding: 2px 4px; font-size: 12px; }

UserProfilePosts.vue:
> export default { name: "UserProfilePosts", props: { posts: { type: Object, required: true, }, } } > .single-post { margin-bottom: 10px; }

UserProfileWrite.vue;
> import { ref } from 'vue'; export default { name: "UserProfileWrite", setup(props, context) { let content = ref(''); const post_a_post = () => { context.emit('post_a_post123', content.value); // 触发父组件中的post_a_post content.valuehttps://www.it610.com/article/= ""; }; return { content, post_a_post, } } } > .edit-field { margin-top: 20px; }button { margin-top: 10px; }

    推荐阅读